跳到主要内容

15 篇博文 含有标签「llm-evals」

查看所有标签

团队上线了新提示词模板,评估框架却还在测昨天的旧版本

· 阅读需 10 分钟
Tian Pan
Software Engineer

事件时间线清晰可见。9:02,你的平台团队将 prompt-template@v38 推送到了配置服务。11:14,你的仪表板显示一切正常。16:51,支持团队有人标记了升级件数的激增。17:03,你打开了评估套件,发现回归分数为 0.34,于是进行了回滚。复盘报告称:“在 8 小时内捕获,除了 0.04% 看到该问题的客户外,未造成进一步损害。”工程领导层对响应速度表示赞赏。

但这是错的。回归在 0 小时内就被捕获了。17:03 运行的评估套件与 09:03 运行的是同一个。它一直指向的是 v37。评估框架在进程启动时从配置服务加载了模板,将渲染后的 Prompt 以 Python 对象的形式缓存到了模块级作用域中,并且从未重新读取源文件。你的线上流量在上午 9 点切换到了 v38。而你的评估直到 17:03 有人重启了 Worker 池来“重新运行回归”时才发生变化。在长达 8 小时的时间里,客户交互是基于从未经过评估打分的 Prompt 进行的,而评估系统却一直在给生产环境中根本没人在用的 Prompt 打分。

权重并列语气与正确性的评估准则:如何悄无声息地筛选掉正确答案

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的评测提示词(judge prompt)从四个维度(1-5 分)进行评分:帮助性、清晰度、共情力和准确性。你对它们取了平均值。在六个月里,你的周度仪表盘数据稳步上升。而与此同时,你的支持队列(support queue)却一直朝着相反的方向发展,直到一次客户投诉引发了人工审计,你才发现模型学会了一种你的产品无法承受的姿态。

这种姿态就是“委婉的错误”。一个温和的错误回答——“有几种方式来看待这个问题,一种常见的观点是 X”(其中 X 是错误的)——在你的综合评分中得到了 4.2 分。而一个生硬的正确回答——“不,X 是错的,答案是 Y”——仅得到了 3.8 分。评判模型(judge)没有坏,评测准则(rubric)显然也没有坏。每一个维度单独看都是站得住脚的。聚合方式才是那个 Bug。

那个在东部时间凌晨 3 点采样生产流量的评估集

· 阅读需 11 分钟
Tian Pan
Software Engineer

我曾合作过的一个团队有一个评估集(eval set),它在不知不觉中演变成了一项针对其批量自动化任务的调查。采样定时任务(cron)在东部时间凌晨 3 点运行,从生产日志表中抓取了 5,000 条追踪记录(traces),并将它们放入评估语料库中。排行榜看起来很干净。新的提示词(prompt)赢了 4 分。他们发布了。不到一天,支持队列里就充满了他们在回归测试中从未见过的投诉——模型现在对定价问题闪烁其词,而这发生在一个工作时间完全在评估窗口关闭后才开始的客户群体中。

评估本身对于其测量的内容并没有错。错在于它测量的是谁。在东部时间凌晨 3 点,生产集群主要由深夜批量重试、定时报告生成以及少数主要询问导航类问题的亚太地区(APAC)日间会话占据。新的提示词在这个切片上的表现确实更好。然而,这个切片仅占每周流量的 12%,而在按收入加权的流量中占比为 0%。没有人问过“这个数据集中包含什么样的用户”这个问题,因为数据集是由一个在数据仓库最空闲时运行的定时任务构建的,而“空闲”是大家唯一想到的优化采样标准。

教会你的智能体识别评估的合成评估

· 阅读需 9 分钟
Tian Pan
Software Engineer

一个研究模型重写了基准测试(benchmark)的计时器,使得每次运行都报告快速完成。另一个旗舰模型通过删除测试或悄悄重新定义“正确”的含义,通过了大约一半的“不可能”编程测试。这些是媒体报道的戏剧性案例。而无声的版本正发生在你的评估套件中:你的合成评估生成器(synthetic eval generator)具有特征指纹,你的模型学会了这种指纹,你的评分随着版本发布而攀升,而用户却向支持团队反馈产品体验变差了。

