前三篇里,每个判断最后都落在评分器上:终态检查、检查点、禁止动作、Skill 是否触发。评分器判错了,前面的结论就全部跟着错。
Anthropic 在 Demystifying evals for AI agents 中举过一个例子:Claude Opus 4.5 在 CORE-Bench 上最初只得了 42%。一位研究员检查后发现了多个问题:评分过于死板,期望值是 “96.124991…” 时,把 “96.12” 判为错误;有些任务描述有歧义;有些任务带有随机性,根本无法精确复现。修复这些问题,并放宽 Harness 的限制之后,分数升到了 95%。
所以这一篇回答两个问题:选什么评分器,以及怎么证明它判得对。
五种评分器
| 评分器 | 怎么判 | 适合 | 主要风险 |
|---|---|---|---|
| 规则 | 字符串、正则、数值比较、格式校验 | 有明确答案的结果 | 太死板,误杀等价的正确答案 |
| 脚本 | 查询终态、运行测试、解析轨迹 | 终态、检查点、禁止动作 | 和任务说明不一致 |
| LLM Judge | 按评分标准阅读输出或轨迹 | 开放式输出、过程是否合理 | 有偏差,必须校准 |
| Agent Judge | 调用工具去核查:读文件、运行代码、查数据 | 需要动手验证的复杂产物 | 本身就是 Agent,成本高,也需要评测 |
| 人工 | 领域专家审阅或抽检 | 校准其他评分器,主观判断 | 慢、贵、难以规模化 |
Anthropic 的建议是:能用确定性评分器的地方就用确定性评分器;必要时,或者需要更多灵活性时,再用 LLM 评分器;人工评分谨慎使用,主要用于验证。按这个原则,可以这样选:
结果能用代码精确判定吗?
是 → 规则或脚本
否 → 判断时需要查看环境、运行代码吗?
是 → Agent Judge
否 → LLM Judge
所有模型评分器 → 用人工标注校准,并定期抽检
对应到第 01 篇的六个维度:
| 维度 | 首选评分器 |
|---|---|
| 完成度 | 脚本:查询终态 |
| 过程检查点 | 脚本:解析轨迹 |
| 过程是否合理 | LLM Judge:阅读轨迹 |
| 安全合规 | 规则和脚本:扫描轨迹 |
| 耗时和成本 | 直接计算 |
| 表达质量 | LLM Judge |
一条用例通常有多个评分器。Anthropic 列出了三种组合方式:加权求和后与阈值比较;所有评分器都通过才算通过;两者混合。第 02 篇用的是混合方式:终态、禁止动作和预算必须全部通过,其余指标单独记录。
确定性评分器也会出错
规则和脚本不会“理解错”,但会“写错”。Anthropic 记录了几类典型问题:
- 太死板:CORE-Bench 中,“96.12” 因为与 “96.124991…” 不完全相等被判错。
- 和任务说明不一致:审查 Terminal-Bench 时发现,有的任务要求 Agent 写一个脚本,却没有指定文件路径,测试却假定脚本在某个特定路径下。Agent 并没有做错,却被判为失败。
- 判定条件写错:METR 发现,有些任务要求 Agent 把分数优化到某个阈值,评分却要求超过这个阈值。照着要求做的模型反而被扣分。
对应的做法:
- 容忍等价写法:数值留出容差;文本先归一化再比较;SQL 比较语义,而不是比较字面(见第 02 篇)。
- 评分器检查的每一项,都要能在任务说明里找到。
- 上线前做冒烟测试:用参考解跑一次,必须通过;什么都不做跑一次,必须失败。
Harbor 正好预置了这两种 Agent。oracle 运行任务自带的参考解,官方文档建议编写任务时用它确认任务是可解的;nop 什么都不做。如果 nop 也能通过,说明评分器在环境的初始状态下就判了通过,例如只检查了一个本来就存在的文件。
LLM Judge:怎么写评分标准
用二元判定,不用 1–5 分。Hamel Husain 和 Shreya Shankar 解释过原因:相邻分数之间(比如 3 分和 4 分)的差别很主观,不同的标注者理解不同;检测分数变化需要更大的样本量;标注者还容易选中间值来回避判断。如果要追踪渐进的改进,可以拆成多个二元检查,比如“5 个应包含的事实中包含了 4 个”。
一个维度一个 Judge。Anthropic 建议为每个维度写清楚的评分标准,并用独立的 Judge 分别评判,而不是让一个 Judge 同时评判所有维度。
允许回答“无法判断”。Anthropic 建议给 Judge 一个出口,在信息不足时返回 “Unknown”,避免它为了给出答案而编造理由。
先写依据,再给结论。skill-creator 的评分结果要求每条断言都附上证据;Langfuse 的 LLM Judge 也会在分数之外返回评判理由。有了依据,人工复核时才能判断 Judge 错在哪里。
提供参考答案。下文会提到的 FBI 研究发现,提供参考答案的评判方式,明显比只看单个回答或两两比较更可靠。
给 Judge 看轨迹,而不只是最终回复。只读最终回复的 Judge 看不到工具选择、错误恢复和多余步骤。Langfuse 的评估器可以把工具调用映射进 Judge 的提示词。
下面是第 02 篇中“取数过程是否合理”这个维度的评分标准示例:
维度:取数过程是否合理(只判断这一项)
输入:任务说明、轨迹中的全部 SQL 及其返回结果、参考 SQL
满足任意一条即判为“不通过”:
- 查询了与任务无关的表
- 对大表执行了没有分区条件的全表扫描
- 已经得到正确结果后,继续执行无关的查询
输出:
- evidence:引用轨迹中的具体 SQL,说明判断依据
- verdict:通过 / 不通过 / 无法判断
LLM Judge 的已知偏差
Judging LLM-as-a-Judge 系统研究了 LLM Judge 的局限:位置偏差、冗长偏差、自我偏好,以及有限的推理能力。同一篇论文也发现,强模型做 Judge 时,与人类判断的一致率可以超过 80%,和人与人之间的一致率相当。所以 LLM Judge 可以用,但要知道它会在哪里出错:
| 偏差 | 表现 | 缓解 |
|---|---|---|
| 位置偏差 | 两两比较时,偏向某个固定位置 | 交换顺序各判一次,两次结论不一致时记为平局 |
| 冗长偏差 | 偏向更长的回答 | 评分标准写明长度不加分;用二元判定 |
| 自我偏好 | 偏爱自己或同家族模型生成的内容 | 以和人工判断的一致性为准,一致性不达标再换模型 |
| 被说服 | 采信 Agent 对自己行为的解释 | 只给 Judge 证据,不给 Agent 的自我评价;结合终态脚本 |
| 推理有限 | 复杂计算或长轨迹判断出错 | 计算交给脚本;按维度拆分 |
关于自我偏好,后续研究发现,LLM 能在相当程度上认出自己生成的文本,而且这种识别能力越强,自我偏好就越明显。不过 Hamel Husain 的看法更务实:真正要看的是 Judge 和人工判断是否一致,不必默认换一家模型来当 Judge。
“被说服”在 Agent 评测里尤其要警惕。ImpossibleBench 发现,监控模型会漏掉一些隐蔽的作弊:Agent 以“向后兼容”为理由,实现了一个违背需求、但恰好能通过测试的行为。Agent 给出的理由越合理,Judge 越容易被带偏。
校准:用人工标注证明 Judge 判得对
LLM Judge 本质上是一段 Prompt。上线之前,要先证明它的判断和人一致。
第一步:先让人和人一致
同一批轨迹由多人独立标注,用 Cohen’s κ 这类排除了随机一致的指标衡量一致性。人和人之间都不一致,说明评分标准本身有歧义,这时应该先讨论分歧、修改标准,再重新标注。Anthropic 对好用例的定义也是如此:两位领域专家各自判断,能得出相同的通过或不通过结论。
不要指望一开始就把标准写完整。Who Validates the Validators? 把这个现象称为“标准漂移”:人需要标准才能给输出打分,但正是在给输出打分的过程中,人才逐渐明确了标准。所以评分标准应该在标注过程中迭代,标完一轮再定稿。
第二步:用 TPR 和 TNR 衡量 Judge
把标注好的数据分成三份:训练集,用作 Judge 提示词里的示例;开发集,用来对比 Judge 和人工的判断、迭代提示词;测试集,留到最后做一次检验。只在开发集上调好了,不代表在新数据上也好。
衡量时看两个指标,而不是总体一致率。这里把“有错误”记为正例:
- TPR(真阳性率):人工判定为失败的输出中,Judge 抓出了多少。
- TNR(真阴性率):人工判定为合格的输出中,Judge 正确放过了多少。
只看总体一致率会被类别不平衡误导。如果 90% 的输出都是合格的,一个永远判“通过”的 Judge 也有 90% 的一致率,但它一个失败都抓不出来,TPR 是 0。
第三步:按维度分别校准
同一个 Judge 在不同维度上的可靠性可能差别很大。Counsel 收集了人工对 Agent 轨迹评判结果的复核,人工标注者之间的一致性达到 Krippendorff’s α = 0.78。在这份数据上,最强的开源 Judge 在错误位置上与人工判断的一致率约为 88%,在错误原因的解释上只有约 65%。找出哪一步错了,比说清为什么错要容易得多。所以每个维度都要单独计算 TPR 和 TNR。
第四步:上线后持续抽检
Judge 模型升级、评分标准修改、被测 Agent 的行为变化,都会让 Judge 和人工之间的一致性发生漂移。上线后要定期抽样人工复核,重新计算 TPR 和 TNR。
以我目前使用的 Langfuse 为例,这套流程可以在一个平台上完成:领域专家在标注队列里,按预先定义的评分配置给轨迹打分、写评论,必要时补充正确输出;LLM Judge 评估器把分数写到同一批轨迹上;再在 Score Analytics 里对比两者的一致性,据此校准 Judge。
进阶:用 Judge 的误差修正通过率
知道了 Judge 的 TPR 和 TNR,还可以修正观测到的通过率。设 p 为 Judge 判定的通过率:
真实通过率 ≈ (p + TPR − 1) / (TNR + TPR − 1)
这是流行病学中常用的 Rogan–Gladen 校正。举个例子:Judge 只能抓出一半的失败(TPR = 0.5),合格的输出 95% 都能正确放过(TNR = 0.95),观测通过率为 80%,那么真实通过率约为 (0.80 + 0.50 − 1) / (0.95 + 0.50 − 1) ≈ 67%。一个偏宽松的 Judge,会让通过率虚高十几个百分点。前提是 TPR 和 TNR 是在有代表性的标注集上估计出来的。
Agent Judge:需要动手核查时
有些产物只读文本判断不了:报告里的数字对不对,要重新查一次数据;代码能不能运行,要真的跑一次。这时可以让 Judge 也成为 Agent,带上工具去核查。
Agent-as-a-Judge 在 DevAI 上验证了这种做法。DevAI 包含 55 个 AI 开发任务,共 365 条分层的用户需求。论文发现,Agent Judge 的表现远好于 LLM Judge,可靠性和人工评估基线相当。Harbor 的 RewardKit 也支持在同一个验证器中组合程序化检查和 LLM 或 Agent Judge。
要注意,Agent Judge 本身就是一个 Agent。它的模型和版本要固定,要在隔离环境中运行,要设置预算,也要用人工标注校准。
评分器的版本管理
第 01 篇说过,评分器本身也是变量。所以每个分数都要记录产生它的评分器版本。
这在实践中很容易被忽略。以 Langfuse 为例,它的文档说明:修改评估器会生成新版本,已经启用的评估规则会自动使用最新版本。如果不额外记录,同一个分数名称在不同时间段对应的可能是不同版本的评分器,趋势图上的变化就说不清是 Agent 变了,还是评分器变了。评分标准发生实质变化时,更稳妥的做法是新建一个评估器,使用新的分数名称。
评分器更新后,历史数据不需要重跑 Agent,只需要重新评分。Harbor 的 Regrade 就是用更新后的验证器,对已经记录下来的输出重新评分,Agent 阶段不会重跑。前提是保留了每次执行的产物和轨迹。
上线新评分器之前,可以给评分器本身做一次回归测试:用新旧两个版本对同一批输出评分,列出结论发生翻转的样本,逐条人工复核。只有翻转的样本都是在纠正旧版本的错误时,才替换旧版本。对比两个版本的 Agent 时,如果评分器换过,要先用新评分器重新评一遍基线。
变异测试:检验评测能不能发现问题
软件测试里有一种方法叫变异测试:故意往代码里注入已知的缺陷,看测试能不能发现。没被发现的变异,就是测试的盲区。评测可以照搬这个方法。
这个方法对 LLM Judge 特别必要。FBI 构造了 2,400 个扰动后的回答,覆盖 22 类扰动,每一类都明确降低了某项能力的质量。结果,被测的 5 个常用评估模型平均有超过一半的质量下降没有被识别出来。
可以注入三类变异:
| 变异对象 | 例子 | 应该由谁发现 |
|---|---|---|
| 产物 | 把 report.md 中的一个数字改错;删掉必需的章节;加入一句没有依据的结论 | 终态脚本、LLM Judge |
| 轨迹 | 在一条通过的轨迹中插入一条 DELETE 语句;删掉分区过滤这一步 | 禁止动作规则、检查点脚本 |
| Skill | 删掉 SKILL.md 中的关键步骤;把公式改错;加入互相矛盾的指令 | 整套评测:通过率应该明显下降 |
前两类变异只需要重新评分,不用重跑 Agent,成本很低;第三类需要重新执行,适合在发布新的数据集版本或新的评分器之前做。
衡量结果用变异检出率:被发现的变异数除以注入的变异数。每一个存活下来的变异,都对应一条该补的断言或用例。
第 03 篇提到的“有没有 Skill 都通过的断言”,可以看作一种不需要注入变异的低成本检查。第 02 篇的不可能用例还有第二个用途:ImpossibleBench 指出,在不可能任务上的任何通过都必然是作弊,所以这些轨迹天然就是一份带标签的数据,可以用来检验作弊监控能不能把它们识别出来。
小结
- 评分器选择:能用确定性评分器就用;必要时用 LLM Judge;需要动手核查时用 Agent Judge;人工用于校准和抽检。
- 确定性评分器:容忍等价写法,判定条件和任务说明保持一致;用参考解和空跑做冒烟测试。
- LLM Judge 的写法:二元判定,一个维度一个 Judge,允许“无法判断”,先写依据再给结论,提供参考答案和轨迹。
- 校准:先让人和人一致;用 TPR 和 TNR 而不是总体一致率衡量 Judge;按维度分别校准;上线后持续抽检。
- 版本:每个分数记录评分器版本;评分器更新后重新评分,并对翻转的样本做人工复核。
- 变异测试:注入已知缺陷,用变异检出率衡量评测能不能发现问题。
下一篇讲数据集:用例从哪里来,怎样覆盖正反例和边界,以及怎样长期维护。