跳到主要内容

毫无意义的影子部署:当并行调用错失对话语境时

· 阅读需 10 分钟
Tian Pan
Software Engineer

影子部署(Shadow deployment)是每个人都公认的负责任的验证方式。你将实时流量镜像到一个候选模型中,记录其输出,但从不向用户展示结果。仪表盘数据一致,候选模型的响应在聚合质量指标上看起来与现有模型(incumbent)一样好,团队收到了新模型是“生产等效”的绿色信号,然后你将其推广到一小部分真实的流量中。在一天之内,在那些影子运行评估为匹配的查询类别上,面向用户的指标全面崩溃。

团队的第一反应是归咎于发布过程:也许是功能标志(feature flag)出错了,也许是路由器(router)路由错误,或者新模型在生产环境中的性能在某种程度上悄无声息地下降了,而影子部署时却没有发现。这些都不是真的。影子部署完全按设计运行。团队衡量的是候选模型孤立的输出——字符串对字符串——而推向生产环境的候选模型,其输出会重塑用户的下一条消息、下一轮对话、放弃决策以及整个会话的路径。影子部署衡量的是模型。生产环境衡量的是对话。这两者并非同一维度。

影子评估只是更昂贵的离线评估

团队之所以选择影子运行,是因为它们感觉比离线评估更安全。离线评估是根据一组静态输入和一组静态参考给模型打分;影子运行则是在真实的生产分布上实时打分,且不对用户产生风险。第二部分是真的。第一部分则是陷阱。影子运行为你提供了针对真实输入分布的候选模型首轮输出,但它无法告诉你接下来会发生什么。

撰写部署策略的从业者在这一框架上是一致的:影子模式让你能够“在不影响用户体验的情况下,在真实的生产环境中评估新的机器学习模型”,并且候选模型“在后台运行”,而现有模型是唯一输出到达用户的模型。“不影响用户体验”这句话被当作一种安全属性来推销。它也是一种测量属性。一个不影响用户体验的运行无法测量用户体验。

这正是让团队感到意外的差距:影子评估对于系统中关键的部分来说等同于离线评估。它比你的离线评估更昂贵,因为它消耗了实时基础设施和供应商的 token,而且因为它能看到生产环境的输入分布,感觉更接近生产环境。但在输出端,影子评估和离线评估都在对同一事物打分:孤立的字符串,要么对比参考值,要么对比现有模型的并行输出,且处于单轮框架中。这种对比无法知道用户会对候选模型的回答做出什么反应。

对话是系统,而非轮次

破坏影子评估的这种替换是无声的,因为生产系统是多轮的,而评估是单轮的。候选模型的首轮回答看似合理。但它可能比现有模型的回答稍欠具体,或者在不同的地方含糊其辞,或者提出了不同的下一步建议。在单轮评分标准中,这些差异都不会被记录为质量下降。

但它们都会改变用户的下一条消息。用户可能会提出一个在现有模型下本不需要的后续问题。用户会澄清一些现有模型已经消除歧义的内容。用户在两轮之后就放弃了,而不是在一轮之后。

最近关于多轮智能体评估的学术研究明确指出:对话具有特定的非确定性,其中“第 n 个 AI 响应取决于第 (n-1) 个用户消息,而该消息又取决于之前所有的交流”。多轮指标必须评估整个对话的一致性,而不仅仅是单个回合。关于智能体评估的调查研究也论证了同样的观点——任务完成情况、记忆和上下文保留、规划——这些都是对话层面的属性,任何单轮对比都无法对其进行评分。

影子评估无法察觉到这些。候选模型在第一轮与现有模型并行运行。它永远看不到第二轮,因为第二轮应该是用户对候选模型回答的反应,而用户只看到了现有模型的回答。候选模型本可以产生的轨迹在日志中根本不存在。仪表盘显示“匹配”,因为仪表盘唯一能衡量的就是第一个字符串。

仔细观察时,“匹配”的实际含义

有必要具体说明一下影子对比指标通常会简化为什么。常见的实现分为三类。第一种是输出相似度:候选模型响应与现有模型响应之间的余弦距离或 token 重合度。第二种是由 LLM 裁判根据候选模型的独立输出进行的单轮质量评分。第三种是侧重于“给定此输入,哪个响应更好”的并排(side-by-side)偏好判断。

这三者都是首轮指标。没有一个锚定在已解决的任务上。影子运行可能会返回“97% 的候选模型输出在与现有模型输出的相似度阈值内,而在剩下的 3% 差异中,LLM 裁判在 52% 的情况下更倾向于候选模型”——而这个结果对于判断用户使用候选模型完成任务时是需要更少回合、更多回合,还是直接放弃,确实毫无参考价值。

