360 Secure SkillHub
360 安全技能中心

gongfen-calc

读取格式不固定的 Excel/CSV 任务清单,自动识别字段、归一单位、执行质检与批次评级,按工时、难度、金额等维度打分,输出含工分明细、批次汇总、质检自检与字段识别的 Excel 结果表,以及同源的 Markdown 报告与 JSON 中间结构;数据不足时降级并拒绝编造分数。

分类:数据
weikion
weikion
热度 2.34
最近更新 2026-11-06 16:16:55

安装

发给 Agent
帮我安装这个技能:npx secure-skills-cli add weikion/gongfen-calc
兼容性
通用兼容
联网要求
不联网
数据出网
数据不出本机
Metadata
name
gongfen-calc
slug
gongfen-calc
version
2.1.0
displayName
任务工分计算器
summary
丢进来一张格式再乱的任务清单,还你一份逐任务打好评级的 Excel 打分表——字段自动识别、单位自动归一、每个分数可回溯到原表行号;数据不足时如实降级,不编造分数。
tags
["excel","工分","任务打分","绩效","工时","点因子法"]
license
MIT
description
从格式不固定的 Excel/CSV 任务清单中自动识别字段、归一单位、按多维度打分并汇总工分,产出**打好评级的 Excel 结果表**(工分明细/批次汇总/质检自检/字段识别)+ 可复核的 Markdown 报告。当用户提供任务清单(.xlsx/.xls/.csv)要求"算工分""算任务分""按工时/难度/金额/优先级给任务打分""评估任务价值分布""导出打分表",或贴出一张任务表问"能不能自动算分"时使用。识别不出必要字段时明确报"分析失败"并回显已识别列名清单,不静默编造结果。
agent_created
true

工分计算(gongfen-calc)

用途

把一张格式不固定的任务清单,变成一份可复核的工分事实清单:

Excel/CSV → 字段识别 → 单位归一 → 质检 → 批次评级 → 打分 → Excel 结果表 + Markdown 报告 + 中间 JSON

输出的是任务分,不是个人绩效等级。设计上宁可报"分析失败",也不静默编造一个看起来合理的分数。

门槛:只要识别到任务名称或描述列就执行分析,缺列不阻断——缺失的维度不参与计算,只在报告提示。 唯一阻断条件是「连任务名/描述都认不出来」。难度维度固定启用,从任务名(优先)或备注描述推断。

不适用:给人定绩效等级(A/B/C)、淘汰或扣罚名单。这类需求直接拒绝。

快速开始

# 1. 装依赖(Windows 必须走阿里云镜像,直连 pypi 会超时)
pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host mirrors.aliyun.com

# 2. 跑(一条命令出结果,全程不询问、不中断)
python scripts/run.py 任务清单.xlsx
python scripts/run.py 任务清单.xlsx --out-dir out --baseline out/baseline.json

# 3. 只有在「明知第 N 列是什么、脚本却认错了」时才人工覆写(唯一的人工介入点)
python scripts/run.py 任务清单.xlsx --override 3=hours --override 5=money

# 4. 明知覆盖度不足(C/D 分支)仍要出工分 —— 默认不出,必须显式加 --force-points
python scripts/run.py 任务清单.xlsx --force-points

--override 列号=字段名:列号从 1 开始(对应报告「字段识别明细」的列号),字段名取值 task_name/hours/money/difficulty/risk/priority/quality/urgency/start_date/end_date/collab/reuse/parent/role/…。 覆写会写进仲裁记录留痕,被取代的同名字段列自动转入「未映射列」。低置信列默认按规则自动裁定,不会停下来问。

