Agent 怎么评测
给检索问答做评测集,和给 Agent 做评测集,是两件不同的事。前者只有一次输入一次输出,判"答案对不对"就够了;后者是一串步骤,最终答案对了完全可能是一条错误的路径碰巧走通的——这次对,下次就不一定。
所以 Agent 评测必须多一个维度:不只判结果,还要判过程。
1. 为什么不能照搬问答评测
检索问答的评测集是"问题 + 期望答案",判一次生成。Agent 的输出是一串:计划、工具调用、参数、观察结果、再计划……最终答案只是这条链的末端。
这带来两个具体差别:
同一个结果可以由多条路径得到。 其中一条干净,另一条绕了八步还调错了两次工具只是碰巧收敛。只看最终结果,两条都得满分。
同一条路径可以产生不同结果。 Agent 是双重不确定的:模型本身有采样随机性,而多步会把小偏差放大。同一个任务跑五次,可能三次成功两次失败。
所以 Agent 评测的最小单位不是"一次运行",是一个任务跑 k 次的分布。
2. 结果侧:任务成功率,但要跑 k 次
任务成功率是头条指标:符合终态判据的任务占全部任务的比例。
关键在于判据要写死。"回答得不错"不是判据,"订单状态被改成已退款且生成了一条退款记录"才是。判据写得含糊,整个成功率就没有意义。
然后必须重复。单次 pass/fail 噪声太大,正确做法是每个任务跑 k 次,报告在 k 次里全部成功的比例(有的基准把它记作 pass^k)。这个数字通常明显低于单次成功率——一次就过的任务,五次里可能只成三次。
这个差距本身就是结论:它说明 Agent 在这个任务上不稳定。不要把它平均掉,也不要挑一次好结果汇报。
3. 过程侧:轨迹评测
轨迹是"完成这个任务所做的全部动作的有序记录":每一步的推理、调用了哪个工具、传了什么参数、拿到什么结果。
工程师实际用的子指标:
- 工具选择准确性:这一步该调的工具调对了没有
- 参数准确性:参数是否合法、是否符合 schema、值对不对
- 步骤效率:两步能做完的事是不是走了八步
- 错误恢复:工具报错之后有没有重试或换路,还是直接放弃或硬编
其中前两项是确定性的——工具名对不对、参数在不在 schema 里、必填项有没有漏,都能用代码直接断言,不需要任何模型参与。这一类检查便宜、可重复、不会漂移,应当先建。
first_call = trajectory.tool_calls[0]
assert first_call.name == "search_order", "第一步应该先查订单"
assert first_call.arguments.get("order_id"), "订单号是必填项,不能为空"
assert len(trajectory.tool_calls) <= 6, "这个任务超过 6 步说明在绕路"
不要拿"期望轨迹"做严格比对。 完全按顺序匹配会惩罚所有同样正确但顺序不同的走法,而多数任务本来就不止一条正确路径。更合适的问法是"该调的工具调了没有,不该调的调了没有",而不是"顺序一不一样"。只有确实存在唯一标准流程的任务,才用严格匹配。
需要判断"这条路走得合不合理"这类主观部分时,才上 LLM 裁判:给它一份结构化评分细则,低温运行,并且固定裁判模型版本,否则分数会漂。
4. 裁判本身有偏差,要先审计
LLM 裁判是被反复验证过的有用工具,但它有几种已知偏差:
- 位置偏差:偏好排在前面的候选
- 冗长偏差:偏好更长的答案,哪怕内容没有更好
- 自我偏好:偏好自己家族模型生成的输出
有的研究报告过裁判判错率超过一半的情况。所以:先拿一批人工标注对比裁判的打分,一致率达标了再把它接入门禁。这一步不能省,否则你是在用一个未校准的尺子做回归判断。
5. 成本与延迟要挂在同一条 trace 上
Agent 的成本不是"一次调用多少钱",是"一个任务跑完花了多少"。步数、总 token(含推理 token)、墙钟时间、重复调用次数,这些必须和成功与否记录在同一条 trace 上,否则你无法回答"为了把成功率从 60% 提到 70%,每个任务多花了多少钱"。
一个典型的回归信号是:步数或成本上升,而成功率没变。这说明某次改动让 Agent 变啰嗦了,但没变聪明——同样的钱买到同样的结果,是纯粹的损失。
6. 失败分类:把"成功率 68%"变成"该修什么"
成功率告诉你有多少失败了,失败分类告诉你是怎么失败的。做个简单的分类:
工具选错 → 改工具描述、收窄工具集(见《工具有多少才合适》)
参数填错 → 改参数 schema、加枚举约束
提前放弃 → 检查步数上限与错误提示是否太早触发
跑飞了 → 加循环检测与硬上限(见《Agentic 的十类风险》)
工具本身报错 → 是后端问题,不是 Agent 问题
最后一类尤其要分出来
分类之后,"把 Agent 做得更好"这个含糊目标会变成"参数填错占 40%,先把 schema 收紧",这就是可以排期的工作。
7. 门禁怎么设
离线评测要能在 CI 里跑,并且失败时让流水线变红。两条闸:
- 绝对阈值:成功率低于某个值直接拒绝
- 相对基线:不比上一次发布的版本差
只设第一条,会放过"悄悄掉了五个点但还在阈值之上"的回归;只设第二条,会在基线本身很差时一路放行。两条都要。
还有一条硬要求:评测必须对 mock 或沙箱工具运行。让 Agent 在评测里真的去下单、真的发邮件,是最快把自己搞挂的方式。
数据集方面,几十个精心挑选的任务胜过一千个随机任务,而且应该从真实日志里捞——包括那些曾经失败的例子。《评测集怎么变成门禁》里有更完整的建集流程,思路可以直接搬过来。
8. 在线侧:把线上失败固化成回归用例
离线评测集再全,也覆盖不了真实用户的提问方式。所以还要有一条回路:
线上 trace 抽样 → 人工或规则标出失败 → 把失败样本加进离线评测集 → 变成永久的回归用例。
这条回路的价值在于评测集会自动长成你真实流量的形状,而不是长成设计者想象的形状。可观测那一侧怎么埋点见《给大模型链路装仪表》。
9. 三个常见误判
"最终答案对就行"。 这是把回归测试做成了冒烟测试。蒙对的坏路径在下次改动后几乎必然暴露,而那时你不知道是改动引起的还是随机的。
"跑一次通过了就发布"。 单次通过说的是"存在一条成功路径",不是"大概率成功"。要的是分布。
"用裁判打总分就够了"。 总分掩盖了结果与过程之间的张力:一个成功率很高但每单烧掉十倍成本的 Agent,总分可能很好看,但它是亏的。分项看,别合成一个数字。
Agent 评测的落点就一句话:拒绝被一个正确的最终答案说服。答案是最容易检查的、也是最没有信息量的部分。能不能上线,取决于它走的是哪条路、这条路稳不稳、以及这条路要花多少钱。