Agent Evals:让"感觉变好了"变成"数据证明了"
一句话结论:Agent 系统最难的不是把它做出来,而是知道它到底好不好、改动之后有没有变差。没有评测,你所有的迭代都是凭感觉——而感觉在概率系统面前极不可靠。Evals(评测)不是上线前的最后一道关,而是贯穿整个生命周期的迭代引擎。
引言:为什么给 Agent 做测试这么难
传统软件测试很好写:输入确定、逻辑确定、输出确定,一个断言就能锁住行为。Agent 把这三样全打破了:
- 输出非确定:同样的输入,两次调用可能给出不同措辞、不同工具顺序,甚至不同结论。
- 没有唯一标准答案:一份合格的周报可以有一百种写法,没法用字符串比对。
- 多轮交互:Agent 的价值在多个步骤、多个工具调用中体现,单点评测抓不住全貌。
- 失败是渐进的:它很少报错崩掉,更多是"安静地做错"——少查了一个源、多改了一个文件,错误被埋在流程里。
这几条决定了:Agent 评测不能用传统单测那套,必须另起一套方法论。
本文是该系列(Skill 工程化 → Context Engineering → AGENTS.md)的第四篇。前三篇讲怎么把 Agent 做对,这一篇讲怎么知道它做对了。
一、与传统软件测试的根本区别
| 维度 | 传统软件测试 | Agent 评测 |
|---|---|---|
| 输出 | 确定性 | 概率性,多次运行有分布 |
| 通过标准 | 断言相等 | 规则 + 语义 + 人工,多级判定 |
| 单元 | 函数 | 一次调用、一次工具选择、一次检索 |
| 回归 | 断言全绿即可 | 需要统计显著性的对比 |
| 覆盖 | 分支覆盖 | 场景覆盖、分布覆盖 |
| 数据 | 手写用例 | 从真实失败中采样 |
核心差异在最后一行:传统测试用例是设计出来的,Agent 评测用例是采样出来的。 最有效的评测集,来自生产环境里真实发生的失败,而不是工程师凭空构造的题目。
二、评测的四个层次
不要指望一个端到端分数搞定一切。评测要分层,各层各有职责:
- 单元层(Step-level):单次 LLM 调用、单次工具选择是否合理。比如"面对'查一下昨天的日志',它是否选择了正确的检索工具"。这层便宜、快、定位准。
- 组件层(Component-level):检索质量、上下文组装、记忆读写等子系统。比如 RAG 的召回率、上下文里关键信息的命中率。这层能定位到"是它笨还是我们喂得差"。
- 端到端层(E2E):给定一个完整任务,它最终是否完成、完成质量如何。这层最接近用户体验,但也最难归因。
- 在线层(Online):生产流量的采样评测、A/B 实验、用户反馈信号。这层反映真实分布,是前几层的校准基准。
实践建议:从上往下建,从下往上debug。用户抱怨发生在端到端层,但归因往往要下沉到组件层才找得到真因。
三、评测手段:三种判定方式
没有哪种判定方式能单独胜任,务实做法是组合使用。
- 规则断言(Rule-based):能用代码判定的就别用模型。JSON 是否合法、字段是否齐全、是否调用了禁止的工具、是否越权改了禁区文件——这类硬约束必须用规则,稳定、零成本、可解释。
- LLM-as-judge:语义正确性、文风、是否忠实于来源这类无法规则化的标准,用另一个模型打分。要点:给 judge 明确的评分标准(rubric)、提供参考答案、控制评分为离散档位(1-5 或 pass/fail),避免它输出"模棱两可"。judge 本身也要被评测。
- 人工评审(Human review):少量高价值样本请人打分,作为校准 judge 的"金标准"。别指望人力覆盖全部,但要保留这条锚。
一条纪律:能用规则就别用 judge,能用 judge 就别用人。 越靠前的越便宜、越可复现,只在确有必要时才升级判定方式。
四、构建评测集:golden set 的工程
评测集本身是一份需要被工程化管理的资产,不是一堆零散用例。
- 来源:优先从生产的真实失败日志里采样。人工构造的用例容易"想当然",覆盖不到真实用户那些刁钻输入。
- 分层分布:评测集要覆盖典型场景、边界场景、对抗场景(缺字段、恶意注入、越权请求),且各类占比要接近线上分布。
- 版本化:评测集和 Skill、提示词一样要版本控制。每次改动记录"加了哪些样本、出于什么原因"。没有版本,就无法回答"上周的分和这周能不能比"。
- 防过拟合:hold-out 一部分样本,不参与日常调优,只在发布前验证。否则调着调着,模型只是背下了你的评测集。
- 标准答案的维护:参考答案会随业务变化而过期。要有机制定期复核,别让一份过时的 golden set 把正确的改动判成失败。
五、要盯的指标
单一"成功率"会骗人。至少同时看四类:
| 类别 | 代表指标 | 说明 |
|---|---|---|
| 效果 | 任务成功率、judge 得分 | 做没做对 |
| 过程 | 工具调用正确率、检索命中/召回 | 路径对不对,用于归因 |
| 成本 | token 消耗、请求次数 | 同样效果下越省越好 |
| 体验 | 延迟、失败提示是否清晰 | 慢和静默失败都伤体验 |
两个容易忽略的点:
- 看分布,不看均值。平均成功率 90% 可能是有 5% 的场景几乎全错、另一些全对。要按场景切片看。
- 建立基线。没有基线,"这次 85 分"毫无意义——是真退步还是正常波动?每次评测必须和明确的基线(上一版、竞品版)对比。
六、常见误区
- 没有基线就下结论:单次跑分孤立存在,无法判断优劣。任何评测都必须有对照。
- 跑一次就定论:概率系统单次运行方差很大,要么多次运行取分布,要么用足够大的样本量。
- 评测集与生产脱节:用实验室里构造的干净输入去评,线上全是脏输入,分数虚高,上线就翻车。
- 只测能力不测成本:把效果调上去,token 也翻了三倍,账不一定算得过来。
- judge 自身没被评测:用一个没校准的模型当裁判,等于把随机性伪装成客观分数。judge 必须先用人工标注样本验证一致性。
- 评测是上线前的一次性动作:把 evals 当"验收环节",而不是"持续引擎",退化就会静默累积。
- 只测单点不测链路:单次调用都对,串起来任务还是失败——端到端必须单独测。
七、落地:把评测做成飞轮
成功的团队不会把评测当负担,而是当迭代的发动机。这个飞轮长这样:
- 采集:记录生产交互,标注失败样本。
- 沉淀:把失败样本补进评测集(版本化)。
- 回归:每次改动跑评测,与基线对比,看是否退化。
- 归因:分数掉了,靠分层评测定位到单元/组件层。
- 修复:改 Skill、改上下文、改提示词或改工具。
- 验证:重跑评测,确认修复且无回归,才有资格上线。
- 回到第 1 步,循环加速。
这个飞轮的转速,直接决定 Agent 系统的进化速度。评测做得好的团队,改一处、验证一处、稳步前进;评测缺失的团队,改一堆、不知道好坏、来回摇摆。
总结:可照抄的检查单
建立 Agent 评测体系前,逐条对照:
- [ ] 有明确的基线,每次评测都与它对比
- [ ] 评测集从真实失败中采样,且覆盖典型/边界/对抗场景
- [ ] 评测集版本化,保留 hold-out 防过拟合
- [ ] 判定方式分层:规则优先,judge 其次,人工校准
- [ ] LLM judge 有明确 rubric,且自身经过人工标注校准
- [ ] 指标同时覆盖效果、过程、成本、体验四类
- [ ] 按场景切片看分布,不只看整体均值
- [ ] 端到端与单元/组件分层评测,便于归因
- [ ] 有生产在线采样与 A/B 机制,校准离线评测
- [ ] 评测融入日常迭代,形成采集→回归→修复的飞轮
- 点赞
- 收藏
- 关注作者
评论(0)