跳到主要内容

143 篇博文 含有标签「evals」

查看所有标签

引用索引失效:当你的分块器开始添加行号前缀时,偏移了一位

· 阅读需 12 分钟
Tian Pan
Software Engineer

分块器开始在每个块前添加 [line N]。Eval 变绿了(通过了)。从那天起,模型生成的每一条引用都指向了实际证据前的一个段落,这种情况出现在该产品所服务的受监管行业的每一份文档中。团队并不是通过评估发现这个问题的,而是通过一位审计人员发现的。审计人员查看了引用的句子,阅读后指出,该句子与其本应支持的断言完全矛盾。

这种回归错误(regression)能躲过代码审查、对三个示例文档的手动 QA 测试以及功能开关(feature-flag)的逐步推送。孤立地看,这些检查都没有错。它们都在问同一个问题——在预期的地方是否出现了引用——但没有一个检查在问审计人员问的问题,即:引用是否指向了断言来源的那个句子。这两个问题之间的差距,正是那个“差一错误”(off-by-one)长期潜伏的地方。

这种失效模式之所以值得专门写篇文章,不在于 Bug 本身。差一错误是陈年旧事了。有趣的地方在于,这个失效是由两个系统共同产生的:它们在整数的结构上保持一致,却在整数的含义上产生了无声的分歧。

那些被你的提示词工程师转变为生产环境 Few-Shot 示例的评估集

· 阅读需 12 分钟
Tian Pan
Software Engineer

评估仪表盘连续三个迭代(sprints)都在攀升。困难切片的质量提升了 6 个百分点,回归切片提升了 9 个百分点,而在支持团队根据上季度最糟糕的工单亲手整理的切片上,质量提升了 12 个百分点。团队据此发布了模型升级。两天后,一位客户提出了一个与评估集中的任何内容都不沾边的问题,结果得到的答案比六个月前还要糟糕。

一旦有人想到进行排查,原因很快就浮出水面了。提示词工程师(prompt engineers)一直与评估团队在同一个代码仓库中工作。他们发现了那些精心策划的示例——这些示例来之不易,有的甚至是某人为了一个理想答案的措辞争论了一个小时才定下来的。在几个迭代中,他们把其中最有代表性的示例以 few-shot 演示的形式直接复制到了生产环境的系统提示词(system prompt)中。仪表盘持续攀升,是因为模型在推理时处理的正是它曾经逐字见过的输入。没有人指出这个问题。没有人负责划定“用于衡量质量的示例”与“用于发布到提示词中的示例”之间的界限。两个团队都准确地完成了他们被雇佣来做的工作。

系统提示词为他人调优的备选模型

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的可靠性仪表盘显示为 99.95% 。但你的支持收件箱却在诉说另一番景象。每周有那么两次,每次持续 10 到 20 分钟,极少数用户会遇到一个说话风格完全像另一家公司的产品版本。拒绝响应读起来很奇怪。一个原本总是渲染为整洁双栏卡片的结构化字段,现在变成了一个塞满了项目符号的段落。语气从“冷静的专家”变成了“热情的助手”。没有人会为此提交工单——他们只会直接关闭标签页,稍后再试。

你的供应商宕机了。故障转移生效了。延迟保持在 SLO 之下。错误预算没有变动。然而,用户在那个窗口期获得的体验,并不是你真正发布的那款产品。

大多数团队在采用多供应商架构时所持的心智模型是:系统提示词(System Prompt)是可移植的——它是一份与“能力出众的模型”这一抽象概念达成的协议,任何理解 LLM 方言的模型都能读懂。这种模型是错误的。系统提示词是一个经过调优的产物(Artifact)。它是针对特定模型的偏好、拒绝语法、格式习惯和指令遵循偏差进行调优的。当故障转移发生时,你并不是将同样的合同交给一个对等的签约方,而是将一份用主模型(Primary Model)的习语编写的合同,交给了一个阅读习惯完全不同却依然强行签字的模型。

被你的模型视为“约束性判例”的 Few-Shot 示例

· 阅读需 11 分钟
Tian Pan
Software Engineer

用户提交了一个问题。你的模型生成了一个答案,这个答案以一种非常具体的方式“自信地出错”:格式完美,推理结构严密,并且出现了一个特定的限定词——这个限定词完全不适用于这个问题——它出现的位置,恰好是你系统提示词(system prompt)中示例三出现类似限定词的地方。这既不是幻觉,也不是提示词注入。模型只是精确地执行了示例教它的操作,尽管这些示例原本并非为了涵盖这个问题。

