关于近期 Claude Code 质量报告的更新
在过去一个月里,我们一直在调查有关 Claude 对部分用户响应质量下降的报告。我们已将这些报告追溯到三项独立的变更,它们分别影响了 Claude Code、Claude Agent SDK 和 Claude Cowork。API 未受影响。
这三个问题均已于 4 月 20 日(v2.1.116)修复。
在本文中,我们将说明我们的发现、修复内容,以及我们将如何改进,以确保类似问题再次发生的可能性大大降低。
我们非常重视关于质量下降的报告。我们从不故意降低模型质量,并且能够立即确认我们的 API 和推理层未受影响。
经过调查,我们发现了三个不同的问题:
- 3 月 4 日,我们将 Claude Code 的默认推理力度从
high改为medium,以减少部分用户在high模式下遇到的极长延迟——长到足以让界面看起来像是卡死了。这是一个错误的权衡。在用户告诉我们他们更倾向于默认使用更高智能、并在简单任务时选择较低力度后,我们于 4 月 7 日回滚了这一变更。此变更影响了 Sonnet 4.6 和 Opus 4.6。 - 3 月 26 日,我们发布了一项变更,用于清除已闲置超过一小时的会话中 Claude 较早的思考内容,以减少用户恢复这些会话时的延迟。一个 bug 导致该操作在会话的后续每一轮中持续发生,而不是仅发生一次,这使得 Claude 显得健忘且重复。我们于 4 月 10 日修复了此问题。此问题影响了 Sonnet 4.6 和 Opus 4.6。
- 4 月 16 日,我们添加了一条系统提示指令以减少冗余。该指令与其他提示变更叠加后,损害了编码质量,并于 4 月 20 日回滚。此变更影响了 Sonnet 4.6、Opus 4.6 和 Opus 4.7。
由于每项变更影响的流量范围不同、时间安排也不同,其综合效果看起来像是广泛且不一致的质量下降。虽然我们在 3 月初就开始调查这些报告,但起初它们难以与用户反馈的正常波动区分开来,而且我们最初的内部使用和评估也未能复现所发现的问题。
这不是用户应从 Claude Code 获得的体验。截至 4 月 23 日,我们正在为所有订阅用户重置使用限额。
Claude Code 默认推理力度的变更
2 月我们在 Claude Code 中发布 Opus 4.6 时,将默认推理力度设置为 high。
不久之后,我们收到用户反馈,称 Claude Opus 4.6 在高力度模式下偶尔会思考过久,导致界面看起来像是卡死,并给这些用户带来不成比例的延迟和 token 消耗。
通常,模型思考时间越长,输出质量越好。力度级别是 Claude Code 让用户设定这种权衡的方式——更多思考,还是更低延迟以及更少的使用限额消耗。在为我们的模型校准力度级别时,我们会考虑这种权衡,以便在测试时计算曲线上选择能为人们提供最佳选项范围的点。在产品层面,我们再选择该曲线上的哪个点作为默认值,这就是我们作为 effort 参数发送给 Messages API 的值;随后我们通过 /effort 提供其他选项。
在我们的内部评估和测试中,对于大多数任务,中等努力程度(medium effort)在智能表现上略有下降,但延迟显著降低。它也没有出现思考时偶尔出现的超长尾延迟问题,并且有助于最大化用户的使用限额。因此,我们推出了一项更改,将中等设为默认努力程度,并通过产品内对话框解释了这一理由。
推出后不久,用户开始反馈 Claude Code 感觉不够智能。我们推出了一系列设计迭代,以使当前的努力程度设置更加清晰,从而提醒用户他们可以更改默认值(启动时的提示、内联的努力程度选择器,以及恢复 ultrathink),但大多数用户仍保留了中等努力程度的默认设置。
在听取更多客户的反馈后,我们于 4 月 7 日推翻了这一决定。现在所有用户对 Opus 4.7 默认使用 xhigh 努力程度,对所有其他模型默认使用 high 努力程度。
一项丢弃先前推理的缓存优化
当 Claude 对任务进行推理时,该推理通常会保留在对话历史中,以便在随后的每一轮中,Claude 都能看到它为何做出这些编辑和工具调用。
3 月 26 日,我们发布了一项本意是针对该功能的效率改进。我们使用提示缓存(prompt caching)来为用户降低连续 API 调用的成本并提高速度。Claude 在发出 API 请求时会将输入令牌写入缓存,经过一段时间的不活动后,提示会从缓存中被逐出,为其他提示腾出空间。缓存利用率是我们精心管理的事项(更多关于我们的 方法)。
该设计本应很简单:如果一个会话空闲超过一小时,我们可以通过清除旧的思考部分来降低用户恢复该会话的成本。由于该请求无论如何都会缓存未命中(cache miss),我们可以从请求中修剪不必要的消息,以减少发送到 API 的未缓存令牌数量。然后我们将恢复发送完整的推理历史。为此,我们使用了 clear_thinking_20251015 API 标头以及 keep:1。
该实现存在一个 bug。它没有一次性清除思考历史,而是在会话的剩余时间里每一轮都清除它。一旦会话超过一次空闲阈值,该进程剩余时间的每个请求都会告诉 API 仅保留最近的推理块并丢弃之前的所有内容。这会产生复合效应:如果你在 Claude 正在使用工具的过程中发送后续消息,那会在该损坏的标志下开始一个新轮次,因此连当前轮次的推理也被丢弃了。Claude 会继续执行,但越来越不记得自己为何选择做正在做的事情。这表现为人们报告的健忘、重复和奇怪的工具选择。
由于这会持续地从后续请求中丢弃思考块,这些请求也因此导致了缓存未命中。我们认为这就是导致使用限额消耗快于预期的单独报告的原因。
两个不相关的实验最初让我们难以复现该问题:一个与消息队列相关的仅限内部的服务器端实验;以及一个关于思考显示方式的正交更改,该更改在大多数 CLI 会话中掩盖了此 bug,因此即使在测试外部构建时我们也没有发现它。
这个 bug 位于 Claude Code 的上下文管理、Anthropic API 和扩展思考(extended thinking)的交汇处。它引入的改动通过了多轮人工和自动化代码审查,以及单元测试、端到端测试、自动化验证和自用测试(dogfooding)。加上这只发生在边缘情况(过期会话)中,且问题难以复现,我们花了一周多的时间才发现并确认根本原因。
作为调查的一部分,我们使用 Opus 4.7 对 Code Review 进行了回溯测试,将其应用于有问题的拉取请求。当提供了收集完整上下文所需的代码仓库时,Opus 4.7 找到了这个 bug,而 Opus 4.6 没有。为防止此类情况再次发生,我们现在正在上线对额外仓库作为代码审查上下文的支持。
我们于 4 月 10 日在 v2.1.101 中修复了这个 bug。
一次减少冗余的系统提示词改动
我们最新的模型 Claude Opus 4.7 相比前代有一个明显的行为特点:正如我们在发布时 所写 的,它相当啰嗦。这使它在难题上更聪明,但也产生了更多的输出 token。
在发布 Opus 4.7 前几周,我们就开始为 Claude Code 做调优准备。每个模型的行为都略有不同,我们会在每次发布前花时间针对它优化运行框架和产品。
我们有多种工具来减少冗余:模型训练、提示词以及改进产品中的思考体验。最终我们全都用上了,但对系统提示词的一处改动对 Claude Code 的智能表现产生了超乎寻常的影响:
“长度限制:工具调用之间的文本保持在 ≤25 个词以内。除非任务需要更多细节,否则最终回复保持在 ≤100 个词以内。”
经过数周的内部测试,并且我们运行的评估集没有出现回归,我们对这一改动充满信心,并于 4 月 16 日将其与 Opus 4.7 一同发布。
作为此次调查的一部分,我们使用更广泛的评估集运行了更多消融实验(从系统提示中移除各行,以了解每行的影响)。其中一项评估显示,Opus 4.6 和 4.7 均下降了 3%。我们作为 4 月 20 日发布的一部分,立即回滚了该提示。
展望未来
我们将采取几项不同的措施来避免这些问题:我们将确保更大比例的内部员工使用 Claude Code 的确切公开版本(而不是我们用于测试新功能的版本);并且我们将改进内部使用的 Code Review 工具,并将此改进版本发布给客户。
我们还在对系统提示的更改加强控制。我们将针对 Claude Code 的每一次系统提示更改运行广泛的按模型评估套件,继续进行消融实验以了解每行的影响,并且我们已构建新工具以使提示更改更易于审查和审计。我们还在 CLAUDE.md 中添加了指导,以确保特定于模型的更改被限制在其针对的特定模型上。对于任何可能与智能性产生权衡的更改,我们将添加稳定期、更广泛的评估套件和逐步推出,以便我们更早地发现问题。
我们最近在 X 上创建了 @ClaudeDevs,以便为我们提供空间来深入解释产品决策及其背后的推理。我们将在 GitHub 的集中讨论串中分享相同的更新。
最后,我们要感谢我们的用户:那些使用 /feedback 命令与我们分享问题的人(或在网上发布具体、可复现示例的人),正是他们最终让我们得以识别并修复这些问题。今天,我们将为所有订阅者重置使用限额。
我们对您的反馈和耐心深表感谢。