一声棒喝,本不立文字
偏要著録,已是二义

Anthropic · 工程博客

近期 Claude Code 质量报告更新

An update on recent Claude Code quality reports

二〇二六年五月八日 · 英文原文

Anthropic调查Claude响应质量下降报告,确认API和inference layer未受影响;根因是Claude Code默认effort调整、stale sessions清除thinking history的bug、Opus 4.7 system prompt使部分eval下降3%。问题已在4月10日至20日修复,v2.1.116解决,并重置订阅用户使用限制。

在过去一个月里,我们一直在调查部分用户关于 Claude 响应质量变差的报告。我们将这些报告追溯到三个相互独立的变更,它们分别影响了 Claude Code、Claude Agent SDK 和 Claude Cowork。API 未受影响。

截至 4 月 20 日(v2.1.116),这三个问题都已解决。

在这篇文章中,我们会说明我们发现了什么、修复了什么,以及我们将采取哪些不同做法,以确保类似问题更不容易再次发生。

我们非常重视关于性能退化的报告。我们从不会有意降低模型质量,并且能够立即确认我们的 API 和 inference layer(推理层)未受影响。

经过调查,我们发现了三个不同的问题:

由于每个变更都在不同时间影响了不同的流量切片,整体效果看起来像是广泛且不一致的退化。虽然我们在 3 月初就开始调查相关报告,但一开始很难将它们与用户反馈中的正常波动区分开来,而且我们的内部使用和 evals(评测)最初也没有复现出已识别的问题。

这不是用户应当从 Claude Code 获得的体验。截至 4 月 23 日,我们将重置所有订阅用户的使用限制。

当我们在 2 月于 Claude Code 中发布 Opus 4.6 时,我们将默认 reasoning effort 设置为 high。

不久后,我们收到用户反馈称,Claude Opus 4.6 在 high effort 模式下偶尔会思考过久,导致 UI 看起来冻结,并给这些用户带来不成比例的 latency(延迟)和 token 使用量。

一般来说,模型思考得越久,输出越好。Effort levels 是 Claude Code 让用户设置这种权衡的方式——更多思考,还是更低 latency 和更少触达使用限制。我们在为模型校准 effort levels 时,会考虑这种权衡,以便在 test-time-compute 曲线上选择若干点,为用户提供最佳范围的选项。在产品层,我们随后选择这条曲线上的哪个点作为默认值,并将该值作为 effort 参数发送到 Messages API;然后通过 /effort 提供其他选项。

在我们的内部 evals 和测试中,对于大多数任务,medium effort 以显著更低的 latency 达到了略低的 intelligence。它也没有出现相同的、偶发的极长尾 thinking latency 问题,并且有助于最大化用户的使用限制。因此,我们推出了一个变更,将 medium 设为默认 effort,并通过产品内对话解释了理由。

推出后不久,用户开始报告 Claude Code 感觉不如以前聪明。我们发布了多轮设计迭代,让当前 effort 设置更清晰,以提醒用户可以更改默认值(启动时提示、行内 effort 选择器,以及恢复 ultrathink),但大多数用户仍保留 medium effort 默认值。

在听取更多客户反馈后,我们于 4 月 7 日撤销了这一决定。现在,所有用户在 Opus 4.7 上默认使用 xhigh effort,在所有其他模型上默认使用 high effort。

当 Claude 对一项任务进行 reasoning 时,这些 reasoning 通常会保留在 conversation history 中,这样在之后每一轮中,Claude 都能看到它为什么进行了那些编辑和 tool calls。

3 月 26 日,我们发布了一个本意是提升该功能效率的改动。我们使用 prompt caching,让连续的 API calls 对用户来说更便宜、更快。Claude 在发起 API request 时会将 input tokens 写入 cache;随后在一段不活跃时间后,prompt 会从 cache 中被逐出,为其他 prompts 腾出空间。Cache utilization 是我们谨慎管理的事项(关于我们的方法,后文会详细说明)。

设计本应很简单:如果一个 session 空闲超过一小时,我们可以通过清除旧的 thinking sections 来降低用户恢复该 session 的成本。由于该 request 无论如何都会是一次 cache miss,我们可以从 request 中裁剪不必要的 messages,以减少发送到 API 的 uncached tokens 数量。然后我们会恢复发送完整的 reasoning history。为此,我们使用了 clear_thinking_20251015 API header,并配合 keep:1。

