跳到主要内容

将你的 LLM 提供商视为不可靠上游:AI 的分布式系统实战手册

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的监控仪表板一片绿色。响应时间看起来正常。错误率接近于零。然而你的用户却在提工单投诉垃圾回答,你的 agent 正在做出自信满满的错误决策,你的客服队列里塞满了与任何基础设施告警都不相关的投诉。

欢迎来到在生产环境中依赖 LLM API 的独特地狱。这是一个能在返回完美健康的 200 OK 的同时让你翻车的上游服务。

大多数后端工程师已经内化了一套处理不可靠第三方依赖的实战手册:熔断器、指数退避重试、舱壁、超时、降级响应。这些模式经过数十年分布式系统实践的战火洗礼。但 LLM API 打破了这些模式赖以建立的每一个假设,天真地应用它们只会给你一种虚假的安全感,而真正的故障却在不知不觉中溜走。

你没在监控的故障模式

传统的上游服务以你的监控栈知道如何捕获的方式故障。数据库返回连接错误。支付 API 返回 500。微服务超时。你的告警响了,熔断器跳闸,降级方案启动。系统优雅降级。

LLM API 引入了一种基础设施监控从未被设计来检测的故障模式:语义退化。API 返回 200,延迟看起来正常,响应体是格式良好的 JSON——但内容是错的。模型幻觉出了一个不存在的政策。它用竞争对手的信息回答了关于你产品的问题。它遵循了用户输入中嵌入的提示注入指令。这些都不会触发你 Datadog 仪表板上的任何一个告警。

这就是 LLM 上游与你依赖的其他所有 API 之间的根本区别。对于支付处理器,200 意味着扣款成功。对于 LLM,200 意味着模型产生了 token。这些 token 是否有用、准确或安全,是一个你的基础设施层没有任何意见的独立问题。

在生产环境中真正造成伤害的故障往往遵循一个模式:

  • 幻觉漂移:模型开始基于越来越不相关的上下文生成回答,但响应保持流畅和自信,而正确性在衰退。
  • 行为回归:提供商更新了他们的模型,你精心调优的提示开始产生微妙不同的输出。语气变了,格式变了,曾经好用的边界情况现在不行了。
  • 静默工具调用损坏:在 agent 工作流中,模型行为的微小变化触发过多或不正确的工具调用,而你的基础设施指标不会标记这些问题。

为什么你的超时策略可能是错的

为 LLM API 设置超时比听起来更难,因为延迟分布与你技术栈中的任何东西都不一样。一个典型的微服务可能 P50 是 50ms,P99 是 200ms——4 倍的差距。LLM API 经常表现为 P50 500ms,P99 4-5 秒——10 倍的差距。在糟糕的日子里,P99 可以飙升到 15-20 秒,而提供商不报告任何事故。

这意味着你的超时必须适应一个巨大的范围。设得太紧,你会杀掉原本会成功的请求。设得太松,你的用户会盯着转圈图标 20 秒然后收到一个错误。两个选项都不可接受。

"将超时设为 2 倍 P99"的常规智慧在这里失效了,因为 P99 本身就是不稳定的。在高峰时段或提供商模型更新后,你的基线延迟可以在没有任何警告的情况下偏移 3-5 倍。根据昨天延迟分布校准的超时今天可能就是错的。

在实践中更有效的方法:

  • 自适应超时,基于最近延迟百分位数的滚动窗口,而不是静态配置值。如果你的 P95 在过去 10 分钟一直在攀升,你的超时应该自动调整。
  • 按操作的超时预算,考虑预期的输出长度。生成 50 个 token 的请求应该有一个与生成 2,000 个 token 的请求非常不同的超时。
  • 截止时间传播,从你面向用户的 SLA 向后通过调用链传播。如果你的 API 承诺在 10 秒内响应,你已经花了 3 秒在检索上,你的 LLM 调用得到 6 秒的预算,而不是你的 HTTP 客户端配置的默认值。

熔断器需要语义维度

经典的熔断器模式监控错误率:当故障超过阈值时,熔断器跳闸断开并停止向故障服务发送流量。对于 LLM 提供商,这大概捕获了 20% 的问题——那些实际产生 HTTP 错误的问题。

生产 AI 团队最终构建的熔断器同时监控三个信号:

错误率(传统信号):追踪 429、500、502 和 503。来自生产部署的社区共识大约是 5 次失败触发跳闸,60 秒冷却期。在错误率大于 5% 时告警,大于 15% 时升级为严重。

延迟退化:当 P95 延迟超过其滚动基线的 3 倍时,即使每个请求最终都成功了,也将其视为部分故障。一个技术上在线但每个请求需要 12 秒的提供商,对于任何面向用户的应用来说都是功能性宕机。

质量退化:这是最难的。你需要内联质量检查——在响应样本上运行的轻量级评估,以检测幻觉率增加、格式合规性下降或指令遵循回归。当你的质量分数降到阈值以下时,熔断器应该将流量路由到降级提供商,即使主提供商在技术上是健康的。

构建第三个信号是区分在生产中运行 LLM 的团队和在生产中演示 LLM 的团队的关键。

降级链比你想象的更复杂

REST API 的典型降级策略很简单:如果服务 A 失败,试服务 B。LLM 降级更棘手,因为服务之间不可互换。

不同提供商的不同模型有不同的能力、不同的上下文窗口、不同的指令遵循特性和不同的故障模式。你在 Claude 上完美工作的提示在 GPT-4o 上可能产出垃圾,反之亦然。OpenAI → Anthropic → Google 的降级链在白板上看起来很好,但需要维护三套提示、三套质量基线和三套集成测试套件。

