「感觉顺畅多了」不算证据:每个指标都要说清来源、采集命令、基线、目标、频率这五件事。
轮到采数时,直接跑采集脚本里的 sh scripts/metrics.sh,每周一一次。
这张表里的每个数字,别人能不能用一条命令自己复现出来?
答「不能」,说明这个数字来自某人的印象或某个已经打不开的控制台。先把它接上一条命令——采不动的指标,宁可不看。
七个指标,每个都能用一条命令采到。基线值取本组启用这套规范之前 4 周的实测值;项目刚开始、没有历史数据时,用第一次采集的值当基线并标注「首次采集」。此后不能再改基线——改基线等于把尺子换掉,趋势就读不出来了。
| 指标名 | 数据来源 | 采集命令 | 基线值 | 目标值 | 采样频率 |
|---|---|---|---|---|---|
| 门禁拦截次数 | 持续集成的失败构建 | gh run list --status failure --limit 50 --json conclusion | jq length | 0(首次采集) | ≥ 1/周,且不连续两周为 0 | 每周一 |
| 格式类评审意见占比 | 合并请求评论 | 见下节脚本的 review_mix | 41%(启用前 4 周) | ≤ 20% | 每周 |
| 返工率 | 同一文件的重复改动 | 见下节脚本的 rework | 14%(启用前 4 周) | 相对基线下降 ≥ 20% | 每周 |
| 跳过用例数 | 测试输出 | pytest -q 2>&1 | grep -c SKIPPED | 0 | 不增长;出现即建 issue | 每次合并 |
| 圈复杂度超限函数数 | 静态检查 | ruff check --select C901 . --statistics | 4 | 不增长 | 每周 |
| 评测通过率(core 集 40 题) | 评测输出 | python eval/run.py --set core | 68%(首次全量) | no_answer 与 other_class 两类 100% 拒答,总答对率 ≥ 80% | 每次发布前 |
| 仓库说明行数 | 文件行数 | wc -l AGENTS.md | 143 | ≤ 200,且不单调增长 | 每周 |
边界:这七个里,先看门禁拦截次数和跳过用例数这两个。前者的基线是 0、目标是「不为 0」,因为一个从不拦东西的门禁和被关掉的门禁分辨不出来;后者一旦增长,说明有人绕过失败的用例,而不是修好它。
把能一条命令采到的固定下来,省掉每次手工敲。脚本放在仓库里,和检查入口并列。跑不通的指标先空着,不要手填。
每周一跑一次,输出直接贴进周报。rework 与 review_mix 里的关键词按项目实际的评论用语改。
#!/bin/sh
# 每周一跑一次:sh scripts/metrics.sh
set -e
echo "门禁拦截次数: $(gh run list --status failure --limit 50 \
--json conclusion | jq length)"
echo "跳过用例数: $(pytest -q 2>&1 | grep -c SKIPPED || true)"
echo "超限函数数: $(ruff check --select C901 . --statistics | wc -l)"
echo "仓库说明行数: $(wc -l < AGENTS.md)"
echo "评测通过率: $(python eval/run.py --set core | tail -1)"
# 返工率:近 4 周内被改动两次以上的文件数 ÷ 被改动过的文件数
rework() {
git log --since="4 weeks ago" --name-only --pretty=format: \
| grep -v '^$' | sort | uniq -c | awk '{if ($1>1) r++} END {print r/NR}'
}
# 格式类评审意见占比:近 10 次合并请求的评论里含格式类词的条数 ÷ 总条数
review_mix() {
gh api repos/:owner/:repo/pulls/comments --paginate \
--jq '[.[].body] | (map(select(test("空格|缩进|引号|换行|行宽"))) | length)
/ (length)'
}
看到的提交速度和合并数量都会因为助手加入而上升,这本身不说明任何问题。要把它和返工率放在一起看,四种组合的含义完全不同。
| 速度 | 返工 | 说明什么 | 怎么办 |
|---|---|---|---|
| 上升 | 下降或平稳 | 工具真的在起作用 | 维持;可以按周逐步放宽非关键环节 |
| 上升 | 上升 | 速度被转成了技术债 | 停下来查两件事:门禁覆盖够不够、改动是不是拆得太粗 |
| 平稳 | 上升 | 判据缺失,改完又改 | 补规约与检查,先别谈效率 |
| 下降 | 上升 | 评审成为瓶颈 | 把可自动化的检查从评审里移出去,接进 make check |
第二行是 AI 团队最典型的陷阱:所有数字都在变好,只有返工在涨,而返工通常要几周后才反映到交付上。看到第二行,第一件事是打开最近三次返工的改动差异,看它们是不是都改了同一处逻辑。
sh scripts/metrics.sh,把七个数字填进 docs/metrics/<年>-W<周>.md。只和上上周比,不和别的项目比——绝对值跨项目不可比。docs/metrics/,不要只留在会上。下个月看趋势时,要知道上个月改了什么。写周报只写三节:一张对照基线与目标的表、本周发现(每条带负责人与期限)、下周动作(一次一条)。下面第 40 周那份可以直接当模板抄。
判定一列只写「达标 / 未达标 / 超线」,不写解释——解释放在「本周发现」里。
# 第 40 周质量与用量 - 统计窗口:2026-09-28 ~ 2026-10-04 - 采集人:李(轮值) - 采集命令:sh scripts/metrics.sh ## 指标 | 指标 | 本周 | 基线 | 目标 | 判定 | |---|---|---|---|---| | 门禁拦截次数 | 3 | 0(首次采集) | ≥1/周 | 达标 | | 格式类评审意见占比 | 12% | 41% | ≤20% | 达标 | | 返工率 | 9% | 14% | 相对基线降 ≥20% | 达标 | | 跳过用例数 | 1 | 0 | 不增长 | 超线 | | 超限函数数 | 2 | 4 | 不增长 | 达标 | | 评测通过率(core 40 题) | 78% | 68% | ≥80% | 未达标 | | 仓库说明行数 | 151 | 143 | ≤200 | 达标 | ## 本周发现 1. 跳过用例 +1:tests/api/test_search.py::test_pagination 被 skip, 理由只写了「待修」。已建 issue #57,负责人:王,期限 2026-10-08。 2. 评测通过率 78%:错的 9 题里 4 题是 no_answer 类,模型编造了出处。 下周把判分规则里「无答案必须拒答」的权重从 1 提到 3,并补 4 条测试。 3. 返工率下降但仍有 9%:两次返工都改在 app/kb/data.py 的同一个查询上, 与本周的 class-isolation 变更重叠,暂不追加动作,下周继续观察。 ## 下周动作 - 把「无答案必须拒答」写进 openspec/specs/kb-answer.md 的 Scenario, 并补 4 条测试进 make check。负责人:张,期限 2026-10-11。
边界:周报用来发现问题和留痕,不是用来考核。一旦把「跳过用例数」按人排名,下个月组里第一个动作一定是把 skip 改成 xfail,数字好看了,问题还在。指标只用于看趋势。
| 指标 | 本周 | 基线 | 目标 | 判定 | |---|---|---|---|---| | 门禁拦截次数 | 0 | 0 | ≥1/周 | 达标 | | 格式类评审意见占比 | 18% | 41% | ≤20% | 达标 | | 返工率 | 13% | 14% | 降 ≥20% | 达标 | | 跳过用例数 | 0 | 0 | 不增长 | 达标 |
认它的办法:先看「门禁拦截次数」这一行是不是 0。这张表四项全达标、看着很漂亮,但门禁拦截 0 次意味着它一次都没拦住过东西——一个从不拦东西的门禁,和被关掉的门禁分辨不出来。这一项的目标反着写(≥ 1/周)就是这个原因。第二个要看的是基线那一列有没有被改过:基线一改,尺子就换了,趋势读不出来。