关于近期 Claude Code 质量反馈的复盘
我们把近期关于 Claude Code 质量问题的反馈,追溯到了三处各自独立的改动。下面说明发生了什么,以及我们正在做出哪些调整。
过去一个月里,我们一直在排查"Claude 的回复对某些用户来说变差了"这类反馈。我们把这些反馈追溯到了三处各自独立的改动,它们分别影响了 Claude Code、Claude Agent SDK 和 Claude Cowork。API 未受影响。
截至 4 月 20 日(v2.1.116),这三个问题现已全部解决。
在这篇文章里,我们解释了我们发现了什么、修复了什么,以及我们今后将做出哪些不同的改变,以确保类似问题再次发生的可能性大大降低。
我们非常严肃地对待有关质量下降的反馈。我们绝不会有意降低模型的表现,而且我们能够立即确认:我们的 API 和推理层未受影响。
经过调查,我们识别出三个不同的问题:
- 3 月 4 日,我们把 Claude Code 的默认推理强度(reasoning effort)从 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 月初就开始调查这些反馈,但起初它们很难与用户反馈中的正常波动区分开来,而且无论是我们的内部使用还是评测(eval),最初都没能复现所识别出的这些问题。
这并不是用户应当从 Claude Code 那里得到的体验。自 4 月 23 日起,我们为所有订阅用户重置使用额度(usage limits)。
一处对 Claude Code 默认推理强度的改动
我们在 2 月把 Opus 4.6 引入 Claude Code 时,把默认推理强度设为了 high。
不久之后,我们收到用户反馈:处于 high 强度模式的 Claude Opus 4.6 偶尔会思考太久,导致界面看起来像卡死了,并给这部分用户带来不成比例的延迟和 token 消耗。
一般来说,模型思考得越久,输出就越好。"强度等级(effort level)"正是 Claude Code 让用户设定这一取舍的方式——更多思考,对换更低延迟、更少触及使用额度上限。在为我们的模型校准强度等级时,我们会把这个取舍考虑进去,从而在"测试时算力(test-time-compute)"曲线上选取一些能给人们提供最佳选项区间的点位。在产品层,我们再选择把这条曲线上的哪个点设为默认值,那也就是我们以 effort 参数形式发往 Messages API 的值;其余选项则通过 /effort 提供出来。
在我们的内部评测和测试中,medium 强度对大多数任务而言,智能略有下降、但延迟显著减少。它也不会像 high 那样偶尔出现思考的超长尾延迟问题,还有助于把用户的使用额度利用最大化。因此,我们推出了把 medium 设为默认强度的改动,并通过产品内的弹窗解释了缘由。
推出后不久,用户开始反馈 Claude Code 感觉变笨了。为了提醒人们可以更改默认值,我们发布了若干设计迭代,让当前强度设置更清晰可见(启动时的提示、内联的强度选择器,以及把 ultrathink 找了回来),但大多数用户仍然保留了 medium 这个默认强度。
在听取了更多客户的反馈后,我们于 4 月 7 日推翻了这个决定。现在所有用户对 Opus 4.7 默认采用 xhigh 强度,对其他所有模型默认采用 high 强度。
一项丢弃了既有推理内容的缓存优化
当 Claude 推理一项任务时,那段推理通常会被保留在对话历史里,这样在后续的每一轮,Claude 都能看到自己当初为什么做出那些编辑和工具调用。
3 月 26 日,我们发布了一项本意是要改进这一机制效率的改动。我们使用提示词缓存(prompt caching)来让连续的 API 调用对用户更便宜、更快。Claude 在发起 API 请求时会把输入 token 写入缓存,随后在一段不活跃期之后,该提示词会被从缓存中逐出,给其他提示词腾出空间。缓存利用率是我们会精心管理的东西(更多关于我们做法的说明)。
这个设计本该很简单:如果一个会话已经闲置超过一小时,我们就可以通过清除旧的思考片段,来降低用户恢复该会话的成本。既然这个请求反正都会是一次缓存未命中(cache miss),那我们就可以从请求中剪掉不必要的消息,以减少发往 API 的未缓存 token 数量。之后,我们会恢复发送完整的推理历史。为实现这一点,我们使用了 clear_thinking_20251015 这个 API 请求头,并配合 keep:1。
这个实现里有一个 bug。它并没有把思考历史清除一次,而是在该会话余下的过程中每一轮都清除。一旦某个会话越过了那条闲置阈值,在该进程余下的过程中,每一个请求都会告诉 API 只保留最近的那一块推理、并丢弃在它之前的一切。这会层层叠加:如果你在 Claude 正处于一次工具使用过程中时发去一条追问消息,那就会在这个出错的标志位下开启新的一轮,于是连当前这一轮的推理也被丢掉了。Claude 会继续执行,但越来越想不起自己当初为什么要那么做。这表现出来,就是人们反馈的健忘、重复和奇怪的工具选择。
因为这会持续地从后续请求中丢弃思考块,那些请求也就同样导致了缓存未命中。我们认为,这正是另外那批"使用额度耗尽得比预期更快"反馈背后的原因。
两个不相干的实验,让我们起初很难复现这个问题:一个是仅限内部、与消息排队(message queuing)相关的服务端实验;另一个是一处正交的、关于我们如何展示思考内容的改动,它在大多数 CLI 会话中把这个 bug 掩盖了,以致我们即便在测试外部构建版本时也没能逮到它。
这个 bug 处在 Claude Code 上下文管理、Anthropic API 与扩展思考(extended thinking)三者的交叉地带。它所引入的改动,闯过了多轮人工和自动代码评审,也闯过了单元测试、端到端测试、自动化验证和内部试用(dogfooding)。再加上这只在一种边角情形(陈旧会话)下发生、以及问题本身难以复现,我们花了一个多星期才发现并确认了根因。
作为调查的一部分,我们用 Opus 4.7 对那几个出问题的 pull request 回测了 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 以做准备。每个模型的行为都略有不同,我们会在每次发布前花时间为它优化 harness 和产品。
我们有若干工具可用来压缩冗长度:模型训练、提示词,以及在产品中改进思考的交互体验(UX)。最终我们把这些都用上了,但系统提示词里的一处新增内容,对 Claude Code 的智能造成了不成比例的影响:
"长度限制:把工具调用之间的文字控制在 ≤25 个词。把最终回复控制在 ≤100 个词,除非任务需要更多细节。"
在经过数周的内部测试、且我们所跑的那套评测中没有出现任何回退之后,我们对这处改动有了信心,并在 4 月 16 日随 Opus 4.7 一同发布了它。
作为这次调查的一部分,我们用一套更广的评测,跑了更多消融实验(ablation,即从系统提示词中逐行删除内容,以理解每一行的影响)。其中一项评测显示,Opus 4.6 和 4.7 都出现了 3% 的下降。我们随即在 4 月 20 日的发布中撤销了这条提示词。
今后的做法
为避免这些问题,我们将做出几项不同的安排:我们会确保更大比例的内部员工使用与公开版完全一致的 Claude Code 构建(而非我们用来测试新功能的那个版本);我们也会改进我们内部使用的 Code Review 工具,并把这个改进后的版本交付给客户。
我们还将对系统提示词改动加上更严格的管控。对 Claude Code 的每一次系统提示词改动,我们都会跑一整套分模型的评测,持续做消融实验以理解每一行的影响;我们也已构建了新的工具,让提示词改动更便于评审和审计。此外,我们在 CLAUDE.md 中补充了指引,以确保针对特定模型的改动被限定(gated)在它所针对的那个具体模型上。对于任何可能以牺牲智能为代价的改动,我们都会加上浸泡期(soak period)、更广的评测套件和渐进式推出(gradual rollout),以便更早地发现问题。
我们最近在 X 上创建了 @ClaudeDevs 账号,好让我们有空间去深入解释产品决策及其背后的考量。我们也会在 GitHub 上以集中式的话题帖(thread)分享同样的更新。
最后,我们要感谢我们的用户:那些使用 /feedback 命令向我们反馈问题的人(以及那些在网上贴出具体、可复现示例的人),正是他们最终让我们得以定位并修复这些问题。今天,我们为所有订阅用户重置使用额度。
我们对你们的反馈和耐心,致以无比的感激。