该指标不知道什么是已解决的任务。它只知道什么是相似的字符串。当团队凭借这种影子结果进行推广并眼睁睁看着面向用户的指标崩溃时,自然的反应是质疑生产环境的发布。真正的元凶是影子部署所衡量的维度。输出相似度和单轮裁判评分是结果质量的代理指标,就像任何代理指标一样,它们在失效前一直有效。从业者在谈到离线-在线悖论时直白地指出了这种失败模式:“改善离线指标的变化可能不会改善,甚至可能损害在线指标。” 影子运行继承了这种风险,因为从相关意义上讲,它们本质上是离线的。

真正弥合差距的模式

将 Shadow 视为等同于离线环境,并不意味着要放弃它 —— 而是要清楚通过它的结果你能推广什么,不能推广什么。弥合差距的准则在于衡量轨迹而非转折,衡量结果 (outcomes) 而非产出 (outputs)。

针对候选版本下游效应的交错曝光 (Interleaved exposure)。与其对候选版本进行 Shadow 处理(并行调用但从不展示),不如将候选版本的输出暴露给一小部分真实用户,并衡量下游行为的增量 —— 如后续转化率、会话时长、流失率、回访率 —— 而不是衡量输出相似度的差异。在排序系统中,交错测试 (Interleaved testing) 相比 A/B 测试具有广为人知的效率优势,因为它控制了单元间的方差。同样的逻辑也适用于 Agent:你真正想得到答案的问题是“这个候选版本是否改变了用户的后续行为”,而衡量这一点的唯一方法就是让部分用户看到该候选版本。即使是触达真实用户的最薄的一层曝光,也胜过最丰富的 Shadow 数据。

多轮轨迹的反事实回放 (Counterfactual replay)。在无法将候选版本输出暴露给真实用户的情况下 —— 如高风险流程、受监管的界面、具有副作用的 Agent —— 请用模拟轨迹取代并行调用。使用用户模拟器(扮演用户角色的 LLM,根据实际对话历史进行引导),在候选版本的第一轮响应下生成后续几轮对话。模拟是不完美的,但现在的相关单元是轨迹 (trajectory) 而非单轮 (turn)。在候选版本 A 与候选版本 B 下运行十轮模拟对话的反事实回放,将揭示单轮对比所掩盖的那种漂移 —— 比如解决问题更慢的候选版本、其模棱两可的回答触发了额外澄清的候选版本,或者提出了用户拒绝的路径的候选版本。

基于结果锚定的评估,而非单轮质量。评估应该根据任务解决率或会话完成率评分,而不是根据单轮评分表。这需要定义一个存在于系统某处的“解决事件” —— 一个确认的操作、一张关闭的工单、一个被采纳的建议或一个成功完成的交易。一旦评估锚定在该事件上,“单轮质量匹配”就不再是可接受的发布标准。候选版本必须在用户真正买账的单元上匹配 —— 或击败 —— 现有的线上版本:即解决的任务,而不是润色过的句子。

Shadow 用于评估能力,而非作为发布标准。Shadow 运行对于它们实际衡量的东西仍然有用:候选版本在真实输入分布上的基本能力。它们是捕获候选版本异常的快速方法,比如在离线评估漏掉的查询形状上崩溃、针对真实 Schema 生成了格式错误的输出,或者遇到了你未曾预料的速率限制。将 Shadow 结果视为发布的先决条件,而不是发布标准。“候选版本在 Shadow 中不崩溃”是一个二进制的准入门槛。“候选版本在 Shadow 中与线上版本匹配”并不是通过的绿灯。

架构层面的认知

将 Shadow 评估作为发布标准的深层问题在于,它隐含了一个关于 AI 系统质量存在于何处的假设。如果质量存在于模型返回的字符串中,那么比较字符串就是一种有效的质量衡量。如果质量存在于用户与模型的对话中 —— 贯穿各轮的轨迹、最后的任务解决情况、再次使用的意愿 —— 那么比较字符串就是一种类别错误 (category error)。Shadow 衡量的是错误的单元。

在上述模式变得显而易见而非昂贵之前,必须先达成这种认知。AI 系统的质量是用户在整个会话中的体验,而不是模型在某一轮的输出。那些只关注字符串 Shadow 而忽略对话的团队,从最字面的意义上来说,衡量错了东西。仪表盘显示绿色是因为它连接到了 Shadow 能看到的单元,而上线后的崩溃是因为用户消费的不是字符串 —— 他们消费的是对话。

补救措施不是增加更多的 Shadow。而是承认 Shadow 本质上是离线的,离线是单轮的,而你真正想要据此发布的单元存在于 Shadow 触达不到的地方。构建交错曝光的切片。构建反事实回放。将评估锚定到任务解决事件。然后将 Shadow 视为它一贯以来的廉价预设条件,不要再把它的绿灯读作是对一个 Shadow 从未观察过的系统的判决。

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