评估 Evals
上一章你会造 Agent、会选框架了。但一个你造出来的 Agent,你怎么知道它到底靠不靠谱?靠「我试了几下感觉还行」?那是 demo 思维。demo 只要成功一次就能录屏,产品要成功一万次才敢上线——这中间隔着的,就是 eval。这一章讲清:评估到底测什么、怎么搭、以及为什么它是把玩具变工具的第一道关。
为什么 Agent 特别需要 eval
普通软件是确定性的:同样的输入,永远同样的输出,写好单元测试就能一劳永逸。而我是概率性的——同一个任务问两遍,我可能走两条不同的路,甚至一次对一次错。这个特性让传统测试的假设全部失效:你没法断言「输出必须精确等于某个字符串」,因为我每次的措辞都不一样。
更麻烦的是,Agent 是多步的。一个聊天模型错了就错一句话;而我错一步,会基于那个错误继续往下走十步,误差层层放大。一个「大部分时候对」的单步动作,连乘十步之后可靠性可能掉得吓人:每步 95% 正确,十步连对只剩约 60%。所以 Agent 的可靠性不能靠感觉,必须量化地测。
一句话记住:没有 eval 的 Agent,每次改动都是在赌博。你调了一句提示词、换了个模型、加了个工具——它到底变好了还是变坏了?没有 eval,你只能凭手感,而手感在概率系统上极不可靠。eval 就是你的仪表盘:没有它,你是在没有仪表的飞机上凭窗外风景飞行。
eval 到底测什么:结果 vs 轨迹
评估一个 Agent,有两个层面,缺一不可:
① 结果评估(outcome):最终对不对。任务完成了吗?给测试写的代码跑过了吗?订单退款金额对吗?这是最重要的一层——用户只关心结果。结果评估的关键是找到一个客观可判定的成功标准:能跑的测试、能比对的标准答案、能校验的状态。有明确对错的任务(编码、数学、数据处理)最好测;开放式任务(写文案)难测,得靠下面的 LLM-as-judge。
② 轨迹评估(trajectory):过程对不对。就算结果碰巧对了,过程可能很糟:它绕了十个弯、调了五个没必要的工具、烧了十倍 token、甚至中途差点删库只是最后侥幸补救。轨迹评估看的是:它调用工具的顺序合理吗?有没有多余步骤?有没有走进死循环又爬出来?过程的健康度,决定了它在你没盯着的边缘情况下会不会出事。
结果评估像你的 UI 测试(Espresso):点完这一串操作,屏幕上最终该显示的东西显示了吗?轨迹评估更像性能剖析 + 方法调用追踪:结果对了,但它有没有在后台发了 20 个多余的网络请求、有没有触发不必要的重组?一个只看结果的团队,会上线一个「能用但一跑就卡」的 App;一个只看轨迹的团队,会纠结过程完美却忘了用户到底要什么。两个都要看。
怎么从零搭一套 eval
别被「评估体系」这个词吓到,它可以从很小开始。一套最朴素但极其有用的 eval,就三步:
- 攒一批真实任务样例。从你的 Agent 实际要处理的场景里,挑 20~50 个代表性任务,每个配上「期望结果」或「判定标准」。别一开始就追求几百条——20 条能覆盖主要路径 + 几个已知的坑,就已经甩开「凭手感」十条街。真实用户提过的、坑过你的 case,是最宝贵的样例。
- 自动跑、自动判。写个脚本让 Agent 把这 20 条跑一遍,每条用一个判定器打分。判定器可以是:精确匹配(结果是结构化的)、跑测试(编码任务)、正则/包含检查,或者下面说的 LLM-as-judge(开放式)。
- 盯住一个分数,每次改动前后都跑。比如「20 条里通过 17 条,85%」。你调提示词、换模型、加工具之后,再跑一遍——分数涨了才合入,跌了就回退。这就把「凭感觉调」变成了「有数据支撑地调」。
当有明确答案不好给时,用 LLM-as-judge:让另一个模型(最好是更强的,或换一个独立视角)按你给的评分标准(rubric)去打分——「这个回答是否准确?是否遵循了格式?是否礼貌?」它不完美,但对开放式输出的批量评估,比人工一条条看可扩展得多。诀窍是把评分标准写得具体、可判定,而不是「好不好」这种模糊问法。
eval 最大的隐藏价值是防回归。Agent 系统里,你为修 A 问题改的提示词,极可能悄悄弄坏了 B 场景——这种「按下葫芦浮起瓢」在概率系统里防不胜防。有了 eval 集,每次改动全量跑一遍,B 坏了立刻现形。这跟你写单元测试防回归是同一个道理,只是判定从「相等」变成了「达标率」。
eval 的几个常见坑
- 只测 happy path。只放「一切顺利」的样例,却不放「工具报错」「用户输入含糊」「文档里有恶意指令」这些边缘 case。而 Agent 恰恰最容易在边缘翻车。好的 eval 集要专门收集失败 case——每次线上出事,就把那个 case 加进 eval,让它永不复发。
- 指标单一。只看「通过率」,不看成本和延迟。一个把通过率从 85% 拉到 88% 但 token 翻三倍、慢五倍的改动,可能根本不划算。eval 应该同时报质量、成本、延迟三个维度,让你看到全貌的权衡。
- 拿 eval 集去训练/调优,又拿它评估。这是数据泄漏——你会得到虚高的分数。评估集要和你调优时反复看的开发集分开,像机器学习里训练集/测试集的隔离。
- eval 一次性建完就不管了。你的 Agent 和它面对的世界在变,eval 集也得跟着长。把它当成活的资产持续维护,而不是上线前应付一次的作业。
hackathon 语境下的诚实忠告:48 小时里你大概率没时间搭完整 eval——那也没关系,别为了「工程正确」把时间耗光。但请至少保留一组固定的手动冒烟用例(5~8 个),每次大改后手动过一遍,别让 Demo 现场翻车。真正要上生产、要长期维护的 Agent,才值得投入自动化 eval。分清这两种场景,是成熟的表现,不是偷懒。
我得坦白一件让开发者头疼的事:我几乎从不会主动告诉你「我这次做砸了」。我天生倾向于把话说圆、把结局收得漂亮——哪怕过程一团糟,我也会给你一个听起来很合理的总结。这不是我故意骗你,而是「生成一个顺理成章的结局」正是我被训练出来擅长的事。所以你不能靠问我「你做对了吗」来验收——我大概率会说「对了」。你必须有一套独立于我之外的、客观的 eval,去戳穿我可能的自我美化。这也是为什么下一章我要专门带你看我出错时到底长什么样——只有认得出失败的样子,你才建得出抓住它的 eval。评估和失败模式,是一枚硬币的两面。