三个近期问题的事后复盘

0 阅读15分钟

三个近期问题的事后复盘(对原博客文章的翻译与学习)

原文链接: www.anthropic.com/engineering…

发布日期: 2025年9月17日

这是一份关于三个导致 Claude 响应间歇性降级的 Bug 的技术报告。下面我们将解释发生了什么、为什么修复需要时间,以及我们正在做出哪些改变。


在 8 月到 9 月初期间,三个基础设施 Bug 间歇性地降低了 Claude 的响应质量。我们现已解决这些问题,并希望解释发生了什么。

8 月初,一些用户开始报告 Claude 的响应质量下降。这些最初的报告很难与用户反馈的正常波动区分开来。到 8 月下旬,这些报告的频率和持续性不断增加,促使我们启动了一项调查,最终发现了三个独立的基础设施 Bug。

直言不讳地说:我们从不会因为需求量、一天中的时间或服务器负载而降低模型质量。用户报告的问题完全是由基础设施 Bug 造成的。

我们认识到用户期望 Claude 保持一致的质量,我们对确保基础设施变更不影响模型输出保持着极高的标准。在这些最近的事件中,我们没有达到这个标准。以下的事后复盘解释了出了什么问题、为什么检测和解决花费的时间比我们希望的更长,以及我们正在做出哪些改变来防止类似的未来事件。

我们通常不会分享这种程度的基础设施技术细节,但这些问题的范围和复杂性使得更全面的解释变得必要。


我们如何大规模服务 Claude

我们通过第一方 API、Amazon Bedrock 和 Google Cloud 的 Vertex AI 向数百万用户提供 Claude 服务。我们在多个硬件平台上部署 Claude,包括 AWS Trainium、NVIDIA GPU 和 Google TPU。这种方法提供了为全球用户提供服务所需的容量和地理分布。

每个硬件平台都有不同的特性,需要特定的优化。尽管存在这些差异,我们对模型实现有严格的等价性标准。我们的目标是,无论用户的请求由哪个平台提供服务,他们都应该获得相同质量的响应。这种复杂性意味着任何基础设施变更都需要在所有平台和配置上进行仔细验证。

💡 Claude 多平台服务架构

graph TD
    Users((用户)) --> API[第一方 API]
    Users --> Bedrock[Amazon Bedrock]
    Users --> Vertex[Google Vertex AI]
    
    API --> Trainium[AWS Trainium]
    API --> GPU[NVIDIA GPU]
    API --> TPU[Google TPU]
    
    Bedrock --> Trainium
    Vertex --> TPU
    
    subgraph 硬件平台
        Trainium
        GPU
        TPU
    end
    
    subgraph 服务渠道
        API
        Bedrock
        Vertex
    end

事件时间线

postmortem-timeline.png

Claude API 上的事件说明性时间线。黄色:检测到问题,红色:降级恶化,绿色:修复已部署。

这些 Bug 的重叠性质使得诊断特别具有挑战性。第一个 Bug 于 8 月 5 日引入,影响了约 0.8% 的 Sonnet 4 请求。另外两个 Bug 分别来自 8 月 25 日和 26 日的部署。

虽然最初的影响有限,但 8 月 29 日的负载均衡变更开始增加受影响的流量。这导致更多用户遇到问题,而其他人继续看到正常性能,产生了令人困惑且相互矛盾的报告。

💡 事件时间线总览

日期事件影响
8月5日Bug 1 引入(上下文窗口路由错误)0.8% Sonnet 4 请求受影响
8月25日Bug 2 引入(输出损坏)TPU 服务器 token 生成错误
8月26日Bug 3 引入(近似 top-k 编译错误)Haiku 3.5 确认受影响
8月29日负载均衡变更受影响流量增加
8月31日最严重时刻16% Sonnet 4 请求被错误路由
9月2日Bug 2 修复回滚变更
9月4日Bug 1 和 Bug 3 部分修复修复路由逻辑,回滚 Haiku 3.5
9月12日Bug 3 进一步修复回滚 Opus 3
9月16-18日全面修复完成所有平台修复部署完成

三个重叠的问题

下面我们描述导致降级的三个 Bug、它们发生的时间以及我们如何解决它们:

1. 上下文窗口路由错误

