跳到主要内容

LLM 输出即 API 契约:为下游消费者版本化结构化响应

· 阅读需 11 分钟
Tian Pan
Software Engineer

2023 年,斯坦福大学和加州大学伯克利分校的研究团队做了一项受控实验:他们在 3 月和 6 月分别向 GPT-4 提交了完全相同的提示词,任务非常基础——判断一个数字是否为质数。3 月时,GPT-4 的准确率为 84%。到了 6 月,使用完全相同的 API 端点和完全相同的模型别名,准确率已跌至 51%。没有变更日志,没有通知,没有传统意义上的破坏性变更。

这项实验清晰地揭示了一个在多服务架构中部署 LLM 的团队迟早都会遇到的问题:模型别名不是稳定的契约。当你的下游支付处理器、推荐引擎或合规系统依赖 LLM 生成的结构化 JSON 时,你就建立了一个隐式的 API 契约——而隐式契约会悄无声息地崩溃。

传统的 API 版本化方案在这里并不完全适用。REST 端点不会自发改变响应结构,但 LLM 会。模型提供商可以在不触发任何 API 兼容性保证的情况下更新权重、调整安全过滤器或改变采样行为。JSON 依然能正常解析,模式验证依然通过,日志看起来一切正常。然而三周后,在某个下游服务中,一个被污染的值悄悄渗入财务报告或用户推荐结果。

本文的目的,是将这个问题作为一个真正的工程问题来对待——将已在服务 API 领域行之有效的契约测试和版本化规范,应用到 LLM 输出这个非确定性的世界中。


两种不同的故障模式:模式漂移与行为漂移

在防御 LLM 输出破坏之前,你需要区分两种表面相似但需要不同检测策略的故障模式。

模式漂移改变的是输出的结构。字段被重命名,必填键被删除,类型从字符串变为整数。在一个有完善监控的系统中,模式漂移应该能被立即检测到——Pydantic 或 Zod 验证器会抛出错误。危险在于,大多数团队以防御性的方式连接验证:他们在边界处验证,但不将验证失败视为阻断构建的事件。故障出现在错误日志中,被默默地重试,而事故复盘时才追溯到三周前的一次提示词修改。

行为漂移更难检测,因为它不会导致验证失败。结构完整,模式满足,但语义已经发生了偏移。置信度分数的分布发生变化,实体提取模型开始返回完整的句子而非名词短语,原本返回三个不同值的分类字段开始有 80% 的时间只返回其中一个。一切都能正常解析,下游服务照常处理,问题最终以产品质量下降的形式浮出水面,却无人能追溯到根本原因。

这两种故障模式在生产环境中都是真实存在的。对金融工作流的研究发现,更大的模型往往更不一致:一个 1200 亿参数的模型在零温度下的输出一致性仅为 12.5%,而较小的 70-80 亿参数模型在相同条件下能达到 100% 的一致性。规模和能力并不意味着可靠性。


为什么模型别名是一个陷阱

斯坦福的漂移研究并非孤例,它只是对从业者早已心知肚明的事情进行了量化测量:gpt-4 今天和明天代表的不是同一个东西。

提供商会不断更新模型权重,以修复安全问题、改善指令遵循或优化计算效率。这些更新持续发布,鲜少公告。同一个模型标识符可能产生不同的输出,因为"同一个模型"不过是一种方便的说辞——它只是一个指向提供商当前认为该模型家族最优版本的指针。

在多步骤流水线中,影响会叠加放大。当你更新链条中的一个提示词时,所有下游提示词都会收到不同的输入。它们本身没有改变,但由于输入分布发生了偏移,行为随之改变。这种"依赖提示词"的故障模式对于单独评估提示词的任何测试策略都是不可见的。

实际应对措施很简单:明确锁定模型版本。使用 gpt-4-0613 而非 gpt-4,使用 claude-3-opus-20240229 而非 claude-3-opus。制定正式的升级窗口并配备回归测试套件,而不是接受提供商别名指向的任何版本。当 OpenAI 停用某个锁定版本时,将其视为破坏性的依赖项升级——与应用主要库版本升级时相同的流程。


模式设计是契约的一部分

在对 LLM 输出进行版本化或测试之前,你必须为稳定性而设计它们。看似无关紧要的模式选择,对输出可靠性有着巨大影响。

字段重命名可能导致模型性能下降 90 个百分点。在一项受控实验中,将输出字段名从 final_choice 改为 answer,在相同的底层任务上将准确率从 4.5% 提升到了 95%。模型是在"answer"是该概念自然词汇的数据上训练的;重命名破坏了模式与模型隐式先验之间的对齐。

字段顺序同样重要。如果你在模式中将答案字段放在推理字段之前,模型会在完成推理之前就锁定答案——这是一种结构性提示,优化了看起来自信但实际上并不可靠的输出。将推理字段放在答案字段之前,能持续提高准确率,因为模型的思维链会塑造最终值。

命名选择、字段顺序和类型特异性不是装饰性决定。它们是契约的一部分,改变它们是破坏性变更,必须被如此对待。


对完整执行上下文进行版本化

传统语义化版本管理自然适用于 LLM 输出契约:

  • 主版本号在输出格式重构、字段重命名、类型变更,或任务定义变化足以破坏任何未更新下游消费者时递增。
  • 次版本号在向后兼容的添加时递增——新的可选字段、格式不变的质量提升。
加载中…
References:Let's stay in touch and Follow me for more thoughts and updates