Claude Code 中途丢了项目上下文:6 个 summarization 触发 + 重启 vs 加固

Agent 突然忘了之前定的事、反复读 CLAUDE.md、和 plan 矛盾——自动摘要把承重细节压没了。重新锚定或者干脆 restart。

Claude Code session 进行 45 分钟。早些时候你定了「不用 GraphQL、坚持 REST」。突然它建议加一个 GraphQL resolver;或者第四次重读 CLAUDE.mdpackage.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

每次 ReadGrepBash 都加 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:

  1. 写一段 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`
阻塞:无
  1. 开新 session。
  2. 把状态贴成第一条消息,加「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 #排查 #上下文缺失