跳到主要内容

那个没人同意却成了规范的评估套件

· 阅读需 9 分钟
Tian Pan
Software Engineer

打开任何成熟的智能体(agent)代码库,问一个简单的问题:需求文档在哪里?不是融资演示文稿,不是发布文档,也不是那个上次更新还在第三季度的 Notion 页面。那份具体且明确地规定了这个智能体应该做什么的产出物在哪里?

对于大多数团队来说,诚实的回答是:评测套件(eval suite)。那里有一个测试用例文件夹——输入与预期输出成对出现,还有评分标准、评判提示词——以及一个显示通过或失败的 CI 门禁。那个文件夹是唯一一个将“正确”定义得足够精确以供执行的地方。其他一切都是散文,而散文会随时间发生偏移。

这本身并不坏。一个可执行的规范比没人读的 PRD 更诚实。问题在于,几乎没有人将评测套件视为规范。它是由一名工程师在截止日期前拼凑出来的,只是为了让发布门禁显示为绿色。它编码了一百个从未被记录、从未被审查、也从未被达成共识的判断。而模型现在正针对它进行精确优化。

谁编写评测,谁就在编写 PRD

在传统软件中,需求文档和测试套件是具有不同作者的不同产出物。产品部门编写规范。工程团队编写检查规范的测试。当他们意见不一时,这种分歧是可见的——测试与需求相抵触,必须有人来调解。

智能体将这两个产出物合二为一。没有哪份需求文档能在进入生产环境后幸存,因为“智能体应该是乐于助人且准确的”不是一个规范——它是一种感觉。唯一让“准确”变得具体的地方是评测集,在那里,某个工程师决定了对 这个 提示词的 这个 响应是正确的,而 那个 则不是。这些决定中的每一个都是产品决策。编写评测的人正在编写 PRD,无论他们是否主动承揽了这份工作。

考虑一个支持智能体。一个评测案例问:“我可以退款吗?”工程师编写的预期输出说,智能体应该解释 30 天政策并提议开始退货流程。这一个测试用例悄无声息地决定了几件事。它决定了智能体引用政策而不是转交给人工。它决定了智能体是主动的——它提供下一步操作而不是等待被询问。它决定了语气是信息性的而不是抱歉的。这些都没有出现在规范中。它们存在于编写测试的人脑海中,时间是下午 6 点,当时他正试图让通过率超过 90%。

将此乘以三百个测试用例,你就得到了一份详细的产品规范。只是这份规范从未被产品部门审查过,从未被法律部门看过,也从未与营销网站的承诺进行过比对。正如一份被广泛分享的从业者指南所言:标注是意见悄悄变成基准真相(ground truth)的地方——而基准真相是评测唯一能赖以生存的东西。

绿色的运行结果是对作者假设的陈述

危险之处在于通过评测运行时的 感觉。它感觉产品工作正常。它是绿色的,它在 CI 中,它守住了发布关口。“所有测试通过”的情绪权重,是从那个测试用于检查独立编写的规范的世界延续过来的。

但智能体评测并非如此。绿色的运行结果只是表明模型的行为符合编写评测集的人的假设。如果那个人误解了退款政策,评测就会编码这种误解,模型会被训练和调整以满足它,而绿色的对勾则会充满信心地认证错误的行为。套件无法捕获它共有的错误。

这在某种特定意义上比没有评测更糟糕:它制造了虚假的确定性。一个没有评测的团队知道自己在盲飞,并保持警惕。一个拥有全面绿色套件的团队则不再紧张。该套件变成了一个无人审计的权威。离线基准测试根据固定的提示词、固定的标签和固定的正确性概念来衡量性能——而生产环境违反了这三者。标签的好坏完全取决于工程师编写它时花费的那个下午。

还有一种更隐蔽的失败。因为模型是针对评测集进行优化的——通过提示词迭代、微调或奖励信号——它学习了评测作者的盲点并将其视为特征。无论作者忘记测试什么,模型都可以犯错,而且它确实会犯错,因为没有任何力量推回。评测集不仅仅在衡量产品。它在塑造产品,将其塑造成一个工程师关注点的精确形态。