这就是 Few-Shot 提示主动诱发的故障模式,而大多数评估套件(eval suites)在结构上对此是视而不见的。你的示例并不是“优秀范式”的中立演示。它们是判例法(case law)。模型通过表面 token 选择最匹配的项,并将该先例——包括其限制条件——应用到眼前的任何案例中。

供应商将你的模型标识符重定向到特定租户的微调模型,而其他人使用的却是基础模型

· 阅读需 12 分钟
Tian Pan
Software Engineer

客户支持团队升级了一个问题:“你的助手以前能正确处理退款资格问题。但上周开始出错了。”值班工程师调取了对话记录,在开发账号中使用相同的模型标识符回放了完全相同的提示词(prompt),得到了正确的回答,于是以“无法复现”为由关闭了工单。两周后,另一名客户提出了同样的投诉。工程师再次在同一个开发账号中进行回放,结果依然正确。团队开始归咎于没人做过的提示词更改。

请求中的模型标识符从未改变。响应字段中的字符串与请求字段中的字符串匹配。评估套件在六周内一直保持绿色。生产流量使用的模型权重与评估套件使用的模型权重是两套不同的集合,而且在该账号的整个生命周期中一直如此——直到过去这六周,它们变成了同一套权重,而团队注意到这一点仅仅是因为客户先发现了。

那些悄然成为你唯一评测集阅读者的提示工程师

· 阅读需 10 分钟
Tian Pan
Software Engineer

评测集(eval set)是一个文件。但它也暗含了对 AI 功能用途的理论定义。这两者并非一回事,混淆它们的团队建立了一个质量网关,而其校准完全依赖于单个人的工作记忆。当那个人离职时,文件留下了,但那套理论也随之而去了。

这是你在组织架构图中看不到的失败模式。你规划了一个提示工程(prompt engineering)角色。你雇佣了一个优秀的人才。他们发布了 v1 版本的提示词,审视了简陋的基准测试,并将其重写为内容丰富的东西——一个失败模式分类法、每个类别的权重,以及一套能够消除边缘情况歧义的标注指南(rubric)。评测集变成了“该模型是否好到足以发布”的契约。六个季度后,你发现这份契约除了编写它的那个人之外,其他人都看不懂。

被你的团队视为独立于模型版本的提示词版本

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的事故时间线显示“过去 72 小时内没有部署”。你的 Prompt 注册表也印证了这一点:prompt v37 已经冻结三周了。你的评估工具链在周二晚上运行正常。但在周三早上,你其中一个 Agent 的结构化输出失败率翻了三倍,另一个 Agent 的重试预算翻了一倍,而第三个 Agent 开始愉快地忽略一条它已经遵守了一个月的指令。什么都没变。除了确实有东西变了,而且变在组织中两边都没盯着的地方:模型。

Prompt 注册表记录 Prompt 版本。模型网关记录模型版本。但在实践中,几乎没有人追踪这两者的“配对”关系。Prompt v37 并不是一个独立的工件——无论你的工具链是否承认,它都是一份针对特定模型协商后的契约。当平台团队将 claude-sonnet-latest 别名向前推进一个补丁版本时,另一端的契约已经被悄悄修改了。由于部署发生在别人的基础设施上,且名称未变,你的事故时间线依然显示“没有部署”。

客户无法复现的隐形个性化层

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个平台团队发布了一项质量改进。推理阶段的一个图层会读取用户的近期交互记录,并悄无声息地调整响应风格:这里更正式一些,那里更简洁一些,或者当历史记录显示是一个工程师在提问时,响应会更具技术性。A/B 测试显示,整体满意度提升了几个百分点。发布公告的标题是“更智能的响应,无需更改 API”。没有人修改 API 中的标志位。没有人更新文档。响应内容中也没有任何迹象表明模型刚刚采用了哪种人格。

六周后,一位企业客户提交了一个支持工单,称“你们的模型比宣传的要差”。他们的内部评估套件——运行的是你们团队发布基准测试时所用的相同提示词——得分低了 8 分。你团队的第一步是核实提示词的一致性。提示词完全匹配。解码参数匹配。模型版本字符串也匹配。差异最终追溯到了个性化层,它为客户新开设的测试账号推断出一个“历史记录贫乏的默认人格”,而为你衡量基准测试的长效用户账号推断出了一个更丰富的人格。关于个性化究竟是功能还是缺陷的讨论,不再仅仅是一个产品决策,而演变成了一场合同谈判。