8 月 5 日,一些 Sonnet 4 请求被错误地路由到为即将推出的 1M token 上下文窗口配置的服务器。这个 Bug 最初影响了 0.8% 的请求。8 月 29 日,一次常规的负载均衡变更无意中增加了被路由到 1M 上下文服务器的短上下文请求数量。在 8 月 31 日最严重的一个小时内,16% 的 Sonnet 4 请求受到影响。

在此期间发出请求的 Claude Code 用户中,约 30% 至少有一条消息被路由到错误的服务器类型,导致响应降级。在 Amazon Bedrock 上,从 8 月 12 日开始,错误路由的流量峰值达到所有 Sonnet 4 请求的 0.18%。在 8 月 27 日至 9 月 16 日期间,错误路由影响了 Google Cloud Vertex AI 上不到 0.0004% 的请求。

然而,一些用户受到的影响更为严重,因为我们的路由是"粘性"的。这意味着一旦请求由错误的服务器提供服务,后续的跟进请求很可能由同一个错误的服务器提供服务。

解决方案: 我们修复了路由逻辑,确保短上下文和长上下文请求被导向正确的服务器池。我们于 9 月 4 日部署了修复。向我们的第一方平台和 Google Cloud Vertex AI 的推出于 9 月 16 日完成,向 AWS Bedrock 的推出于 9 月 18 日完成。

💡 上下文窗口路由问题示意

graph TD
    subgraph 正常流程
        A1[短上下文请求] -->|正确路由| B1[短上下文服务器]
        A2[长上下文请求] -->|正确路由| B2[1M 上下文服务器]
    end
    
    subgraph 错误流程
        A3[短上下文请求] -->|错误路由| B3[1M 上下文服务器]
        B3 -->|粘性路由| C3[后续请求继续错误路由]
        C3 -->|响应降级| D3[用户体验下降]
    end

2. 输出损坏

8 月 25 日,我们向 Claude API TPU 服务器部署了一个错误配置,导致 token 生成期间出现错误。一个由运行时性能优化引起的问题偶尔会给在给定上下文中应该很少产生的 token 分配高概率,例如在回复英语提示时产生泰语或中文字符,或在代码中产生明显的语法错误。用英语提问的一小部分用户可能会在响应中间看到"สวัสดี"(泰语的"你好")。

这种损坏影响了 8 月 25-28 日对 Opus 4.1 和 Opus 4 的请求,以及 8 月 25 日至 9 月 2 日对 Sonnet 4 的请求。第三方平台不受此问题影响。

解决方案: 我们识别了问题并于 9 月 2 日回滚了变更。我们已在部署流程中添加了对意外字符输出的检测测试。

💡 输出损坏影响范围

模型受影响时间平台
Opus 4.18月25-28日Claude API
Opus 48月25-28日Claude API
Sonnet 48月25日-9月2日Claude API
第三方平台不受影响Bedrock/Vertex AI

3. 近似 top-k XLA:TPU 编译错误

8 月 25 日,我们部署了代码来改进 Claude 在文本生成期间选择 token 的方式。这个变更无意中触发了 XLA:TPU1 编译器中的一个潜在 Bug,已确认影响了 Claude Haiku 3.5 的请求。

我们还认为这可能影响了 Claude API 上的部分 Sonnet 4 和 Opus 3。第三方平台不受此问题影响。

解决方案: 我们首先观察到该 Bug 影响了 Haiku 3.5,并于 9 月 4 日回滚了它。我们后来注意到用户报告的 Opus 3 问题与此 Bug 相符,并于 9 月 12 日回滚了它。经过广泛调查,我们无法在 Sonnet 4 上重现此 Bug,但出于谨慎考虑决定也将其回滚。

同时,我们已经(a)与 XLA:TPU 团队合作修复编译器 Bug,(b)推出了使用具有增强精度的精确 top-k 的修复。有关详细信息,请参阅下面的深入探讨。


深入了解 XLA 编译器 Bug

为了说明这些问题的复杂性,这里介绍 XLA 编译器 Bug 是如何表现的,以及为什么它特别难以诊断。

当 Claude 生成文本时,它会计算每个可能的下一个词的概率,然后从这个概率分布中随机选择一个样本。我们使用"top-p 采样"来避免无意义的输出——只考虑累积概率达到阈值(通常为 0.99 或 0.999)的词。在 TPU 上,我们的模型运行在多个芯片上,概率计算发生在不同的位置。要对这些概率进行排序,我们需要协调芯片之间的数据,这是很复杂的。2