产出(默认与输入同目录,可用 --out-dir / --xlsx / --json / --md 指定):

  • 任务清单.gongfen.xlsx —— 打分结果表(主交付物),4 个 sheet:
    • 工分明细:逐任务 原表行号 / 任务名 / 各维度档位(带权重)/ 原始值 / 完整度 / 分层 / 层内排名 / 小计 S / K系数 / 工分 P / 判定依据(容器父任务也列出,标"不计分")
    • 批次汇总:分支结论、总分 T、总工分、分层分布、维度权重与覆盖度、口径冻结、提升建议
    • 质检与自检:质检提示、自检结果、被打折任务、被剔除行(含行号与原因)、冻结任务、红线声明
    • 字段识别:列映射明细(列号/置信度/方式/样例)+ 未映射列 + 仲裁日志
  • 任务清单.gongfen.md —— 给人看的报告(九节)
  • 任务清单.gongfen.json —— 复核与下游用的中间结构(解析层与打分层的唯一契约)
  • out/baseline.json —— 首次运行自动存档,第二次起启用环比检测

C/D 分支下 Excel 的「工分 P」列留空,另给一列**「参考工分(仅供排序对照·不可用于分配)」**(= S×20×K), 表头与汇总页都写明不可用于分配;确需工分时加 --force-points 重跑,脚本会在保单里追加一条强制输出警示。

退出码:0 正常或降级 / 1 分析失败(已出可读报告)/ 2 参数错误 / 3 内部异常。

执行流程

脚本端到端出结果,模型不做二次判断。 不要自己打开 Excel 猜字段,不要覆写脚本给出的分数,不要在识别环节打断用户。

  1. 跑脚本(合并单元格展开、合计行剔除、单位归一、Excel 排版这些手工很难做对的事都在脚本里)。
  2. 读"批次结论":A_正常 / B_可排名 / D_体系退化 / C_仅描述 / E_失败。这决定结果能不能用于分配。
  3. 交付 *.gongfen.xlsx(主交付物,直接给用户打开);Markdown 是同一份数据的文字版,用于贴聊天/贴文档。
  4. 把三件事讲给用户:分支结论与免责句、剔除了哪些行(Excel「质检与自检」第五节有行号与原文)、哪些任务标了异常(工时与日期矛盾、被偏离度打折、难度为估算值)。
  5. 用户追问某个数怎么来的,查 任务清单.gongfen.json 或 references/field_dictionary.md(别名表、正则、换算系数、质检规则都在里面)。
  6. 口径:改 scripts/params.py 后重跑;列认错了用 --override 列号=字段名 重跑;不要手工改分数,也不要手工改 JSON。

Excel 结果表(scripts/excel_out.py)

只在非 E_失败分支产出(失败时只有 MD/JSON)。excel_out.py 只读 payload、不碰任何分数, 所以 Excel 与 MD/JSON 永远同源同值;重跑即覆盖同名文件。

sheet 内容 用途
工分明细 原表行号 / 任务ID / 任务名 / 各维度档位(表头带归一化权重)+ 原始值 / 有效维度数 / 完整度×2 / 分层 / 层内排名 / 小计 S / K偏离·K合计 / 工分 P / 判定依据 逐任务核对、按原表行号回溯
批次汇总 分支结论、总分 T、总工分、分层分布、维度权重与覆盖度表、口径冻结、补齐字段建议 一眼看结论
质检与自检 质检提示、批次评级提示、自检结果、被打折任务、被剔除行(行号+原因+原文)、冻结任务、红线声明 复核"哪些数据没被采信"
字段识别 列号 / 原始列名 / 识别为 / 置信度 / 识别方式 / 样例值 + 未映射列 + 仲裁日志 认错列时查列号,配 --override 重跑

实现约束(改这个文件时必须守住):

  • 列对齐:明细行逐列拼装,len(line) != len(headers) 直接抛错。容器父任务分支只补 「分层/排名/小计/K偏离/K合计」5 列(有效维度数与完整度在分支前已追加),多补就会越界。
  • 容器父任务必须出现在明细里(标"不计分(防父子重复计分)"),否则用户会以为漏了任务。
  • P.COVERAGE_RANK/COVERAGE_NORMAL 是百分制数值(45.0/60.0),格式化用 :.0f% 而不是 :.0%。
  • 未映射列要跳过空白列名(真实表常有几十个空列)。
  • 写入前清 Excel 非法控制字符并截断超长文本(备注列经常带换行与超长文本)。

