为什么评估智能体很难——以及你的测试套件为何在骗你。
评估单次模型调用是个基本算解决的问题:固定提示词、采样一次、给字符串打分。智能体打破了让这件事变简单的每一条假设。输出是非确定的,任务是多步的因而误差会复合,很少有唯一的标准答案,成功是路径依赖的,每一次评估运行都要花真金白银和好几分钟,而你上个季度还信任的数据集已经悄悄腐烂了。本文是关于智能体评估为何困难的诚实清单,好让接下来的五篇文章能逐一刻意地攻克每个难点。
非确定性使单次运行失去信息量。
一个 temperature > 0 的模型每次运行都采样出不同的轨迹;即便在 temperature = 0 下,批处理、GPU 的非结合性以及厂商侧的路由也会产生运行间漂移。对一次性问答提示词,这只是稳定均值附近的噪声。对智能体则是结构性的:第 3 步采样出的某一个词,会把智能体送向不同的工具、进入不同的观察、走上任务的不同分支。方差不是答案周围的一小条带——而是经由不同路径抵达的不同答案。
后果残酷且常被忽视:单次运行上的单个 pass@1 数字不是测量,而是你尚未刻画的某个分布的一个样本。一个"通过了评估"的智能体可能只有 40% 的时候通过。你必须对每个任务运行 k 次并报告一个分布——pass^k(k 次全过,可靠性数字)通常比 pass@k(至少过一次,能力数字)更诚实。
如果你的 CI 对每个评估任务只运行一次,那个绿勾的置信区间宽到足以让一次回归直接开车穿过去。你归咎于"模型今天有点怪"的那次抖动,正是测量本身,而非该被压制的噪声。
误差跨步骤呈乘性复合。
这道算术毫不留情。如果智能体每一步独立地有 95% 可靠,一个 10 步任务的成功率是 0.95^10 ≈ 0.60;20 步任务是 0.36。对分类器堪称优秀的单步精度,对一条工作流就是抛硬币。这就是为什么智能体演示在 5 步时看着像魔法、到 30 步就崩塌,也是为什么"模型在子任务上变强了"却可能让端到端成功率原地踏步甚至更差。
# the tyranny of the exponent: per-step p -> task success for p in (0.99, 0.95, 0.90): for n in (5, 10, 20): print(p, n, round(p ** n, 2)) # 0.99 20 -> 0.82 0.95 20 -> 0.36 0.90 20 -> 0.12
这对评估设计有两点含义。其一,聚合的任务成功率数字告诉你系统坏了,却不告诉你坏在哪里——你需要逐步的埋点(这是贯穿到追踪那篇文章的主线)。其二,误差并不独立:一个错误步骤会毒化它之后每一步的上下文,所以真实曲线衰减得比朴素乘积更快。恢复行为——智能体能否察觉并自我纠正——是一等公民的待测对象,而非事后补的东西。
很少存在唯一的标准答案。
对于"法国的首都是哪里",有一个字符串可供匹配。对于"重构这个模块以消除循环导入"或"帮我订一张合理的航班",存在的是一集合可接受的结果,可能无穷多,且没有干净的归属判定。精确匹配打分不可能;任务由一个对终态的谓词来定义("测试通过且不再有导入环"),而非由一份答案表。
- 开放式生成——许多正确的措辞;字符串匹配毫无希望,嵌入相似度是个弱代理,会奖励流畅的错误。
- 约束满足——规格是"以下这些性质全部成立",可由一个可执行检查器评判;这是最适合用来构建评估的任务类型。
- 真正主观——"这份摘要好不好"。不存在检查器;这正是 LLM 评判者登场之处,连同其专文中的全部偏差告诫。
设计上的动作是把任务推向第二类:偏好具有可验证终态的任务,因为一个你能跑起来的检查器,抵得上十个你得去校准的评判者。
成功是路径依赖的,所以同一个答案可对可错。
两个智能体返回了完全相同的最终答案。一个读了文档、正确调用了 API 并验证了结果。另一个靠猜、撞了大运,下一个输入上就会失败。单凭结果无法区分能力与一次幸运的抛硬币——而只检查终态的评估会把它们打成同分,并把那个走运的发布出去。
更糟的是,即便结果正确,路径也可能不可接受:智能体删掉了一张生产表,然后从备份里恢复了它,然后报告成功。终态没问题;轨迹却是该被开除的级别。这正是结果 vs 轨迹那篇文章的全部动机所在——对智能体而言,如何做到常常是是否做到的一部分。
评估很昂贵,而且数据集会腐烂。
每一次评估运行都是完整的智能体执行:大量模型调用、真实的工具延迟,有时还有真实的 API 花费与副作用。一个 500 任务的套件运行 k=5 次,就是 2500 条以分钟计的轨迹——你不可能条件反射地在每次提交上都跑它。评估成本是你要据以设计的预算:每次推送跑一个快速小关卡,每晚跑完整套件,每周跑昂贵的评判者打分切片。
- 污染。公开基准会泄漏进预训练;一个前沿模型可能已经见过 SWE-bench 的解。昨天的硬基准是今天被背下来的答案表。留出的、私有的、新撰写的任务是唯一持久的信号。
- 评估集腐烂。你的任务引用了已变更的 API、已重设计的网站、已关闭的工单。一次通过的评估可能意味着系统能用,也可能意味着这个任务已不再测试任何东西。陈旧任务静默地腐烂成虚假的绿色。
- 对套件过拟合。一旦评估成了 CI 关卡,每一次改动都隐式地被朝它调优。套件不再测量能力,而开始测量对它自身的合规度。轮换团队从未见过的留出任务。
把评估集当作有保质期的代码。钉住工具/API 版本,对网页目标做快照,给每个任务打日期戳,并排期一轮重新验证——一个尚未被确认仍在测试其所声称之物的任务,是正在以虚假信心累积的技术债。
诚实的取舍。
你无法让智能体评估既便宜、又确定、又决定性——挑你要伪造哪两个,并大声说出来。成熟的姿态不是"我们有个评估说 87%";而是"我们在一个版本化、去污染、刻意轮换的集合上采样一个被刻画过的分布,并报告方差与路径,而非只报一个头条数字"。一个产出单个你完全信任的干净数字的智能体评估并不严谨——它只是把这六个问题全藏在了一个绿勾后面。