前五篇分别讲了评测要回答什么、Agent 和 Skill 怎么测、评分器怎么选、数据集怎么建。这一篇把它们连起来:从一次改动开始,到一个“能不能发布”的结论为止,中间每一步做什么、产出什么。
文中用 Harbor 作为执行层、Langfuse 作为观测和评分层举例。换成其他工具,各个环节的职责也是一样的。
流水线全貌
① 触发 什么变了:Skill、知识库、模型、Harness
↓
② 固定变量 生成运行清单:所有版本号写下来
↓
③ 执行 每个试次一个隔离环境,并发运行,对照组和实验组交替运行
↓
④ 归一 轨迹转成统一格式,写入观测平台
↓
⑤ 评分 验证器 + LLM Judge,分数写回同一条轨迹
↓
⑥ 复核 可疑样本进入人工标注队列
↓
⑦ 分析 配对比较、置信区间、按失败类型拆解、效果与成本
↓
⑧ 决策 门禁:能不能发布
↓
⑨ 回流 新的失败进入错误分析,变成新的用例
| 阶段 | 产出 | 对应章节 |
|---|---|---|
| 触发 | 要跑哪些数据集、对比哪两个配置 | 第 01、03 篇 |
| 固定变量 | 运行清单 | 第 01 篇 |
| 执行 | 每个试次的产物、终态和原生轨迹 | 第 02 篇 |
| 归一 | 统一格式的轨迹 | 本篇 |
| 评分 | 多维分数 | 第 02、04 篇 |
| 复核 | 人工标注,以及 Judge 的 TPR 和 TNR | 第 04 篇 |
| 分析 | 配对差值、置信区间、成本变化 | 本篇 |
| 决策 | 通过、拒绝,或需要人工确认 | 本篇 |
| 回流 | 新用例 | 第 05 篇 |
触发:什么变了,就评什么
第 01 篇说过,评测是一次控制变量实验。所以触发规则可以直接从“改变了哪个变量”推出来:
| 变更 | 要跑的评测 | 对照组 |
|---|---|---|
| 修改某个 Skill | 该 Skill 的能力集、触发用例,再加全量回归集 | 修改前的 Skill 版本 |
| 更新知识库 | 受影响领域的数据集,再加全量回归集 | 更新前的知识库快照 |
| 升级模型 | 第 03 篇的 2×2 复测,再加全量回归集 | 旧模型 |
| 升级 Harness | 全量数据集 | 旧版本的 Harness |
| 没有变更 | 定期运行回归集 | 上一次通过评审的运行 |
Anthropic 的建议是,自动化评测在上线前和 CI/CD 中运行,每次 Agent 改动和模型升级都跑一遍,作为防住质量问题的第一道防线。最后一行“没有变更也定期跑”,是为了发现外部依赖和执行环境的漂移。
全量评测很慢时,可以分两档:每次提交只跑回归集的一个快速子集,发布前再跑全量。
固定变量:运行清单
每次评测开始前,把所有可能影响分数的变量写进一份运行清单,和结果一起保存:
run_id: 2026-10-22-skill-weekly-report
purpose: 周报 Skill v1.3 → v1.4
subject:
model: <模型 ID 和版本>
harness: claude-code@<版本>
skills: # 全部已安装的 Skill,而不只是目标 Skill
weekly-report: v1.4 (git 4f2c9e1)
sales-daily: v2.0 (git a17d3b0)
knowledge_base: snapshot-2026-10-20
baseline:
skills:
weekly-report: v1.3 (git 9b81c22)
dataset: weekly-report-capability@2026-10-18T09:00Z
graders:
verifier: tests@v5
judge-process: v3
environment:
image: eval/sales-warehouse@sha256:...
resources: { cpus: 2, memory: 4G }
trials: 5
schedule: 对照组和实验组同一时段交替运行
前几篇反复提到,好几个工具默认取“最新版本”:Langfuse 的数据集查询默认返回最新版本,已启用的评估规则默认使用评估器的最新版本。运行清单的作用,就是把这些默认值全部替换成显式的版本号。
Langfuse 的对比实验文档也是这样要求的:做发布决策时,基线和候选版本要使用同一个数据集版本和同一套评估器定义,并把应用的 commit、Prompt 或模型版本、评估器版本记录在实验元数据里。文档还特别提醒:固定数据集版本只是固定了测试数据,并不会让模型的输出变得确定。
执行:隔离、并发、交替
执行层负责三件事,第 02 篇已经展开过:
- 隔离:每个试次一个干净的环境,验证器在独立环境中运行。
- 并发:试次之间相互独立,可以大规模并行。HAL 在数百台虚拟机上并行编排评测,把原本需要数周的评测缩短到几个小时。
- 区分失败原因:沙箱失败、模型服务失败的试次作废重跑,Agent 自己超时的试次照常计入成绩。
这里只补充一点:对照组和实验组要在同一时段内交替运行,而不是先跑完一组再跑另一组。第 01 篇提到,通过率会随一天中的时段波动;分开运行时,两组的差异里就会混进时段的影响。
每个试次的产物和轨迹都要保留。评分器更新后,可以直接重新评分(第 04 篇的 Regrade),不用重跑 Agent。
归一:一种轨迹格式,服务所有 Harness
Claude Code、Codex、pi 和自研 Agent 输出的原生日志格式各不相同。如果评分器、查看工具和报告都直接读原生日志,每接入一个 Harness,就要把这些代码全部重写一遍。
更好的做法是在执行和评分之间加一层“归一”,先把各种原生日志转成同一种格式。Harbor 定义的 ATIF 可以作为参考,当前版本是 ATIF-v1.7。它的主要字段是:
| 字段 | 内容 |
|---|---|
agent | Agent 名称、版本、模型,以及可用的工具定义 |
steps | 按顺序记录的系统、用户和 Agent 交互;Agent 的步骤中包含工具调用、对应的观察结果和每一步的用量 |
final_metrics | 汇总的 Token、成本和步数 |
subagent_trajectories | 嵌套的子 Agent 轨迹 |
extra | 自定义的元数据 |
Harbor 会为支持 ATIF 的 Agent 在每次试次后写出 agent/trajectory.json,Claude Code、Codex 和 pi 都在支持之列。NVIDIA 的 ACES 也是先把各个 Harness 的轨迹统一转成 ATIF,再计算指标。
即使不直接采用 ATIF,自定义的轨迹格式也至少要包含这些信息:每一步的类型(消息、工具调用、工具结果)、工具名称和参数、返回结果、Token 用量(区分输入、输出和缓存)、时间戳、最终回复,以及运行清单中的配置信息。
归一后的轨迹写入观测平台。Langfuse 可以通过 SDK 写入,也提供标准的 OpenTelemetry 接收端点。
评分与复核
评分阶段把第 02 篇和第 04 篇的内容组合起来:
- 验证器在独立环境中检查终态、检查点和禁止动作,输出多维结果;
- LLM Judge 评估过程是否合理、表达质量等维度;
- 所有分数都写回同一条轨迹,并带上评分器版本。
人工复核不需要覆盖所有样本,但要有明确的分流规则。下面几类样本值得进入人工标注队列:
| 样本 | 原因 |
|---|---|
| 验证器和 Judge 结论矛盾 | 至少有一个评分器错了 |
| Judge 返回“无法判断” | 第 04 篇预留的出口,需要人来判断 |
| 两个版本之间结论翻转的用例 | 发布决策最依赖的证据 |
| 命中安全红线、疑似作弊、疑似虚报完成 | 一票否决的结论必须确认 |
| 随机抽取的一部分通过样本 | 用来持续估计 Judge 的 TNR |
Anthropic 的态度是:在有人深入检查评测细节、读过一些轨迹之前,不要轻信评测分数。他们建议每周抽样阅读轨迹。分流规则保证了人的时间花在最需要的地方。
分析:差异是不是真的
用配对差值算置信区间
第 03 篇讲过,比较两个版本时要按用例配对。具体算法:
1. 每条用例 i,分别算出两个版本在 n 次执行中的通过率:a_i 和 b_i
2. 计算每条用例的差值:d_i = b_i − a_i
3. 差值的均值 d̄,就是提升幅度
4. 标准误:SE = sd(d) / √N,N 为用例数
5. 95% 置信区间:d̄ ± 1.96 × SE
举个例子(数字仅作示意):40 条用例,每条执行 5 次。差值的均值是 +12 个百分点,差值的标准差是 0.31。配对标准误为 0.31 / √40 ≈ 0.049,95% 置信区间约为 [+2, +22] 个百分点,没有跨过 0,可以认为提升是真实的。
如果不配对,把两个版本当作两组独立样本来算,假设每组用例得分的标准差都是 0.40,标准误就变成 √((0.16 + 0.16) / 40) ≈ 0.089,置信区间约为 [−6, +30] 个百分点,跨过了 0,结论就变成“无法确定是否有提升”。同样的数据,配对之所以更精确,是因为两个版本跑的是同一批用例,用例本身难易的影响在相减时被抵消了。
Evan Miller 的 Adding Error Bars to Evals 还给了几条建议:
- 用例成组时用聚类标准误。比如多条用例派生自同一条线上轨迹、同一份文档,它们不是相互独立的,按独立样本计算会低估不确定性。
- 对同一用例多次执行,取平均分再计算。执行次数多到一定程度后,再增加的收益就很小了。
- 不要为了减少波动去调低采样温度,除非你要评测的就是低温度下的模型。
- 报告时给出:每个版本分数的标准误、配对差值及其标准误,以及两个版本分数之间的相关性。
事先算出能发现多大的差异
Miller 的论文还给出了样本量公式,可以反过来算“最小可检测效应”:在给定的用例数和执行次数下,有 80% 的把握发现的最小差异。下表沿用论文示例中的方差假设,并只作量级参考。实际使用时,应该用自己的历史数据估计方差:
| 用例数 | 每条执行次数 | 最小可检测效应 |
|---|---|---|
| 50 | 1 | 约 26 个百分点 |
| 50 | 5 | 约 17 个百分点 |
| 100 | 1 | 约 19 个百分点 |
| 100 | 5 | 约 12 个百分点 |
| 400 | 5 | 约 6 个百分点 |
| 1000 | 1 | 约 6 个百分点 |
这张表有两个用处。第一,在评测开始之前就知道这次评测能不能回答问题:如果预期提升只有 5 个百分点,100 条用例、每条 5 次是测不出来的。第二,帮助决定预算花在哪里:每条执行次数从 1 增加到 5,效果明显;但想把最小可检测效应再降一半,主要靠增加用例数。论文中的示例结论是,要可靠地检测 3 个百分点的差异,大约需要 1,000 道独立的题目。
置信区间跨过 0,不代表“没有差异”,只代表“这次评测分辨不出来”。
报告:效果、代价和证据放在一起
报告的顺序建议是:先给结论和置信区间,再给逐条用例的变化,最后给成本和证据。Langfuse 的文档用一个例子说明了为什么逐条变化不可省略:两次运行的准确率都是 50%,但一次是用例 A 通过、B 失败,另一次正好相反。只看平均分,会以为什么都没变。
成本要和效果放在一起看。CLEAR 统计发现,精度相近的方案之间,成本可以相差 50 倍;HAL 在 21,730 次运行中发现,大多数情况下调高推理强度反而降低了准确率。所以在模型选型、调整推理强度、决定是否启用某个 Skill 时,报告里应该有一张效果与成本的散点图:横轴是单任务成本,纵轴是通过率,每个配置一个点。在效果相近的点之间,选成本低的;只有当效果的提升超出置信区间时,多花的成本才有意义。
一份报告的骨架(数字仅作示意):
结论 周报 Skill v1.4:建议发布
提升 通过率 62% → 74%,配对差值 +12pp,95% 置信区间 [+5, +19]
回归集 无关键用例退化;安全违规 0;虚报完成 0
逐条变化 提升 8 条 / 持平 30 条 / 退化 2 条(每条附两个版本的轨迹链接)
成本 单任务成本 +9%,P90 耗时 +4%
复核 进入人工队列 11 条,其中 Judge 误判 2 条,已修正评分标准
运行清单 run_id 2026-10-22-skill-weekly-report
决策:门禁怎样参与发布
门禁规则要在看结果之前定好。Langfuse 的文档特别提醒:先定发布规则,比如“每条必需的用例都要通过”,或者“候选版本必须保持所有已批准的通过结果”,再去看结果;已知的失败必须被明确接受;更新的一次运行,不会自动成为已批准的基线。
一套可以参考的门禁:
| 检查 | 通过条件 |
|---|---|
| 安全 | 违规数为 0 |
| 回归集 | 之前已批准通过的关键用例没有变成失败;配对差值的置信区间没有整体落在 0 以下 |
| 能力集 | 如果要声称有提升,配对差值置信区间的下限大于 0 |
| 成本 | 单任务成本和耗时的变化在预算范围内 |
| 评测健康 | 冒烟测试通过,没有用例缺失结果 |
最后一行容易被忽略。Langfuse 的文档说得很直接:缺失的用例不等于通过的用例。门禁也要区分“被测对象没通过”和“流水线自己出错了”。NVIDIA SkillEvaluator 的做法是用不同的退出码区分:0 表示所有门禁检查通过;1 表示检查未通过或运行失败;2 表示用法错误,比如参数不对、路径不存在,这时要修的是流水线,而不是 Skill。它还建议渐进式接入:先上不需要模型调用的离线检查,再逐步加入依赖 LLM 的检查。
门禁没通过时,结果有两种:拒绝发布,或者由负责人看过逐条失败之后,明确接受已知的失败。不能因为“这次分数也不算差”就默认放行。
离线评测之外
离线评测是第一道防线,但不是唯一的一道。Anthropic 用安全工程里的瑞士奶酪模型来描述:每一层都有漏洞,多层叠在一起,漏过一层的问题会被另一层拦住。
| 方法 | 什么时候用 | 能补上什么 |
|---|---|---|
| 自动化离线评测 | 每次改动、每次模型升级 | 快速、可复现、不影响用户 |
| 线上监控 | 上线之后 | 真实用户的行为和分布漂移 |
| A/B 测试 | 流量足够、改动较大时 | 真实的业务结果 |
| 用户反馈 | 持续 | 没预料到的问题 |
| 人工阅读轨迹 | 每周抽样 | 自动检查漏掉的细节 |
线上和离线可以共用同一套评分器。以 Langfuse 为例,评估规则可以按过滤条件和采样率,对线上的观测记录自动运行 LLM Judge;线上发现的失败轨迹,可以直接加入数据集,进入第 05 篇的错误分析和用例生命周期。这样,流水线的最后一步“回流”就和第一步接上了。
小结
- 触发:按“改变了哪个变量”决定跑哪些评测、和谁对照;没有变更也定期运行回归集。
- 运行清单:把模型、Harness、全部 Skill、知识库、数据集、评分器、环境的版本都显式写下来,不依赖任何“默认最新”。
- 执行与归一:隔离、并发、交替运行;把各个 Harness 的轨迹转成统一格式,评分器只写一次。
- 评分与复核:分数写回同一条轨迹;按规则把可疑样本分流给人。
- 分析:用配对差值算置信区间;事先算出能检测的最小差异;置信区间跨过 0 只代表分辨不出来。
- 报告与门禁:结论、逐条变化、成本和证据放在一起;门禁规则事先定好,区分被测对象的失败和流水线的失败。
下一篇是系列的最后一篇:常见的误区,以及团队从零开始搭建评测时的推进顺序。