五个输出分支(都是正常路径,不是异常)

分支 触发 结果能用于什么
A_正常 启用维度权重 ≥60%,n_eff ≥3 可排名,作分配参考
B_可排名 权重 45–60%,或单维归一权重 >35%(预警线),或无日期锚点 可排名,不建议直接分配
D_体系退化 n_eff <3,或难度排名与工时排名一致性 >0.85,或有效维度 ≤2(40% 硬上限数学不可满足) 仅排序参考,禁作分配依据
C_仅描述 权重 <45%,或任务数 <3,或 >50% 任务无任何有效维度 仅描述统计,不出总分
E_失败 无任务名或描述列 / 表头定位失败 / 文件不可读或加密 不出分,回显失败三件套

门槛口径(已按用户要求放宽):只要识别到任务名称或描述列就执行分析, 缺列不再阻断——缺失的维度不参与计算(走降权重重分配),只在报告里提示。 唯一阻断条件是「连任务名/描述都认不出来」。「无任何可量化维度」由阻断改为降级提示 (W_NO_QUANT_DIM),落到 C_仅描述 分支,仍出逐任务难度与排序,但不输出工分。

优先级 E → C → D → B → A,命中即停。分支 B/C/D 不停流程、不弹询问,只在报告首屏加固定提示句; 在 C/D 分支下不得给出任何分配建议,也不输出工分单价(MD 里工分列渲染为「—」, Excel 里「工分 P」列留空,另给一列明标「参考工分(仅供排序对照·不可用于分配)」)。 确需工分时由人工显式加 --force-points,脚本会在保单与 Excel 汇总页追加"强制输出"警示 —— 默认不给,脚本不替人做这个决定。

红线

  1. 不产出"某人应得 X 分 / 应评为 X 级"。要按人汇总,只能说"该人负责任务的工分合计",并注明"不等同于个人绩效结论,用于分配前须经团队共识与人工复核"。
  2. 不产出淘汰/扣罚名单,也不设计这类规则。
  3. 不得静默改分。工时偏离度打折、疑似拆分、分布偏斜——全部只提示 + 列清单,判断权归人工。
  4. F 技能门槛永不进小计(即使有花名册)。职级→门槛的映射会让同级员工的所有任务获得加成,且同一任务换人做就变分,属于对特定人群的系统性偏差。
  5. 数据不足不得伪装成可用。权重合计 <45% 或 n_eff <3 时,必须显式写「仅排序参考」。
  6. 报告必须带红线声明;失败时必须回显三件套(①已识别列名 ②缺失字段 ③建议补充列)。
  7. 估算值不得冒充实测值。关键词推断出的难度必须标 estimated,且标注要出现在总分旁边,不能只写在方法说明里。

关键口径

