跳到主要内容

评估集腐化:为什么评估分数在上升,而用户满意度在下降

· 阅读需 11 分钟
Tian Pan
Software Engineer

评估分数连续两个季度呈上升趋势。仪表盘是一片绿色,回归测试套件自三月以来从未标记过真实的失败,团队交付 prompt 更改的速度也变快了,因为评估(eval)给出了清晰的通过/失败答案。与此同时,用户反馈的质量正在下滑。NPS 下降了 4 分,支持队列里堆满了没人标记过的失败模式,产品负责人开始质疑:如果客户这么生气,为什么评估结果看起来却这么好?

评估集没有撒谎。它正在回答六个月前它被构建时要回答的问题,针对的是发布周存在的流量分布。产品已经发生了偏移。用户群体已经发生了偏移。发布时团队未预见到的长尾用例现在占了流量的三分之一。评估集仍在衡量第一周的世界,而团队正在用昨天的产品对今天的模型求平均值。

这就是评估集腐化(eval set rot)。它是现代 AI 工程中最隐蔽的失败模式之一,而且随着评估集的变大而变得更糟,因为维护它的人将“更多用例”误认为是“更好的覆盖”。

评估集是一个样本,且采样策略是隐形的

工程师在构建评估集时做的第一件事就是将其视为一个固定的对象。一个 JSON 文件文件夹、一个测试运行器、一个通过率。CI 流水线根据通过率来控制合并。当报告 bug 时,团队会添加新的用例。评估集在增长。每个人都感觉良好。

没人追踪的是这套评估集背后的隐形采样策略。一个评估用例之所以进入该集合,是因为某人在某个时刻认为它很重要。发布时的策略可能是“我们从调研访谈中预期的首要用例”。一个月后变成了“用例加上一些我们要防止回归的 bug”。六个月后变成了“任何人手动标记过的所有内容,并根据抱怨最响亮的团队进行加权”。

那不是采样策略。那是累积。这种区别很重要,因为评估分数只有相对于样本才有意义,而一个毫无原则的样本会产生一个毫无原则的分数。团队报告的是一个与实际分布没有合理关系的数字,他们已经失去了回答“如果我们的模型通过了评估,用户会更开心吗?”这个问题的能力。

一个有用的评估集应该有一个书面的、版本化的采样策略。新工程师能在五分钟内读完并理解:这个集合包含 N 个用例,从定义的时间窗口内的生产追踪中提取,按以下意图类别分层,并带有这些目标权重,遵循以下排除规则,并按以下频率刷新。如果你不能为当前的评估集写出这样的一段话,那么你就没有评估集。你只有一堆文件夹。

隐藏在综合通过率下的两种失败模式

站会上报告的数字是综合通过率。这个数字掩盖了两种需要不同修复方法的不同失败模式。

第一种是校准偏移(calibration drift)。集合中的用例在发布时是生产流量的合理替代方案,但生产流量已经发生了偏移。该集合仍然通过是因为用例本身没有改变,且模型没有在这些用例上发生回归,但该集合现在回答的是团队不再关心的问题。修复方法是根据当前的生产分布重新对集合进行采样。

第二种是简单用例累积(easy-case accumulation)。随着时间的推移,新的用例被添加进来,主要来自 bug 报告。Bug 报告往往偏向于那些足够明显、有人能写出清晰预期输出的用例。困难用例——开放式生成、多轮对话的歧义、合法的评判者也会产生分歧的用例——添加得更慢,因为它们更难标记。几个月后,简单用例的相对权重就会上升。通过率上升不是因为模型变好了,而是因为评估变简单了。修复方法是建立删除机制和按群体加权,而不是增加更多用例。

大多数团队两者都没注意到。他们看到数字呈上升趋势,就假设系统正在改进。架构上的认识是:综合通过率是两种独立动态的有损总结,一个健康的评估程序应该同时报告这两者。

影子集:检测分布偏移的并行工具

修复校准偏移的原则是并行运行两个评估集。

黄金集(gold set)是团队信任的产物。它控制发布。它是精心策划、手动标记并按季度刷新的。它的工作是回归检测:这次模型更改是否破坏了我们明确承诺保留的行为?

影子集(shadow set)在每个周期都根据最近生产流量的分层样本重新构建。它还不足以被信任到可以控制发布。它的工作是分布偏移检测:这次模型更改在看起来像用户今天实际发送的用例上,表现是否有所不同?

有趣的指标不是任何一个集合单独的通过率,而是它们之间的分歧。当黄金集和影子集一致时,黄金集仍然是生产环境的忠实代表。当它们的分歧超过阈值时,黄金集已经陈旧,需要刷新。这种分歧信号告诉团队何时该投入精力重新生成黄金集,而不是按照一个或过于激进或不够激进的固定时间表进行刷新。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates