Agent Eval:Golden Dataset、指标与回归
一句话定位:给 Agent 配一套「考卷 + 判卷 + 成绩单 + 错题本」——本文给出题集的建法、判法的完整谱系、六个核心指标、十三类失败归因与回归门的做法,全部对齐到一个 29 行可跑的迷你判卷器。前置:Harness 总览——先有五部件的骨架,才谈得上给骨架打分。检索评估的实操在旗舰项目篇已经带做了一遍,本篇把它推广到整个 Agent。
先从「改了一句提示词」说起
你优化了一句提示词,新任务的成功率肉眼可见地涨了,开心上线。三天后客服来问:「上周明明修好的退款问题,怎么这两天又开始答错了?」
你翻记录:改动前后没有任何对比——新题涨了多少、旧题塌了几道、哪类失败变多了,一笔账都没有。「感觉变好了」和「变好了」之间,隔着一整套评估体系。
怎么判断一次改动是净赚还是净亏?
四步:
- ① 建题集——golden set,带标准答案的考卷。
- ② 定判法——谁来判断答案对不对。
- ③ 记指标——成功率、幻觉率这些成绩单。
- ④ 回归与归因——旧题不许塌、失败要有错题本。
本篇四步逐个落地。
全景图:评估体系的流水线
图 1:Agent 评估流水线——①题集 ②判法 ③指标 ④回归与归因;错题反哺题集成闭环,上线判据是新题涨且旧题不塌
渐进拆解:给 Agent 配一个质量部
类比:传统软件的质量部就是这套流水线。题集是卷库,判法是阅卷规则,指标是成绩单,失败归因是错题本,回归门是补考——旧学期挂过的科目,新学期必须重考。Agent 的麻烦在于答案不唯一:同一问题两次回答可以措辞全异却都对,所以「判卷」这一步比传统软件难得多,值得单独一节讲。
① 题集:先有考卷,再有教学
golden set 的四列格式(问题、应命中块、答案要点、失败归类)在旗舰项目篇定过,推广到 Agent 只需把「应命中块」换成「该走的步骤与该碰的工具」。题集分两栏:新题针对本次改动的新用例,旧题是每次全量重跑的存量用例——「新题涨、旧题不塌」的回归门(见④)靠这个分栏才成立。覆盖面照任务类型拉清单:代码理解、代码修改、检索问答、长程多步任务各占一个区块,每区按难度分层。两条纪律:
- 自设计防背题:公开基准会被头部模型「背过」(代码库实战篇讲过 SWE-bench 停报的前车之鉴),自己的业务题才是护城河。
- 验收先于作答:判卷规则写好并先验证规则本身是对的,再开放跑批,否则考卷出错冤枉的是学生。
② 判法:从便宜到贵的六级阶梯
判卷的完整谱系按成本从低到高分六级:
| 判法 | 成本 | 适用场景 | 失效方式 |
|---|---|---|---|
| 规则判 | 最低,机器可判秒出 | 必含要点命中、禁含词零现 | 只认题面收录的判据,判据外的要点丢失不报警 |
| Schema 判 | 低 | 输出结构对不对:JSON 能否解析、字段是否齐全 | 结构对但内容错时不报警 |
| 快照判 | 低 | 与上次通过的答案逐字比对,适合「一个字都不许变」的结算与法务场景 | 措辞一变就报警,分不清「正常改写」与「事实漂移」 |
| 参考答案比对 | 中 | 与人工写的参考实现或标准答案做语义比对 | —— |
| LLM 判卷 | 中,便宜模型当裁判 | 按评分维度打分 | 位置、冗长、自我偏好三大偏差 |
| 人工 | 最贵 | 模糊案例与前五档拿不准的部分 | —— |
用法不是六选一,是分层漏斗:便宜的判法先过一遍,剩下的疑难杂症逐级上贵判法。
LLM 判卷单独说——它是谱系里最诱惑也最坑的一档。评测研究者已经系统量化了判卷模型的三大偏差,各配一个便宜的缓解:
| 偏差 | 表现 | 对应缓解 |
|---|---|---|
| 位置偏差 | 同内容换个位置分数就变(2025 年 AACL-IJCNLP 的系统研究给过量化) | 换位重判:A/B 位置互换各判一次取一致 |
| 冗长偏差 | 谁长谁得分高,与质量无关 | 拆评分维度:把「好不好」拆成五六个可独立判断的小问 |
| 自我偏好 | 裁判偏爱像自己风格的答案 | 做与验收分离:生成答案的模型不给判自己的卷——用外部硬判据兜底,Agent 判自己的作业并不可靠 |
打分之外还有两两对比的 Pairwise 模式:不绝对打分、只判 A 与 B 谁好,适合没有标准答案的偏好类评测——位置偏差的量化研究正是在 pairwise 设定下做的。所以 LLM-as-Judge 的边界是:在有客观判据的任务上不可靠也没必要(直接用规则判),在开放式生成任务上可用但必须拆维度加换位,用便宜模型打小分、拿不准的升级人工——可靠性来自流程设计,不来自裁判模型多贵。
③ 指标:六项成绩单
核心指标六个,各答一个问题:
- 任务成功率:最终做成了吗(业务方最关心)。
- 工具准确率:该调的工具调对了吗。
- 引用准确率:答案的出处引用靠得住吗。
- 幻觉率:没根据的话占比多少。
- 人工接管率:多少单子最后转了人(成本与体验的双重信号)。
- 延迟与成本:达成质量花了多少时间与 token;延迟看 p95 而非平均值——体验由最慢的一批请求决定。
前四项判质量,后两项判代价——只报质量不报代价的评估是半份成绩单。
④ 回归与归因:错题本与补考
每次改动(提示词、模型、工具、知识库)上线前跑一遍全量题集:新题要涨、旧题不许塌——与微调篇「两把尺子」同一条纪律。塌了的旧题和新的失败案例进错题本:失败现场从可观测性篇的 Trace 与 Replay 里捞出来,把常见失败归成十三类,覆盖面够用——提示词、上下文、检索、工具选择、参数、权限、执行、死循环、委托、模型能力、幻觉、引用、评测误判(最后一条最容易被忽略——有时不是 Agent 错了,是考卷错了)。归因不是给失败贴标签,是统计分布:哪类失败占大头,改进就往哪投。
图 2:回归门的一次判定(示意数字)——同一套题集跑改动前后两版,新题涨但旧题塌,判定不通过;塌掉的题逐条归因后进错题本
动手:29 行的迷你判卷器
三个黄金要素——必含要点、禁含词、上次通过的快照——就能拦住最常见的回归。保存为 judges.py:
# 三要素、两档判法:改动后谁拦得住回归
GOLDEN = [ # 题集:问题 + 必含要点(机器可判事实)+ 禁含词
{"q": "退货期限", "must": ["30 天"], "ban": ["90 天"]},
{"q": "运费谁出", "must": ["买家"], "ban": []},
{"q": "开发票", "must": ["电子发票"], "ban": []},
]
V1 = ["退货请在 30 天内申请,特殊商品除外。", # 旧版:全对
"运费由买家承担。",
"支持电子发票,开具后 30 天内可换开。"]
V2 = ["退货期限是 90 天。", # 新版:期限错了(回归)
"非质量问题运费由买家承担。",
"支持电子发票,开票后可自助换开。"] # 后两条:措辞变了,事实仍对
SNAPSHOT = {item["q"]: ans for item, ans in zip(GOLDEN, V1)} # 上次通过的原句快照
def judge_rule(ans, item): # 规则判:必含要点全中 + 禁含词零现
return (all(k in ans for k in item["must"])
and not any(k in ans for k in item["ban"]))
def judge_snapshot(ans, item): # 快照判:与上次通过的答案逐字比对
return ans == SNAPSHOT.get(item["q"])
for name, outs in [("v1 旧版", V1), ("v2 新版(改了提示词)", V2)]:
print(f"== {name} ==")
for item, ans in zip(GOLDEN, outs):
r = "过" if judge_rule(ans, item) else "不过"
s = "同快照" if judge_snapshot(ans, item) else "偏离快照"
print(f" [{item['q']}] 规则判:{r} · 快照判:{s}")
实跑输出(已验证,python3 judges.py):
== v1 旧版 ==
[退货期限] 规则判:过 · 快照判:同快照
[运费谁出] 规则判:过 · 快照判:同快照
[开发票] 规则判:过 · 快照判:同快照
== v2 新版(改了提示词) ==
[退货期限] 规则判:不过 · 快照判:偏离快照
[运费谁出] 规则判:过 · 快照判:偏离快照
[开发票] 规则判:过 · 快照判:偏离快照
对着输出读:
- 规则判当场拦住这条回归:改提示词后,「退货期限」塌成 90 天。
- 快照判抓的是措辞变化:另外两题措辞变了、事实仍对,规则判放行、快照判报警——报警要人工(或 LLM 判卷)甄别「正常改写」与「事实漂移」。
- 一个设计内盲区:V2[2] 丢掉了「30 天内可换开」的时限,属于要点级丢失——现行题集的 must 列没收录这条,规则判按题放行是对的,补题即可兜住。
- 三级接力正是判法谱系的用法:规则拦硬伤、快照抓变化、模糊地带上 LLM 判卷与人工;LLM 判卷的评分维度 prompt 是这套骨架的第五档——把「答案对吗」拆成「是否包含 30 天期限 / 是否遗漏免责条款 / 语气是否合规」三个独立小问,比一句「打个分」可靠得多。
29 行骨架接真系统时,把 V1/V2 换成两次跑批的真实输出、GOLDEN 换成几十条业务题,再把这段判卷循环挂进 CI——每次改动的 PR 自动出一份成绩单,就是 Benchmark 自动化的最小形态。
边界与取舍
评估值不值得建,六问自检:变更有没有题集拦着?失败有没有归因账?判分能不能被机器复验?题集会不会被模型背过?指标跟业务对齐了吗?回归门是自动的还是要用户当测试员?——六问里答不上来的超过两个,先补评估再谈优化。这正是「Eval 是 Agent 核心护城河」的日常含义:模型大家都能调,知道自己每天变好还是变差的,只有少数团队。
最后的坏味道预警:如果评估只在上线前跑一次、失败案例从不回流题集、判分全靠人眼——这套评估会随时间腐烂。题集与错题本要用起来(接可观测性篇:Replay 攒下的失败案例正是考卷毛坯);而回归门之后怎么安全地送上线——灰度、回滚、版本归档,在生产化里展开。
自测
LLM-as-Judge 在什么任务上不可靠?怎么用便宜模型做靠谱 Judge?
有客观判据的任务上不可靠也没必要——直接用规则判(要点命中、结构校验),机器秒出且可复验。开放式生成任务上可用但有已知偏差:评测研究系统量化过位置偏差(换位置分数变)、冗长偏差(谁长谁分高)、自我偏好(偏爱像自己的答案)。用便宜模型做靠谱 Judge 的做法:拆评分维度(把「好不好」拆成可独立判断的小问)、换位重判(A/B 互换位置取一致)、做与验收分离(生成模型不判自己的卷),拿不准的升级人工。可靠性来自流程,不来自裁判模型的价钱。
改了 Prompt 旧任务退化——回归集怎么设计才能拦住?
三个要件:其一,回归集来自历史真实失败与已修好的旧题([可观测性](/learn/harness-observability/)篇 Replay 攒的失败案例是现成毛坯),而不是随手新编;其二,每题带机器可判的判据(必含要点 + 禁含词 + 快照),「感觉答对了」不算过;其三,改动上线前全量重跑,判定标准是净赚——新题涨且旧题不塌,塌掉的逐条归因(对照十三类失败归因找主因)后要么修改动、要么把该题记为已知回归带版本说明。两把尺子的纪律与[微调篇](/learn/fine-tuning-lora/)同源:任务分要涨、旧分不许塌。
规则判与快照判各适合什么场景?混用时的分工是什么?
规则判适合「事实要点」类验收:必含的数字、条款、步骤命中即可,措辞随意——便宜、可复验、不误伤正常改写。快照判适合「一个字都不许变」的场景:结算金额、法律条款、已定稿文案——措辞一变就报警。混用分工:规则判当第一道闸拦事实硬伤,快照判当第二道闸抓一切变化,快照的报警交给人工或 LLM 判卷甄别「正常改写」与「事实漂移」——动手段的三条样例就是这个分工的实景。
参考与延伸
- Judging the Judges: A Systematic Study of Position Bias in LLM-as-a-Judge(arXiv,AACL-IJCNLP 2025):判卷模型位置偏差的系统量化研究
- 旗舰项目:从零搭一个 RAG 问答系统:检索侧评估闭环的完整实操(题集四列、一次一变量、两锅分账)
- 下一站:生产化——灰度、回滚、成本治理与 Runbook,把评估与监控接进发布流程