模型更新只有4类变更真正影响代码:配置数据、新标识符、请求/响应结构、行为差异;大多数版本迭代无需改动代码,只需改配置。
真正影响代码的新模型发布,到底需要做什么
模型发布公告来得比任何团队评估的速度都快,而它们制造的焦虑大多是没有必要的:对于一个边界良好的代码库,绝大多数发布根本不需要任何改动。决定这一点的不是你有多擅长跟进,而是你的抽象边界画在哪里。
剥掉发布公告中的营销措辞,具体来说,只有四件事可能与你当前运行的版本不同:
前两件事几乎始终只是配置变更。第三件事是唯一可靠地需要写代码的。第四件事需要评估,是工作但不是开发工作——而且它最有可能在暗中伤到你,因为它静默地到来。
新模型的存在。如果你的模型标识符来自配置或目录,而不是代码中的字面量,那么新模型就是一条数据记录。没有任何东西需要发布。
价格变动。如果价格是数据,那就是一次数据更新。如果价格是代码中的常量,那就是一次发布——而且更糟糕的是,你没有注意到的价格变动是静默的:一切都与一个过时的数字完美对账,而你则在系统性地少收或多收费用。
基准分数。基准测试结果不是你工作负载的证据。它们只是运行你评估集的理由,仅此而已。基准为什么不具备迁移性——这才是完整的论证。
更大的上下文窗口。能够发送更多信息不是发送更多的理由。你的实际开销与你发送的内容成正比,而质量并不会随着发送量的增加而单调提升。
有日期的弃用。工作在于选择替代方案并运行评估集,而不是改代码。把那个日期放在会通知到人的地方,因为文档里的日期依赖于某人在正确的那天重新阅读文档——而这恰恰是写下来本来要避免的事情。
客户端库中的新默认值。改变重试次数、超时时间或默认模型的 SDK 升级是一种伪装成依赖升级的行为变更。请锁定版本,并专门阅读变更日志中关于默认值的部分。
跨越路由阈值的价格变动。如果你按成本进行路由,竞争对手的降价会静默地重路由你的流量。这通常是正确的,但仍然应该是可见的。
你想要的新响应字段。推理 token 计量、每个部分的用量明细、缓存命中指示器。每一个都需要被读取、存储和展示。
请求中的新内容类型。音频、视频、文档作为一级输入。新的验证、新的尺寸限制、新的存储。
你的抽象没有插槽的能力。这是代价最高的一类。如果新模型暴露了你的提供商无关接口无法表达的东西,你要么为所有人拓宽接口,要么对某一个提供商做特殊处理——而第二个选项正是抽象腐化的方式。
某些提供商选择忽略而非拒绝的参数。静默接受比拒绝更糟糕:你会收到一个全额计费的响应,但其中没有你的代码所期望的字段。在你自己的边界处拒绝不支持的参数。
某条发布公告是数据更新还是一周的工作,这在你看到公告之前很久就已决定了,由五个边界决定。
拥有这五个边界的团队会发现大多数公告只是一条表记录。没有这五个边界的团队则发现每次发布都是一个项目,然后得出结论说这个领域变化太快——而实际上变化太快的只是他们与某一供应商表面的耦合。参见《提供商无关代码》。
它是否弃用了我正在运行的东西?如果是,这是公告中唯一紧急的事项。把那个日期记到会发出警报的地方。
它是否改变了我进行计费的价格?更新数据,并检查它是否跨越了路由阈值。
它是否添加了我会使用的请求或响应字段?如果不是,停止阅读。大多数公告在这里就结束了。
有没有可信的质量或成本收益?如果有,就运行你的评估集和提供商切换清单中的差异测试工具。不是对三个 prompt 凭感觉检查。
其他都是阅读。有趣,但不可操作。保持跟进是一项研究活动,应该像研究活动一样规划预算——如何阅读模型发布中涵盖了值得提取的内容。
需要防范的静默情况是模型在稳定标识符下发生了变化。如果你的提供商不提供固定版本,记录响应中报告的模型字符串并在变化时告警;否则第一个症状是几周后的质量投诉,而原因在《为什么一个生效的 prompt 突然不工作了》中。
对于通过分诊后数量不多的发布,决定是否值得切换的只有四件事,而且只有第一件与质量相关。
把切换作为老路由预热的逐步放量来运行,而不是作为直接切换。重要的差异会在生产形状的输入上浮现,回滚必须是路由变更而不是重新发布——这是设计断路器的四层中的第一层。
同时做而不是事后做的一件事:记录每个请求由哪个模型服务。没有这条信息,在放量三周后提出的质量问题就得不到答案,因为数据中没有任何东西能区分这两个群体。