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 日 | 对闲置超 1 小时的会话清理旧的思考内容(为降低恢复时的延迟) | 一个 bug 导致它之后每轮都清,Claude 显得健忘、重复,4 月 10 日修复 | Sonnet 4.6、Opus 4.6 |
| 4 月 16 日 | 加了一条「控制冗长」的系统提示 | 叠加其他 prompt 改动后伤了编码质量,4 月 20 日回滚 | Sonnet 4.6、Opus 4.6、Opus 4.7 |
因为每个改动在不同时间命中不同的流量切片,合起来看就像是广泛、不一致的退化。我们 3 月初就开始查,但起初很难和正常的反馈波动区分,内部使用和 evals 一开始也复现不出。
这不是用户该从 Claude Code 得到的体验。4 月 23 日起,我们为所有订阅用户重置用量额度。
一、默认 reasoning effort 的改动
我们 2 月在 Claude Code 里发布 Opus 4.6 时,默认 effort 设为 high。很快收到反馈:Opus 4.6 在 high 模式下偶尔想太久,界面像卡死,给这些用户带来不成比例的延迟和 token 消耗。
一般来说模型想得越久,输出越好。effort 等级正是 Claude Code 给用户设定这个权衡的方式——更多思考 vs 更低延迟、更少触顶用量。在内部 evals 里,medium 对多数任务只略降智能、却显著降延迟,也没有偶发的超长思考尾延迟,还能让用户额度更耐用。于是我们把默认改成 medium,并用产品内对话框解释了理由。
但改完没多久,用户就反馈 Claude Code「变笨了」。我们做了一堆设计迭代来提示用户「可以改默认」(启动提示、内联 effort 选择器、找回 ultrathink),但多数用户还是保留了 medium 默认值。听取更多客户反馈后,4 月 7 日我们逆转了这个决定:Opus 4.7 默认 xhigh,其余模型默认 high。
二、一个丢掉了「先前思考」的缓存优化
Claude 推理一个任务时,那段思考通常会留在对话历史里,好让它在后续每一轮都能看见「自己当初为什么这么改、为什么这么调工具」。
3 月 26 日我们上线了一个本意是提效的改动。我们用 prompt caching 让连续的 API 调用更便宜更快;一段时间不活动后,prompt 会被逐出缓存。设计本该很简单:会话闲置超 1 小时,就在恢复时清掉旧的思考段(反正这次请求本来就是 cache miss,顺便剪掉没必要的消息、减少发往 API 的未缓存 token),之后恢复发送完整推理历史。为此用了 clear_thinking_20251015 头加 keep:1。
实现有 bug:它没有「只清一次」,而是在会话剩下的每一轮都清。一旦会话越过闲置阈值,之后每个请求都告诉 API「只保留最近一块推理、丢掉之前全部」。它还会累积恶化:如果你在 Claude 正用着工具时追发一条消息,会在坏掉的标志下开启新一轮,连当前这轮的推理也被丢掉。Claude 会继续执行,却越来越不记得自己当初为什么要这么做——这就表现为用户报告的健忘、重复、奇怪的工具选择。
因为它持续丢弃后续请求的思考块,这些请求也都变成 cache miss——我们认为这正是「用量额度比预期掉得快」那批反馈的根源。
两个不相关的实验让我们起初复现不出:一个是仅限内部的服务端消息队列实验;另一个是关于「思考如何展示」的正交改动,它在多数 CLI 会话里压制了这个 bug,连测外部构建时都没抓到。这个 bug 处在 Claude Code 上下文管理、Anthropic API、extended thinking 三者的交叉点,绕过了多重人工/自动代码审查、单元测试、端到端测试、自动验证和 dogfooding。加上只在「过期会话」这种边角情形发生、又难复现,我们花了一周多才确认根因。
⭐ 调查时我们拿 Opus 4.7 回测了出问题的那些 PR:给足完整代码仓库上下文时,Opus 4.7 找到了 bug,而 Opus 4.6 没找到。为防重演,我们现在正落地「代码审查支持引入更多仓库作上下文」的能力。该 bug 已于 4 月 10 日在 v2.1.101 修复。
三、一条「控制冗长」的系统提示
我们最新的 Opus 4.7 相比上一代有个明显的行为特点:话很多(verbose)。这让它在难题上更聪明,但也产出更多 token。发布前几周我们就开始为它调 Claude Code(每个模型行为略不同,发布前都要为它优化 harness 和产品)。
减少冗长有多种手段(模型训练、prompt、改进思考的展示 UX),我们最后全用上了,但有一条加进系统提示的话造成了对智能的超额影响:
「长度限制:工具调用之间的文字保持 ≤25 词。最终回复保持 ≤100 词,除非任务确实需要更多细节。」
经过数周内部测试、在我们当时跑的那套 evals 上没看到回归,我们就放心地随 Opus 4.7 在 4 月 16 日一起上线了。调查中我们用更广的一套 evals 做了 ablation(逐行删系统提示看每行影响),发现其中一个评估对 Opus 4.6 和 4.7 都掉了 3%。我们在 4 月 20 日的发布里立刻回滚了它。
今后怎么改
- 让更大比例的内部员工用和公众完全一致的 Claude Code 构建(而非我们测新功能用的版本);
- 改进我们内部用的代码审查工具,并把改进版发给客户;
- 给系统提示改动加更严的管控:每次改动跑一套按模型分的广泛 evals,继续 ablation 理解每行影响,并建了新工具让 prompt 改动更易审查;
- 在 CLAUDE.md 里加指引,确保模型专属的改动只对目标模型生效;
- 对任何可能牺牲智能的改动,加 soak 期(观察期)、更广的 eval 套件、灰度发布,好更早发现问题。
最后要感谢用户:那些用
/feedback反馈、或在线贴出具体可复现示例的人,正是他们最终让我们定位并修复了这些问题。
总结
三个本意良好的优化——调 effort、省缓存、控冗长——各自看都合理,叠在一起却酿成「Claude 好像全面变笨了」的体感。这份复盘的真正教训不是某个 bug 本身,而是:任何可能拿智能去换效率/延迟的改动,都值得更慢、更宽、更灰度地发;以及在评估抓不到时,用户那条具体、可复现的反馈,往往是定位问题的关键信号。