Claude Code session 进行 45 分钟。早些时候你定了「不用 GraphQL、坚持 REST」。突然它建议加一个 GraphQL resolver;或者第四次重读 CLAUDE.md 和 package.json、像没见过一样;或者它现在的 plan 和 10 分钟时的 plan 互相矛盾。
对话长到一定程度,自动 summarization 触发——前面的上下文被压缩,具体约束(不用 GraphQL、用 vitest、在 apps/web/ 改)从摘要里掉了出来。Agent 现在用的是一份有损的”你说过什么”记忆。修法:显式重新锚定状态,或者——通常更快——开新 session 带上紧凑 handoff。
常见原因
按命中率从高到低:
1. 上下文撞满、auto-summarization 压缩前面对话
context 满了,老 turn 被摘要——摘要保留大意、丢具体。「讨论了方案」取代「定了不用 GraphQL、用 vitest、不允许 inline style」。然后 agent 做的决定就和被摘掉的内容不一致。
如何判断:注意「compacting context / summarizing earlier conversation」之类指示——出现后就要预期有损记忆。
2. 长 tool-call 链比预期更快吃光 context
每次 Read、Grep、Bash 都加 context。5 次大文件 Read 可能 20K token——auto-summary 比对话长度暗示的更早触发。
如何判断:session 感觉不长但工具调用密集。看可见的 context-usage 指示器——高比例来自 tool 而不是你的消息。
3. 摘要保留大目标、丢了具体约束
Auto-summary 留「user 想加 billing feature」,丢「user 说:不要 GraphQL、只改 apps/web/、测试 vitest」。任务在做、护栏没了。
如何判断:输出在 task 上但违反了你早先设定的约束——约束被丢了,task 还在。
4. CLAUDE.md 太虚,替代不了 in-session context
summarization 发生时,Claude 退回到持久 context(CLAUDE.md)。CLAUDE.md 没写到的约束就没了——CLAUDE.md 的空缺就是 summarization 的空缺。
如何判断:丢的约束是 per-session 决定(不耐久)——升级到 CLAUDE.md 让它持续。
5. Tool 报错占 context 没贡献信号
Bash 命令连失败 5 次,每次错误 trace 都进 context。Claude 没法思考——半个窗口都是相同的 permission-denied。
如何判断:session 里很多重复 tool 错误——只加噪音不加信号。
6. Plan mode 出长 plan,code 还没开始就吃满 context
100 行 plan + 你的修改 + 用来验证 plan 的 tool read = 真干活之前 context 已半满。第一个代码生成就触发摘要、把 plan 丢了。
如何判断:session 开局花大量时间做 plan,bug 在开始 codegen 时出现。
最短修复路径
按收益从高到低。Step 1 是快速重启,2-3 是耐久加固。
Step 1:停、snapshot、restart
session 明显丢线时不要硬救——开新 session 带 handoff:
- 写一段 5 行「我们现在在哪」:
## 状态(2026-05-22 15:30)
任务:给 apps/web/ 加 billing feature
决定:
- 不用 GraphQL——REST only
- 测试 vitest,紧挨源
- 结构照 `apps/web/src/features/auth/`
进度:
- 已完成:`apps/web/src/features/billing/index.ts`、`types.ts`
- 下一步:实现 `billing.service.ts`
阻塞:无
- 开新 session。
- 把状态贴成第一条消息,加「continue from here」。
新 session 对这份 snapshot 是全 context——没有衰减记忆。
Step 2:把 per-session 决定升级到 CLAUDE.md
每个被丢的约束都是 CLAUDE.md 空缺。session 后更新:
## 架构决定
- API 风格:REST only(不 GraphQL——2025-Q4 试过弃了)
- 测试框架:vitest only(不 jest——见 `apps/web/AGENTS.md`)
- 新 web feature 工作目录:`apps/web/src/features/`
下次 session 启动就读到,约束跨 summarization 存活。
Step 3:每 30 分钟把进度落盘
长 task 把进度写到文件,跨 context reset 存活:
# session 开始时 claude 建这个文件
echo "## 进度日志" > .agent-progress.md
echo "Started: $(date -Iminutes)" >> .agent-progress.md
Prompt:
完成有意义的一步就 append 到 `.agent-progress.md`:
- 时间戳
- 完成了什么
- 改的文件
- 下一步
context 丢了,这个文件就是权威状态。
Step 4:减少 context-吃货 tool 调用
降噪让 summarization 晚点触发:
- 找东西用 Grep 不用 Read——输出小得多
- Read 时用行区间不读整文件
- 同一个文件不要 Read 两次——记住内容
- 大输出写到 /tmp/<name>.txt 再 refer
- Bash 命令一直 fail 就停下来问,不要重试 5 次
Step 5:正交子任务交给 sub-agent
长 task 多关切——把它们 delegate 给 sub-agent(Task tool / 子对话),每个 sub-agent 有自己的 context window:
DB migration 这步开一个 sub-agent。
返回:migration 文件路径 + 应用了的 migration 名。
主 session 看不到 sub-agent 的工具调用,只看 return value。
Step 6:识别 summarization 临近
Claude Code 显示 context 用量。过 ~60% 时 summarization 不远了——提前:
- 把进行中的决定存进 CLAUDE.md 或
.agent-progress.md - 收尾当前子 task
- 在干净边界(一步完成后)计划重启,不要硬撑过 summarization
60% restart 比从撞坏的 95% 救回来便宜。
预防建议
- per-session 决定当文档缺口处理,升级到 CLAUDE.md,跨 summarization 存活
- 超过 20 分钟的 task 维护一份
.agent-progress.md——context reset 时的 fallback - 在干净边界 restart session,不要硬撑过 summarization
- 减少 tool 噪音——Grep > Read、行区间 > 整文件、不重复 read
- 正交子任务给 sub-agent,每个独立 context
- 60% 用量当收尾信号、80% 当「保存 + restart」触发
相关阅读
标签: #排查 #Claude Code #排查 #上下文缺失