评测衡量的标准与承诺之间的偏移

三份文档本应表达同样的意思:评测套件检查的内容、产品团队的意图,以及告诉用户的内容。在实践中,它们分道扬镳,而评测套件是唯一带牙齿(有约束力)的那一个。

营销页面说智能体“端到端处理你的调度”。评测套件测试了 11 个调度场景,其中没有一个涉及冲突时区,因为编写它们的工程师没考虑到——或者考虑到了,但想不出一个清晰的预期输出,所以跳过了。该产品现在在操作层面被定义为“调度减去困难部分”。没有人做出这个决定。它是由于哪些测试用例易于编写而产生的涌现属性。

随着时间的推移,两种力量扩大了这种差距。第一种是便利性:具有清晰、可检查答案的案例进入套件,而模糊的案例——恰恰是产品赚大钱或引起诉讼的那些——因为难以评分而被排除在外。第二种是陈旧性。政策变了,入驻流程变了,法规变了,散文文档更新了,而评测套件却没有更新,因为更新评测既不光鲜又没有负责人。智能体继续通过测试。它现在是针对一个不再存在的世界进行认证。

结果是一个智能体,其真实行为受控于一个无人将其与意图进行比对的产出物。评测套件默认赢得了每一场争论,因为它被接入了 CI。它赢了,并不是因为它正确。

将评估集视为 API Schema

解决方法不在于增加更多的评估。而在于将评估集视为它的本质——一个契约——并给予它契约应有的审查严谨性。一个 API Schema 不会被一个人悄无声息地合并一次提交而改变。定义你的智能体用途的产物也不应该如此。

几个具体的行动:

  • 将评估的变更作为产品决策进行审查。 增加、删除或重新标注测试用例的差异是对规范的更改。它应该由负责该产品领域的人员审查,而不仅仅是由懂 TypeScript 的人随手批准。审查的问题是“我们是否同意这是正确的?”——而不是“这能运行吗?”
  • 要求对评估准则(Rubric)而非运行程序(Runner)进行跨职能签字。 对于高风险类别——退款、医疗建议、财务建议,以及任何涉及拒绝或升级处理的内容——产品部门,以及在必要时的法律或合规部门,应该对“正确”的定义签字确认。他们不需要阅读测试脚本代码。他们需要阅读预期的输出。
  • 为评估集设定版本并关联日期。 评估用例的编写时间非常重要。针对去年退款政策编写的用例是陈旧的快照,且应该被明确标识出来。像对待带有变更日志的 Schema 一样对待评估套件,这样“这个版本的智能体认为什么是正确的?”这个问题才会有答案。
  • 追踪针对意图的覆盖率,而非针对自身的覆盖率。 将评估类别映射回产品页面上的承诺和政策文档中的义务。那些已承诺但未测试的缺口才是你真正的风险登记册。在你碰巧编写的用例上获得 98% 的通过率,无法说明任何关于你避开的那些用例的情况。
  • 将“谁审查了评估?”作为一个发布门禁问题。 目前,门禁问题是“评估通过了吗?”。增加第二个问题:“自上次发布以来,是否有拥有产品决策权的人审查了评估变更?”如果答案是否定的,那么那个绿色的勾选标记就是未经签字的。

这一切都不需要新工具。它需要的是承认评估套件就是规范,并将其纳入与其他定义产品的任何事物相同的审批路径中。

本周要问的一个低调问题

下次智能体发布通过时,找到评估套件并对其运行 git log。看看在过去六个月里谁动过它。如果只有一两个工程师,而没有出现产品或合规部门的名字,那么你就找到了你真正的规范——以及实际编写它的人员名单。

这并不是一场灾难。由工程师编写的可执行规范仍然优于没人执行的 PRD。但这是一份在没有对产品负责的人参与下编写的规范,其中编码了他们从未见过的假设,认证了他们从未批准的行为。评估套件终究会成为规范。你唯一的选择是,它是否是一份经过相关人员同意的规范。

References:Let's stay in touch and Follow me for more thoughts and updates