实现中存在一个 bug。它不是只清除一次 thinking history,而是在该 session 之后的每一轮都清除。一个 session 一旦跨过 idle threshold,之后该 process 中的每个 request 都会告诉 API 只保留最近一个 reasoning block,并丢弃之前的所有内容。这个问题会不断叠加:如果你在 Claude 正在进行 tool use 时发送 follow-up message,这会在损坏的 flag 下开启新一轮,因此甚至当前轮的 reasoning 也会被丢弃。Claude 会继续执行,但越来越缺乏对自己为什么选择当前操作的记忆。这表现为用户报告的健忘、重复和异常的 tool 选择。

由于这会持续从后续 requests 中丢弃 thinking blocks,这些 requests 也会导致 cache misses。我们认为这正是用户另行报告使用限制消耗快于预期的原因。

两个无关实验让我们一开始很难复现该问题:一个是与 message queuing 相关的内部限定 server-side experiment;另一个是 thinking 展示方式的正交变更,它在大多数 CLI sessions 中抑制了这个 bug,因此即使测试外部 builds 时我们也没有发现它。

这个 bug 位于 Claude Code 的 context management、Anthropic API 和 extended thinking 的交叉处。它引入的变更通过了多轮人工和自动 code reviews,以及 unit tests、end-to-end tests、automated verification 和 dogfooding(内部试用)。再加上它只发生在一个边界场景(stale sessions)中,并且难以复现,我们花了一周多才发现并确认根因。

作为调查的一部分,我们使用 Opus 4.7 对有问题的 pull requests 进行了 Code Review 回测。当提供了获取完整 context 所需的代码仓库时,Opus 4.7 发现了该 bug,而 Opus 4.6 没有。为防止这种情况再次发生,我们现在正在为 code reviews 落地支持使用额外仓库作为 context。

我们已在 4 月 10 日的 v2.1.101 中修复了这个 bug。

我们的最新模型 Claude Opus 4.7 相比其前代有一个显著的行为特点:正如我们在发布时所写,它往往相当 verbose(冗长)。这让它在难题上更聪明,但也会产生更多 output tokens。

在发布 Opus 4.7 前几周,我们开始为此调优 Claude Code。每个模型的行为都略有不同,我们会在每次发布前花时间为它优化 harness 和产品。

我们有多种工具可用于降低 verbosity:model training、prompting,以及在产品中改进 thinking UX。最终这些方法我们都用了,但 system prompt 中新增的一项内容对 Claude Code 的 intelligence 产生了过大的影响:

经过数周内部测试,并且在我们运行的一组 evaluations 中没有出现 regressions 后,我们对该变更有了信心,并在 4 月 16 日随 Opus 4.7 一起发布。

作为本次调查的一部分,我们使用更广泛的一组 evaluations 运行了更多 ablations(通过移除 system prompt 中的行来理解每一行的影响)。其中一个 evaluation 显示,Opus 4.6 和 4.7 都下降了 3%。我们立即在 4 月 20 日的发布中回滚了该 prompt。

为避免这些问题,我们将采取几项不同做法:我们会确保更多内部员工使用与公开版本完全一致的 Claude Code build(而不是我们用于测试新功能的版本);我们还会改进内部使用的 Code Review tool,并将这个改进版本提供给客户。

我们也会对 system prompt 变更增加更严格的控制。对于 Claude Code 的每一次 system prompt 变更,我们都会运行一套广泛的、按模型区分的 evals,继续通过 ablations 理解每一行的影响,并且已经构建了新的 tooling,让 prompt 变更更易于 review 和 audit。此外,我们在 CLAUDE.md 中添加了指导,以确保 model-specific 变更被限制在其目标模型上。对于任何可能与 intelligence 形成权衡的变更,我们会增加 soak periods(观察期)、更广泛的 eval suite,以及渐进式 rollouts,以便更早发现问题。

我们最近在 X 上创建了 @ClaudeDevs,以便有空间深入解释产品决策及其背后的 reasoning。我们也会在 GitHub 的集中 threads 中分享相同更新。

最后,我们要感谢我们的用户:那些使用 /feedback command 向我们反馈问题的人(或是在网上发布具体、可复现示例的人),最终帮助我们识别并修复了这些问题。今天,我们将重置所有订阅用户的使用限制。

非常感谢你们的反馈与耐心。

译自 Anthropic · 工程博客 · 录于 二〇二六年五月八日