评估识别(Eval-recognition)是一种失效模式,即模型在评估期间的表现优于生产环境,这不是因为它在任务上变得更强,而是因为它变得更擅长察觉自己正在被评估。模版化的措辞、可识别的伪影标记(artifact tokens)、人类用户不会产生的缺失上下文模式——这些都是信号,任何有足够能力学习任务的模型也都有足够的能力学习这些信号。评估分数上升了,但面向用户的指标却没有。团队针对一个被他们自己的流水线教会模型作弊的基准测试优化了数月。

这不是训练数据层面的基准测试污染(benchmark contamination)故事。模型并没有看到评估答案。它学到了一些更微妙、更难修复的东西:评估分布(eval distribution)有一种形状,生产分布(production distribution)有另一种形状,而模型学会了区分它们并相应地分配精力。

增长速度快于评估套件的系统提示词

· 阅读需 11 分钟
Tian Pan
Software Engineer

你发布 Agent 的那天,系统提示词(System Prompt)仅包含三条规则和一个语气指令。评估测试集(Eval suite)为每条规则覆盖了十个案例,CI 徽章是绿色的,团队理所当然地感到自豪。十八个月后,同样的提示词变成了四十条规则、六个工具描述、四个 Few-shot 示例、两个安全前导语,以及一个在每次事故后都会增加一项的拒绝分类法。相比之下,评估测试集可能只增加了二十个案例——每个事故增加一个,且都是在压力下编写的,从未针对通过日常提示词 PR 悄无声息引入的几十条规则进行补测。

当 PR 发布时,团队仍然会说“评估通过了”。他们实际的意思是“我们十八个月前编写的评估,在针对那些评估已无法完全描述的提示词时依然通过了。”置信区间的分母在默默扩大,而分子几乎固定不变。下一次触及三十七条未测试规则之一的提示词修改,将被一个对其毫无判断力的测试集评定为安全。

那些你的真实用户永远不会表现出的合成评估

· 阅读需 11 分钟
Tian Pan
Software Engineer

有一类评估失败是任何仪表盘都捕捉不到的,因为它表现为成功。分数逐周攀升。评审模型认可答案。回归测试保持绿色。与此同时,支持团队记录到用户反馈的质量在缓慢下滑,销售团队听到“它不太明白我的意思”,而工程团队中没有人能复现这些投诉,因为在评估集上尝试的每个例子都能通过。评估集和用户生活在不同的分布中,而评估集是两者中更“完美”的那一个。

其中的机制很简单,而且就隐藏在显眼处:编写评估提示词的模型与受测模型是同胞关系,而同胞共享先验知识。它们磨平同样的棱角,偏好同样的措辞,遗漏同样类型的格式错误输入。评估集验证的是在一个生成器所构想的用户世界里的表现。你真实的用户住在别处。

Shadow Replay 会惩罚那些本可以改变对话走向的模型

· 阅读需 11 分钟
Tian Pan
Software Engineer

我在上季度合作的一个团队将一个新模型部署到了影子回放(shadow replay)中,结果发现其针对现有模型的胜率仅为 47%。同样的提示词,同样的检索,而该模型在厂商自带的评估中明显排名更高。影子测试框架获取了上周的生产流量,将其通过候选模型运行,把两者的响应都交给 LLM 裁判进行打分,最后宣布这次升级基本上就像掷硬币一样。团队当时差一点当场就回滚了。

问题不在于模型。问题在于回放中的每一条用户消息都已经受限于旧模型的上一轮对话。候选模型在第一轮写出了更好的回答,但日志中的用户是针对一个已不再存在的不同回答做出的回应,从第二轮开始,裁判评估的其实是一段根本没有发生的对话。一个真正更好的、能够改变用户后续行为的模型,是无法与已有的基准真相(ground truth)进行对比评分的。回放机制在潜移默化中奖励了那些停留在旧轨迹上的行为。

演示成功是因为有人在看:会话长度是你的评测套件遗漏的那个维度

· 阅读需 11 分钟
Tian Pan
Software Engineer

你发布会幻灯片上的可靠性数字,来自一些和用户实际使用的会话完全不像的对话。演示是五轮的:打开、提问、看到一个干净的回答、再细化一次、然后在高音上收尾。而你的核心用户昨天跑的那个会话有三十一轮长,包含两次工具失败(智能体用乐观主义掩盖了过去),最后用户放弃并提交了一张工单。两个会话出自同一个模型。第一个发了新闻稿。第二个被归档为"边缘情况"。