项 口径
单任务小计 S = Σ(level_i × W_i) / Σ(W_i有效),缺失维度从分子分母同时剔除,不填 0、不填中位 3
单任务工分 P = S × 20 × K_偏离 × K_体量 × K_角色 × K_子任务。所有 K 只乘在工分上,不进小计 S;K_体量 默认关闭(K_VOLUME_ENABLED=False),K_角色 默认 1.0
工时偏离度 K_偏离 = h_eff / h,h_eff = min(h,P90) + 0.3×max(0,h−P90);n≥10 启用;物理可行豁免:有起止日期且 h ≤ 自然日×8×0.7×1.5 → K_偏离 = 1。被打折任务逐条单列进报告第五节,证据含原始 h、P90、h_eff、K 值
⚠️ 分档输入 分位数与绝对档一律用原始工时 h,不得用 h_eff(绝对档下用它等于二次惩罚,与 K_偏离 重复打折)
⚠️ 不存在 hours_deviation_weight_compression 开关、「削 B 权重 + 回补」写法——只有上面一种打折实现
分档 P10/30/70/90 右闭;n<5 或 P10==P90 → 绝对档 4/16/40/80h
完整度 分母 = 本批启用维度权重和(不是固定 100),另输出 completeness_vs_100 对照。分层两刀:L1 ≥90%/L2 60%–90%/L3 <60%
总分 只对 L1+L2 求和(INCLUDE_L3_IN_TOTAL=False);L3 不参与分配,另出一行含 L3 的参考总分
冻结 无任何有效维度的任务不填 0、不进任何层、不排名,单列第六节
覆盖度(批次级) min(启用维度基础权重和, 100) / 100;≥60% 分支 A/45–60% 分支 B/<45% 分支 C
40% 封顶 单维归一权重 >40% 触发回流;有效维度 ≤2 时数学不可满足 → 强制 D 分支且不输出工分
相关性 Spearman,n≥10 才执行(n<10 不执行,不猜)
C 经济效益 覆盖率按「非空且非 0」计,<50% 整批关闭,走通用归一化
A 困难程度 关键词规则表(params.A_KEYWORD_TABLE,剥离排除词 → 最长匹配去重 → 取最低档)。只要有任务名/描述就启用:命中率 <20% 只提示「建议校准词表」、不再关闭维度。匹配分两级源:① 任务名(+交付物列)优先;② 任务名无命中才用备注/描述列,依据前缀 描述: 区分。无模型参与
J 复用价值 三档枚举 5/3/1;表里必须有交付物列且命中率 ≥20% 才启用
子任务折价 父任务被判独立任务时,子任务 ×0.60 防重复计分;父被判容器时父子不重复计

完整锚点、权重算例、自检项与参数表见 references/scoring_anchors.md。

脏数据处理

现象 处理
表头不在第一行 前 15 行打分定位,阈值 0.45,失败回显前 15 行
多 Sheet 评分选表,分差 <1.5 报歧义让用户选,默认不合并
纵向合并任务名 按锚点聚合成 1 条,工时/金额求和(防成倍放大)
合计/小计行 关键词 + 可加性自检(没有"合计"二字也能抓)双重判定
2人天 / 8h / 约3天 / 待定 混排 单位三来源:列名 > 日期锚点反算 > 数量级推断
¥12,000 / 1.2万 / 12k 统一转元;列名已含"万"不重复乘
- 待定 N/A 统一空值集,转 NaN 并计入缺失率
「状态」列 内容仲裁:枚举含 通过/驳回/返工/验收 → 归质量;含 已完成/进行中 → 归进度,不参与打分
「优先级 P0-P3」 只喂紧迫性,不喂风险(急 ≠ 错了多严重)
多区块考核表(区块标题 + 独立表头 + 数据,重复多次) detect_blocks 切分区块、每块独立识别表头与列后合并。闸门:第 2 个及以后的表头行正上方必须是区块标题行,否则不切(防单表被切碎)
月评/计划/意见栏被当任务 is_non_task_row 剔除:整行同值(合并标题)、单格文本、或命中 自我月评/下月计划/意见/签字 等
序号列被当成工时 公差为 1 的连续整数列判为 seq,不映射工时(否则 1–13 变成 8–104 小时,排名由行号决定且不报错)

完整清单见 references/field_dictionary.md(24 项质检 + 别名表 + 解析正则)。

参数校准

所有经验值集中在 scripts/params.py,禁止散落硬编码。标注 [需校准] 的必须按团队实际校准后方可用于分配,重点四项:

  • HOURS_PER_MANDAY = 8.0 —— 研发岗常见 6.5–7(单位统一时不影响分位数分档,影响较小)
  • WORKDAY_FACTOR = 0.7 + 无节假日日历 → 工期高估 10–12%,影响面大
  • HOURS_DEVIATION_FACTOR = 0.3(超 P90 部分保留比例)
  • ABSOLUTE_BANDS / COLLAB_LEVEL_CUTS / LOOSE_* / ENTROPY_MIN