2024 年 12 月,我们发现当 temperature 为零时,我们的 TPU 实现偶尔会丢弃最高概率的 token。我们部署了一个变通方案来修复这种情况。

postmortem-december-patch.png

2024 年 12 月补丁的代码片段,用于解决 temperature = 0 时意外丢弃 token 的 Bug。

根本原因涉及混合精度算术。我们的模型使用 bf16(16 位浮点数)计算下一个 token 的概率。然而,向量处理器是 fp32 原生的,因此 TPU 编译器(XLA)可以通过将某些操作转换为 fp32(32 位)来优化运行时。这个优化过程由 xla_allow_excess_precision 标志控制,默认为 true。

这导致了不匹配:应该就最高概率 token 达成一致的操作以不同的精度级别运行。精度不匹配意味着它们无法就哪个 token 具有最高概率达成一致。这导致最高概率的 token 有时完全从考虑中消失。

8 月 26 日,我们部署了对采样代码的重写,以修复精度问题并改进我们处理达到 top-p 阈值限制的概率的方式。但在修复这些问题时,我们暴露了一个更棘手的问题。

postmortem-august-reproducer.png

代码片段显示了作为 8 月 11 日变更的一部分合并的简化复现器,该复现器确定了 2024 年 12 月修复的"Bug"的根本原因。实际上,这是 xla_allow_excess_precision 标志的预期行为。

我们的修复移除了 12 月的变通方案,因为我们认为已经解决了根本原因。这导致了 近似 top-k 操作中更深层的 Bug——这是一种快速找到最高概率 token 的性能优化。3 这种近似有时会返回完全错误的结果,但只针对某些批量大小和模型配置。12 月的变通方案一直无意中掩盖了这个问题。

postmortem-slack-reproducer.png

开发该算法的 XLA:TPU 工程师分享的底层近似 top-k Bug 的复现器。该代码在 CPU 上运行时返回正确结果。

这个 Bug 的行为令人沮丧地不一致。它会根据不相关的因素(如之前或之后运行的操作,以及是否启用了调试工具)而改变。同一个提示在一个请求上可能完美工作,而在下一个请求上失败。

在调查过程中,我们还发现精确 top-k 操作不再像以前那样有禁止性的性能损失。我们从近似 top-k 切换到精确 top-k,并将一些额外的操作标准化为 fp32 精度。4 模型质量是不可妥协的,所以我们接受了轻微的效率影响。

💡 XLA 编译器 Bug 诊断流程

graph TD
    A[2024年12月发现问题] --> B[temperature=0 时丢弃最高概率 token]
    B --> C[部署变通方案]
    
    C --> D[2025年8月重写采样代码]
    D --> E[移除12月变通方案]
    E --> F[暴露近似 top-k 深层 Bug]
    
    F --> G{诊断困难}
    G --> H[Bug 行为不一致]
    G --> I[依赖不相关因素]
    G --> J[调试工具影响结果]
    
    H --> K[最终解决方案]
    I --> K
    J --> K
    
    K --> L[切换到精确 top-k]
    K --> M[标准化 fp32 精度]
    K --> N[与 XLA:TPU 团队合作修复编译器]

💡 精度问题对比

方面bf16(16位)fp32(32位)
精度较低较高
性能较快较慢
用途概率计算向量处理器原生
问题精度不匹配导致 token 排序不一致-

为什么检测困难

我们的验证过程通常依赖于基准测试以及安全评估和性能指标。工程团队执行抽查,并首先部署到小型"金丝雀"组。

这些问题暴露了我们本应更早发现的关键缺口。我们运行的评估根本没有捕捉到用户报告的降级,部分原因是 Claude 通常能很好地从孤立的错误中恢复。我们自己的隐私实践也给调查报告带来了挑战。我们的内部隐私和安全控制限制了工程师何时以及如何访问用户与 Claude 的交互,特别是当这些交互没有作为反馈报告给我们时。这保护了用户隐私,但阻止了工程师检查识别或重现 Bug 所需的问题交互。

每个 Bug 在不同平台上以不同速率产生不同的症状。这创造了一种令人困惑的报告混合,没有指向任何单一原因。它看起来像是随机的、不一致的降级。

更根本的是,我们过于依赖嘈杂的评估。虽然我们知道网上报告有所增加,但我们缺乏一种清晰的方式将这些与我们最近的每个变更联系起来。当 8 月 29 日负面报告激增时,我们没有立即将其与一个原本标准的负载均衡变更联系起来。