在生产中实际有效的方法:

  • 优先同提供商降级:在跨提供商边界之前,先尝试同一提供商的不同模型层级。从 GPT-4o 降级到 GPT-4o-mini,或从 Claude Opus 降级到 Claude Sonnet,保持你的提示兼容性高,同时在退化期间给你一个更便宜、通常更快的替代方案。
  • 缓存响应降级:对于你之前见过的查询(或足够相似的查询),从响应缓存提供服务。这对于信息检索和 FAQ 类型的交互出奇地有效,前提是新鲜度不是关键。
  • 优雅降级响应:对于某些功能,正确的降级不是另一个模型——而是一个静态响应,告诉用户"此功能暂时在有限模式下运行",而不是提供一个看起来很权威的低质量回答。

一个关键错误:不要让你的降级与主路径共享同一个故障域。如果你的主路径和降级都通过同一个 LLM 网关路由,网关宕机会同时打掉两条路径。如果两个提供商使用同一个云区域,区域性事故会同时影响两者。

构建你会后悔没有早点建的提供商健康仪表板

每个在生产中运行 LLM 的团队最终都会构建某个版本的提供商健康仪表板。有效的仪表板追踪五件事:

请求级指标:延迟百分位数(P50、P75、P95、P99)、按状态码的错误率和吞吐量。这些是基本功——你对任何上游都会追踪它们。

Token 经济学:每个请求的输入和输出 token 计数、每个请求的成本,以及如果你使用提示缓存的缓存命中率。这是你发现模型更新后开始生成冗长响应的微妙成本爆炸的地方。

质量分数:对采样百分比的响应进行自动化评估分数。即使是简单的格式合规检查("响应是否遵循了我要求的 JSON 模式?")也能捕获数量惊人的回归。

速率限制余量:你离你的预配置吞吐量和每分钟 token 限制有多近,以百分比追踪。你想在 70% 利用率时告警,而不是在你已经收到 429 的时候。

提供商事故关联:一个将你的内部质量指标与提供商状态页面更新叠加的时间线。这让你能够回顾性地识别质量下降是由提供商变更还是你这边的问题造成的。

构建此仪表板的最重要洞察是,LLM 提供商的可靠性不是二元的。没有单一的"在线或宕机"状态。提供商可以在错误率方面在线、在延迟方面退化、在质量方面失败——同时发生。你的监控需要反映这一点。

舱壁模式:隔离你的 AI 功能

如果你的应用从多个功能调用 LLM 提供商——聊天机器人、摘要管道、代码审查工具——而它们都共享同一个 API 密钥和连接池,一个功能的速率限制命中会饿死所有其他功能。

舱壁模式将功能隔离到具有独立资源池的独立隔舱中。对于 LLM API,这意味着:

  • 每个功能使用独立的 API 密钥(或至少独立的速率限制追踪)。
  • 每个功能使用独立的熔断器,这样退化的聊天机器人不会触发你摘要管道的熔断器。
  • 每个功能的 token 预算,防止任何单个功能消耗你的全部预配置吞吐量。

这与你在微服务架构中防止吵闹邻居所使用的模式相同。区别在于 LLM API 的速率限制通常是账户级别的,而不是按端点的,这使得在没有提供商合作或多个账户的情况下更难实现隔离。

非幂等性是默认行为

大多数 LLM API 调用默认是非幂等的。问同一个问题两次,得到两个不同的答案。这以一种微妙的方式破坏了重试逻辑:如果一个请求超时了你重试它,你可能得到一个完全不同的响应。如果第一个请求实际上在提供商那边成功了(你只是没有及时收到响应),你现在为两次补全付了费,并且需要决定使用哪一个。

对于每一步都依赖前一步的 agent 工作流,盲目重试可能是危险的。重试可能产生不同的计划、选择不同的工具或做出不同的断言——现在你的 agent 正试图调和两条分歧的执行路径。

有效的缓解措施:

  • 使用 seed 和 temperature 0,当你需要重试的确定性时。这不能保证重试间的输出完全相同,但能减少方差。
  • 应用层的幂等键:追踪每个请求属于哪个逻辑操作,如果你收到重复响应,丢弃它。
  • agent 的检查点与恢复:不要重试整个多步骤工作流,而是在每个成功步骤后设置检查点,在失败时从最后一个检查点恢复。

你的实战手册应该是什么样的

如果你今天在生产中运行 LLM API,以下是最小可行的韧性配置:

  1. 自适应超时,带有按操作的预算和截止时间传播。
  2. 三信号熔断器,覆盖错误、延迟和质量。
  3. 同提供商模型降级作为第一层级,跨提供商降级作为第二层级。
  4. 舱壁隔离独立功能免受彼此的爆炸半径。
  5. 采样流量上的质量监控,带有自动化回归检测。
  6. 提供商健康仪表板,追踪上述五个维度。

这些都不是高深的分布式系统理论。这与你对任何不可靠上游依赖应用的实战手册相同,只是针对 LLM API 的独特属性进行了调整:可变延迟、非幂等响应,以及使所有其他模式成为必要的静默故障模式。

做得好的团队不会将他们的 LLM 提供商视为需要全新基础设施的特殊、神奇的服务。他们将其视为它的本质——一个恰好比他们以前依赖的任何上游都更不稳定、更慢、更难监控的第三方 API——然后应用他们已经知道的模式,在旧假设失效的地方进行扩展。

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