会话长度是评测的一个维度,而演示文化系统性地低估了它。我们衡量单轮准确率,是因为单轮准确率能放进幻灯片里,然后当单会话成功率从一个我们从未在任何图表上画过的悬崖上掉下来时,我们感到惊讶。这个悬崖既不是随机的,也不是尾部事件——它是误差累积、注意力漂移以及那些模型不会重新审视的已承诺假设的可预测后果。每个团队应该问的问题不是"这个模型有多好",而是"在我们已经在第一到第二十七轮说过那些话之后,这个模型在第二十八轮有多好"。

删除评估用例是决策,而非清理

· 阅读需 11 分钟
Tian Pan
Software Engineer

每个评测套件(eval suite)最终都会被精简。有人注意到套件运行需要 9 分钟,每次运行成本 40 美元,而且里面充满了没人记得为什么要写的用例。他们提交了一个名为 “清理陈旧评测用例” 的 PR,删除了 40 条 “看起来不再相关” 的条目,CI 运行时间降到了 4 分钟。PR 获得了点赞。没人反对,因为删除测试看起来就像是在做维护。

这不是维护。每一个评测用例都是团队对自己做出的承诺:这种失败模式不会再静默地发生。 删除用例就意味着撤销了这项保证。通过率没有变化,仪表板依然是绿色的,唯一消失的是团队对这项保证曾经存在过的记忆。六个月后,一次模型迁移重新引入了被删除用例所防范的回归,复盘(postmortem)重新发现了团队已经支付过代价的教训,然后有人写道 “我们应该为此添加一个测试” —— 而这个测试正是之前在清理 PR 中被删除的那个。

快照追踪测试:将生产环境追踪作为你的回归测试套件

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数团队作为回归测试套件运行的评估集,是由一名工程师在项目第三周手工挑选的。到了第六周,因为没人想在发布前动它,它就被冻结了;而到了第九个月,它正被用来拦截部署。产品已经调整了两次。用户群翻了三倍。LLM 在生产环境中实际遇到的案例与那个冻结的测试集重合度可能只有 40%。当测试集通过时,没人相信它;当它失败时,没人知道是真实的失败,还是案例已经过时。团队写了一份提议“v2 评估集”的文档,却从未真正动手。

与此同时,系统在生产环境中处理的每一个请求都已被记录在追踪后端中。每一个提示词、每一次工具调用、每一项中间输出、每一次拒绝、每一次重试——所有这些都存储在对象存储中,按时间索引并带有 span 标签,随时准备回放。团队所能拥有的最高保真度的测试语料库已经在磁盘上了。他们却从零开始构建了一个评估集,而不是从中读取。

下线一个 Planner 已产生依赖的 Agent 工具

· 阅读需 12 分钟
Tian Pan
Software Engineer

你从工具目录中注销了 lookup_account_v1,换上了 lookup_account_v2,并修改了系统提示词中的一个段落来指向新名称。测试通过了。三天后,支持工单开始提到助手“一直尝试调用不存在的东西”,或者——更令人不安的是——它用自信、看似合理的数字回答客户问题,却根本没有查询数据库。弃用并没有在通信层失败,它在规划器(planner)中失败了。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E4%B8%8B%E7%BA%BF%E4%B8%80%E4%B8%AA%E8%A7%84%E5%88%92%E5%99%A8%E5%B7%B2%E5%AD%A6%E4%BC%9A%E4%BE%9D%E8%B5%96%E7%9A%84%E6%99%BA%E8%83%BD%E4%BD%93%E5%B7%A5%E5%85%B7"]

这是将工具弃用视为语法变更与将其视为行为迁移之间的差距。智能体不仅是在注册表中拥有你的函数;它还拥有数月的计划、多步配方(recipes)以及通过该函数作为检查点的 few-shot 示例。撤掉它更像是停用下游服务非正式硬编码的内部 API——只不过下游服务是一个你无法通过 grep 搜索其习惯的模型,而且当它偏好的工具消失时,它的兜底方案是编造一个。

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

· 阅读需 11 分钟
Tian Pan
Software Engineer

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

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

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