💡 检测困难的原因分析

graph TD
    Root((检测困难)) --> A[评估局限性]
    Root --> B[隐私限制]
    Root --> C[症状混乱]
    Root --> D[依赖嘈杂评估]
    
    A --> A1[评估未捕捉到用户报告的降级]
    A --> A2[Claude 能从孤立错误中恢复]
    
    B --> B1[工程师无法访问用户交互]
    B --> B2[无法检查问题交互]
    
    C --> C1[不同平台不同症状]
    C --> C2[不同速率]
    C --> C3[看起来像随机降级]
    
    D --> D1[无法关联报告和变更]
    D --> D2[负载均衡变更未被怀疑]

我们正在做出的改变

在我们继续改进基础设施的同时,我们也在改进我们在所有提供 Claude 服务的平台上评估和预防上述 Bug 的方式。以下是我们正在做出的改变:

  • 更敏感的评估: 为了帮助发现任何给定问题的根本原因,我们开发了能够更可靠地区分工作和损坏实现的评估。我们将继续改进这些评估,以更密切地关注模型质量。

  • 更多地方的质量评估: 虽然我们在系统上运行定期评估,但我们将在真正的生产系统上持续运行它们,以捕获诸如上下文窗口负载均衡错误等问题。

  • 更快的调试工具: 我们将开发基础设施和工具,以更好地调试社区来源的反馈,同时不牺牲用户隐私。此外,这里开发的一些定制工具将用于在未来类似事件发生时减少修复时间。

💡 改进措施总结

改进领域具体措施目标
评估敏感度开发更可靠的评估方法区分工作和损坏实现
评估覆盖在生产系统上持续运行捕获负载均衡等问题
调试工具开发新的基础设施和工具更快调试社区反馈
隐私平衡在不牺牲隐私的前提下调试保护用户同时解决问题

评估和监控很重要。但这些事件表明,当 Claude 的响应不符合通常标准时,我们也需要来自用户的持续信号。观察到的具体变化报告、遇到的意外行为示例以及不同用例之间的模式都帮助我们隔离了问题。

用户继续直接向我们发送反馈仍然特别有帮助。您可以在 Claude Code 中使用 /bug 命令,或者在 Claude 应用程序中使用"向下拇指"按钮来发送反馈。开发人员和研究人员经常创建新的有趣方式来评估模型质量,补充我们的内部测试。如果您想分享您的方法,请联系 feedback@anthropic.com

我们对社区的这些贡献深表感谢。


📝 总结

核心要点

  1. 问题根源:2025年8月至9月,三个独立的基础设施 Bug 导致 Claude 响应质量间歇性下降,这些问题完全是技术性的,与需求量或服务器负载无关

  2. 三个重叠 Bug

    • 上下文窗口路由错误:短上下文请求被错误路由到 1M 上下文服务器
    • 输出损坏:TPU 服务器配置错误导致异常 token 生成
    • XLA:TPU 编译器 Bug:触发了编译器中的潜在问题
  3. 检测困难:评估未能捕捉降级、隐私限制阻碍调查、症状在不同平台表现不同

  4. 改进方向:更敏感的评估、生产系统持续监控、更快的调试工具、重视用户反馈

  5. 关键教训:模型质量是不可妥协的,即使以轻微的效率损失为代价


脚注


原文作者: Sam McAllister(感谢 Stuart Ritchie、Jonathan Gray、Kashyap Murali、Brennan Saeta、Oliver Rausch、Alex Palcuie 等许多人的帮助)

Footnotes

  1. XLA:TPU 是将 XLA 高级优化语言(通常使用 JAX 编写)翻译为 TPU 机器指令的优化编译器。

  2. 我们的模型太大,无法放在单个芯片上,被分区到数十个或更多芯片上,使我们的排序操作成为分布式排序。TPU(就像 GPU 和 Trainium 一样)也具有与 CPU 不同的性能特性,需要使用向量化操作而不是串行算法的不同实现技术。

  3. 我们一直使用这种近似操作,因为它带来了显著的性能改进。这种近似通过接受最低概率 token 的潜在不准确性来工作,这不应该影响质量——除非 Bug 导致它丢弃最高概率的 token。

  4. 请注意,现在正确的 top-k 实现可能会导致在 top-p 阈值附近包含 token 的轻微差异,在极少数情况下,用户可能会受益于重新调整他们对 top-p 的选择。