跳到主要内容

LLM 供应商锁定是一个光谱,而非非黑即白

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个团队在 GPT-4 上构建了一个生产环境功能。几个月后,出于成本考虑,他们决定评估 Claude。他们花了两周时间进行“迁移”——但核心的 API 替换只花了一个下午。剩下的十天都花在了修复损坏的系统提示词(system prompts)、重新测试拒绝服务的边缘情况、调试由于意外文本而崩溃的 JSON 解析器,以及重新调整在不同供应商之间表现迥异的工具调用模式(tool-calling schemas)。原本以为只是简单的连接器更换,结果迁移预算膨胀成了多层重构。

这就是现实中的 LLM 供应商锁定问题。那些受挫的团队并不是因为选错了供应商——而是因为他们没有意识到锁定存在于多个维度,且每个维度都有不同的风险画像。

锁定分为六个层级,且重要程度各不相同

大多数工程师将供应商锁定视为 API 格式问题。但事实远不止于此。

第 1 层:API 调用格式。 OpenAI 兼容的 API 已成为事实上的标准——80% 以上的新供应商都支持它。更改基础 URL 和模型名称只需一行代码。这一层的切换成本最低,基本已得到解决。如果你是针对 OpenAI SDK 的形态进行构建,且你的供应商支持它,那么通常没问题。

第 2 层:提示词词汇与结构。 这是工程师们第一次感到意外的地方。Claude 经过微调,会密切关注 XML 标签结构。GPT 模型则更倾向于带有章节和强调的 Markdown 格式提示词。为某一模型系列优化的系统提示词在另一模型上往往会产生质量下降的输出——虽然不是灾难性的错误,但会以难以察觉的方式偏离预期,需要时间来诊断。指令风格也存在差异:面向指令的模型受益于显式的、结构化的提示词;而面向推理的模型在面对稀疏的高层目标和强大的验证步骤时表现更好。

第 3 层:工具调用模式。 OpenAI 使用 JSON Schema 定义函数。Claude 使用内容块,其中 tool_use 与文本分开出现。Google Gemini 则有自己的格式。工具选择的准确率各不相同:GPT-4o 达到 97–99%,Claude Sonnet 为 96–99%,Gemini 为 95–98%。孤立来看,这些差异是可以容忍的,但当你每天运行数千次智能体(agentic)工具调用时,2% 的准确率偏差就是实际生产环境中的巨大差异。

第 4 层:输出长度规范与格式偏好。 Claude 偶尔会在 JSON 块之前添加散文式描述——“这是你请求的数据:”——这会静默地破坏那些期望原始 JSON 的解析器。GPT-4o 在严格遵守输出格式指令方面更加一致。这些行为通常未被记录在文档中,且在模型版本之间会发生变化。团队是在生产环境中发现这些问题的,而不是在评估阶段。

第 5 层:拒绝模式与安全对齐。 不同模型有不同的阈值。安全对齐严苛的模型在面对不安全提示词时的履行率非常低,但对无害提示词的过度拒绝率也更高。如果你的应用涉及边缘领域(医疗、法律、成人内容),模型的拒绝画像就是你产品的一部分。切换供应商可能会改变这种画像,而这些变化在转化为客户投诉之前是不可见的。

第 6 层:嵌入、微调与存储状态。 这是最难逃脱的一层。使用一家供应商模型存储为嵌入(embeddings)的聊天记录,与另一家供应商的嵌入空间不兼容。在专有平台上微调的模型通常无法导出。如果你的应用使用检索或记忆功能,你的数据就与供应商的表示层纠缠在一起了。

哪些依赖是可以接受的,哪些从第一天起就是技术债

正确的思维模型不是“避免所有锁定”,而是“知道你正在刻意承担哪些锁定”。

可接受的锁定是指满足以下条件的依赖:

  • 该功能提供了其他地方无法获得的、真实的、可衡量的优势
  • 迁移成本是有限的,且你已诚实地估算了成本
  • 该功能是稳定的,且供应商已承诺其长期存在
  • 你已经构建了一个抽象层,限制了下游的影响范围

在复杂的推理管线中使用 Claude 的扩展思考(extended thinking)是可接受的锁定。这种能力具有真正的差异化优势,且可在多个部署目标(直接 API、Bedrock、Vertex AI)上使用,你可以将它的使用范围限制在特定的管线阶段,而不会渗透到代码库的其余部分。同样,在 GPT-4o 的视觉能力明显优于其他方案的文档理解任务中使用它,也是一种合理的工程折中。

从第一天起就产生的技术债表现为:

  • 应用代码直接调用供应商 API 而没有抽象层,且没有添加抽象层的计划
  • 提示词字符串中充斥着特定供应商的格式,且从未针对替代方案进行过测试
  • 在专有平台上进行微调,而不导出权重,也不验证这种改进是否能推广到可应用于其他基础模型的参数高效技术(LoRA、适配器)
  • 将嵌入和聊天记录存储在供应商管理的向量数据库中,且没有导出路径
  • 依赖于既未记录在文档中、也未测试过跨版本一致性的输出行为(特定的 JSON 格式、冗长程度、推理轨迹)

这种债务的成本不仅仅是最终的迁移,还有持续的隐性成本:如果不重建评估框架,你就无法对新模型进行竞争性评估;你无法应对供应商的价格变化;当供应商发生故障时,你无法降级到备选方案。

真正行之有效的抽象架构

业界已经在隔离策略上达成了一些切实的共识。