那个把用户的字面问题“改写”没了的摘要器

· 阅读需 9 分钟
Tian Pan
Software Engineer

一个用户问:“这是否符合第 28 条规定的‘转移’(transfer)?”四十轮对话后,模型给出了一个针对不同问题的答案。对话记录显示,模型回答了它收到的问题。用户正在阅读一份看起来像幻觉的投诉。两者都对。模型从未看到用户的提问——它看到的是你的摘要生成器对其进行的礼貌改写:“用户询问了第 28 条的适用性。”

“转移”一词就是问题所在。摘要生成器把它丢弃了,因为摘要生成器的损失函数被调优为保留事实而非措辞,而且评估准则从未学会区分改写主题和改写约束。主题被保留了。约束变成了迷雾。

这种失效模式是结构性的,而非偶发性的。任何通过模型生成的摘要来压缩长对话的应用,在关键路径上都有第二个模型——其质量契约通常被视为 Token 预算旋钮,而非一段产品逻辑。这种不对称性正是 Bug 所在。

那些你团队的人员已悄然停止阅读的标注队列

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的评估流水线每周会产生 800 条 trace 供人工审核。你的标注人员每周大约有 90 分钟的预算来处理这些数据。他们打开队列,对前三条进行打分,再将其余几条标记为“跳过”,然后就关闭了标签页。你在周一早上盯着看的排行榜,现在只是反映了哪些 trace 碰巧排在了列表顶部,而不是对系统质量的真实衡量。

这不是一个标注问题。这是一个披着质量问题外衣的吞吐量问题,也是评估项目退化最隐蔽的方式之一。Trace 仍在流动。仪表板仍在渲染。数值仍在变动。你没看到的是,你的“人工评分评估得分”的分母已经悄然缩减到了寥寥几项,而这些项是由一个没人刻意设计的排序函数挑选出来的。

抹除后续问题所需上下文的对话记忆修剪启发法

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个用户打开你的长会话智能体(agent),在第 3 轮对话时说:“我是素食主义者,而且预算有限。”对话继续进行。11 轮之后,裁剪器(pruner)开始运行。它计算 Token 数量,发现第 3 轮内容既陈旧又短小,于是为了将窗口维持在预算范围内,将其丢弃了。第 14 轮用户问:“我今晚该做点什么菜?”模型查看一个约束条件已不存在的窗口,推荐了一份 40 美元的肋眼牛排。用户觉得智能体变得越来越难用,打开满意度调查,给这次会话打了一个 2 分。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E6%8A%B9%E6%8E%89%E4%B8%8B%E4%B8%80%E8%BD%AE%E9%97%AE%E9%A2%98%E6%89%80%E9%9C%80%E4%B8%8A%E4%B8%8B%E6%96%87%E7%9A%84%E5%AF%B9%E8%AF%9D%E8%AE%B0%E5%BF%86%E8%A3%81%E5%89%AA%E5%90%AF%E5%8F%91%E6%B3%95"]辨

你的技术栈中没有任何环节会报告记忆失败。Token 预算仪表盘会显示窗口健康地维持在上限之下。延迟仪表盘会显示绿色。评估套件——将单轮回答与预留集进行对比评分——会报告没有退化。唯一能体现智能体能力下降的信号是一个差评,而你的产品团队会将其归咎于“模型方差”。但这并不是模型方差,而是裁剪启发法在错误的目标上,精准地执行了它被调优后该做的任务。

那些在评估集中遗漏、却在模型蒸馏中丢失的能力

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个团队将一个 200B 的教师模型压缩成一个 7B 的学生模型,因为评估套件——包含五万个覆盖产品发布时所有功能的样本——显示学生模型仅落后教师模型不到两个点,且推理成本降低了一个数量级。迁移上线了。成本曲线下降。客户满意度曲线持平。三周后,客服开始看到一类团队无法在评估中复现的故障。

学生模型不再识别教师模型曾默默处理的边缘案例输入格式。它不再能从教师模型曾可靠消除歧义的特定模糊指令中恢复。它不再产生那种罕见但关键的“与其猜测不如询问澄清问题”的行为——因为评估集以这些提示词是“坏数据”为由,清除了其中的模糊提示词。

评估结果显示蒸馏是忠实的。评估对于“忠实性”的定义是错误的。