换算系数会冻结进 baseline.json,跨批次系数不一致时自动禁用环比比较。

已验证 / 已知限制

已跑通并回归验证(10 份 fixture,tests/):

fixture 验证点
fixture_dirty.xlsx 表头在第 3 行、纵向合并聚合成 1 条、无「合计」字样但等值于上方之和的伪合计行(靠可加性自检抓到)、工时混排 2人天/8h/约3天/待定、金额混排 ¥12,000/1.2万、480h 与 2 天工期的矛盾行只标记不改分、真实 160h 长任务豁免打折
fixture_status_progress.xlsx 「状态」列枚举为 已完成/进行中 → 判为进度列、不映射质量维(否则所有已完成任务同分、E 维退化成常数)
fixture_container.xlsx 容器父任务可加性自检(父 40h = 子 15+15+10 → 父不计分);父工时 >> 子之和 → 父判独立任务、子任务 ×0.6 折价
fixture_serial_date.xlsx Excel 序列号日期(46027 = 2026-01-05)反算可用工时,不被当成工时/金额
fixture_double_header.xlsx 双层表头(父行纵向/横向合并 + 子行细分 → 拼成 工时投入|投入工时)+第三行「单位:人天」单位行 → 工时 ×8
fixture_minimal.xlsx 3 维、n_eff<3 → D 分支,工分列降级为「—」
fixture_only_hours.xlsx 仅工时 → C 分支,只出描述统计;同时作为 --force-points 回归用例(强制出工分不报错)
fixture_gbk.csv GBK 编码 CSV,全角 ¥ 金额
fixture_no_dim.xlsx 无可量化维度(只有任务名+负责人)→ 按放宽后的门槛不再阻断,落 C 分支只出描述统计 + 提示可补充的列(旧口径为退出码 1)
fixture_noheader.xlsx 表头定位失败 → 退出码 1 + 前 15 行回显

已实现但未做回归验证(遇到时以实际输出为准,不要向用户承诺):

  • .xls 旧格式与加密文件(需 xlrd / msoffcrypto,默认环境未装)
  • 多 Sheet 歧义分支(分差 <1.5 需人工指定)、分页重复表头剔除、列级横向合并
  • 「单位行」只解出工时的单位;金额的 万元 单位行暂未回填到金额换算(同列同尺度,不影响相对档位)
  • Excel 输出不回写原文件(不改动用户原表),只另存 *.gongfen.xlsx;如需"原表+打分列"的合表形式, 用明细表的「原表行号」列自行 VLOOKUP 关联,不要在脚本里改写用户文件

依赖

Python ≥3.9(实测 3.13)|pandas / openpyxl / numpy / python-dateutil,版本见 requirements.txt。

文件结构

scripts/
  params.py            全部经验参数(唯一来源)
  excel_io.py          读取、编码嗅探、选表、表头定位、合并展开
  field_recognize.py   别名词典、字段识别、仲裁、单位归一、层级
  quality_stats.py     24 项质检、分档、覆盖度、自检、baseline
  score.py             小计、分层、层内排名、总分(只读 JSON)
  report.py            Markdown 报告、固定句、失败回显
  excel_out.py         打分结果 Excel(工分明细/批次汇总/质检与自检/字段识别)
  run.py               编排入口
references/
  scoring_anchors.md   评分锚点、动态权重、参数表、红线(口径来源)
  field_dictionary.md  别名词典/单位表/解析规则/质检清单(模型与脚本共用)
tests/
  make_fixture.py       生成「故意做脏」的测试表(6 份)
  make_fixture_extra.py 生成 4 份高危场景测试表(状态列/容器父任务/序列号日期/双层表头)
  run_regression.py     回归入口:跑全部 fixture + --force-points 用例,可接真实表路径
python tests/run_regression.py                      # 只跑 fixture
python tests/run_regression.py 你的真实表.xlsx       # 额外跑一份真实表

预期:fixture_noheader.xlsx 退出码 1(故意失败),其余全部 0;末尾打印"全部符合预期"。