在边缘层使用 AI 网关。 LiteLLM 和 Portkey 等工具位于应用程序代码前端,通过统一接口在不同提供商之间进行转换。Netflix、Lemonade 和 Rocket Money 在生产环境中使用 LiteLLM,无需重写应用逻辑即可在第一时间接入新模型。当你想从一个提供商切换到另一个时,只需更改配置值,而非应用代码。网关还为你提供了中心化的可观测性、成本归因以及在提供商服务降级时的回退路由。

Gartner 预测,到 2028 年,构建多 LLM 应用的组织中将有 70% 通过 AI 网关进行路由,而 2024 年这一比例还不足 5%。趋势非常明显:直接与提供商耦合正被视为一种技术风险,就像 2000 年代直接与数据库耦合一样。

抽象你的提示词层。 不要将特定提供商的格式嵌入业务逻辑。相反,应维护一个接受模型目标作为参数的提示词生成器(prompt builder),并应用相应的结构规范——例如 Claude 使用 XML 标签,GPT 使用 Markdown 章节,推理模型则使用极简结构。这虽然增加了一层间接性,但使跨模型评估变得可行。

使用 MCP 进行工具集成。 模型上下文协议(Model Context Protocol)最初于 2024 年 11 月发布,目前已被 OpenAI 和 Google 采用,它规范了模型连接外部工具和数据源的方式。按照 MCP 规范构建一次工具集成,即可在 Claude、GPT 和 Gemini 上运行,无需针对每个提供商编写适配代码。这不会消除所有的工具调用差异,但能显著减少针对每个提供商的开发工作量。

隔离你的嵌入(Embedding)层。 如果你使用检索或记忆功能,请将嵌入流水线置于接口之后,以便更换底层模型。不要将提供商的嵌入对象直接传递到应用代码中。当你因为更换提供商而需要重新嵌入时,影响范围应仅限于一个模块,而不是对整个检索路径进行重构。

切换成本的算账逻辑

那些将模型切换视为“插拔式”操作的企业团队通常会发现事实并非如此。隐藏成本是可预见的:

迁移通常会消耗原始开发时间的 20% 到 50%。在评估和迁移期间,团队通常会同时运行两家供应商的合同,导致一段时间内支付双倍费用。企业级的最低年度承诺金额在 5 万到 20 万美元之间——因此,如果处理不当,一次每年能节省 3 万美元推理成本的迁移可能需要三年时间才能收回成本。

仅 Token 化(Tokenization)的差异就会带来预算意外。对于相同的输入,Anthropic 的分词器比 OpenAI 的更冗长——在 GPT 上花费 X 个 Token 的提示词,在 Claude 上会花费更多。适用于一个提供商的 Token 预算无法直接套用。围绕特定分词方案构建的缓存也需要重新调整。

更微妙的是,质量回退会出现在你没有测试过的地方。你测试的是理想路径(happy path)。你所迁移到的模型在长尾输入上会有细微差别——不同的推理模式、对模糊指令的冗长度差异、对错误工具参数的处理方式。从“通过评估”到“达到生产就绪”之间的差距往往比工程师预期的要长。

能够以低成本完成迁移的团队,是那些在需求出现之前就考虑到迁移的团队。他们维护了针对特定模型的提示词变体,使用网关进行路由,保持嵌入的可移植性,并进行定期的跨模型评估,因此他们早已了解差异所在。

何时应有意识地接受绑定

这并不意味着你应该避开特定提供商的功能,而是意味着你在使用它们时应保持清醒。

如果 Claude 的深度思考(extended thinking)是复杂推理流水线的正确工具,那就使用它——但要限定绑定的范围。不要让深度思考的提示词格式渗透到通用的聊天代码中。将特定提供商的功能隔离在具有显式接口、清晰弃用路径和记录备选方案的模块中。

如果 GPT-4o 的视觉处理在你的文档理解场景中明显更优,那就使用它。但要在上下游保持抽象层,这样视觉组件就可以在不重建周围流水线的情况下进行更换。

Meta 的开源模型策略极具启发性:用户留下是因为生态系统确实有用,而不是因为他们被困住了。构建你的应用也要满足同样的约束。如果用户(或你自己的工程团队)想要更换底层模型,这种更换应该是网关层的配置变更,而不是涉及十个文件并搞挂三个解析器的重构。

真正关键的维度

如果你现在正在构建一个新的 LLM 应用,以下是值得深思熟虑的可移植性决策:

  • 通过网关进行路由。 只需一行代码即可添加 LiteLLM 或 Portkey;而稍后移除直接耦合则需要数月的重构。
  • 从第一天起就跨提供商测试提示词。 针对至少两个模型系列运行你的评估套件。这样在绑定深入之前,它就会变得显而易见。
  • 掌控你的嵌入表示。 保留导出路径。永远不要在没有导出路径的情况下依赖提供商托管的向量数据库。
  • 限定特定提供商功能的范围。 可以使用深度思考、视觉或推理模式,但要将它们限制在具有显式接口的有界模块中。
  • 追踪输出格式行为。 记录模型输出偏离预期格式的情况。这些在生产环境中通常表现为解析器 Bug。

目标不是追求“模型无关”(model-agnostic)——这是一种昂贵的抽象,往往会因为针对最低标准而降低质量。目标是实现“模型可移植”(model-portable):能够做出深思熟虑的提供商决策,在情况变化时更换组件,并且永远不会因为供应商的价格决策或停机而被迫迁移。

绑定是一个光谱。那些保持可移植性的团队,是早早就决定了自己愿意处于该光谱的哪个位置,并据此进行构建的团队。

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