Skip to content

第 11 章 上下文管理进阶

第 05 章把 /compact /clear /context 当作"省钱工具"讲过一遍,第 06 章点到 200K 窗口与 40 轮衰减。这一章不再重复命令清单,而是回答一个更底层的问题:你给 Claude 的上下文,就是它全部的记忆。记忆质量决定输出质量——管理上下文,本质是管理 Claude 的记忆质量。

11.1 结论:上下文窗口约 200K,超限自动压缩;管理上下文就是管理记忆质量

三个事实决定了本章所有策略:

  1. 窗口有限:约 200K tokens(核对日期 2026-07-08,v2.1.202+),装满后会触发 auto-compact 有损摘要
  2. 记忆易失:超过 40 轮后,早期细节开始模糊;压缩后的摘要必然丢失部分早期信息
  3. 稳定锚点存在:CLAUDE.md 在 /compact 后从磁盘重新注入,auto memory 首 200 行/25KB 自动加载——这是不受对话衰减影响的"长期记忆"

由此推出本章的核心心法:

关键信息写文件,不依赖对话记忆;同任务继续用 /compact,切任务用 /clear,观测用 /context

这三句话落到工程里,就是本章的九节内容。

11.2 上下文窗口与自动压缩机制

11.2.1 200K tokens 装什么

200K tokens 约合 15 万英文单词、8-10 万中文汉字。听起来很大,但实际消耗极快,因为窗口里装的远不止对话:

类别内容是否稳定
系统提示Claude Code 自带的系统 prompt、工具定义、技能说明会话内稳定
项目上下文项目根 CLAUDE.md~/.claude/CLAUDE.md/compact 后重注入
Auto memorymemory 文件首 200 行/25KB启动时加载
对话历史用户消息、助手回复、工具调用与结果持续增长,主要消耗源
文件内容@file 投喂、Read 工具读取的结果读入即占空间
工具结果Bash 输出、测试日志、搜索命中常被低估,日志可达数万 token

经验值:一次中等规模的代码探索(读 8-10 个文件 + 跑两次测试),就能消耗 30-50K tokens。一个连续工作 2 小时的会话,很容易逼近 auto-compact 阈值。

11.2.2 衰减不是"满了才丢"

一个常见误解是"窗口没满,记忆就完整"。实际行为更接近:注意力随对话长度稀释。在 200K 窗口里,即使只用了 80K,第 50 轮的 Claude 对第 3 轮约束的把握,也明显弱于第 5 轮的 Claude。

这种衰减表现为:

  • 用户早期声明的"不要引入新依赖""保持 API 签名不变"被遗忘
  • 已排除的假设被重新探索
  • 已确认的根因被再次怀疑
  • 文件路径引用变得含糊

对抗衰减的唯一办法是:把关键信息写进文件(CLAUDE.md、memory、plan 文件、任务注释),让 Claude 在需要时重新读取,而不是依赖它"记得"。

11.2.3 auto-compact:有损摘要,不是无损归档

当上下文接近上限,Claude Code 自动触发压缩:把历史对话生成摘要,替换原始消息。这是有损操作——摘要保留主线,丢失细节。

有损意味着:

  • 具体的错误日志原文可能被压缩成"曾遇到测试失败"
  • 早期文件读取的完整内容只剩文件名和一句话摘要
  • 已排除的中间假设可能被合并或省略

因此 auto-compact 是安全网,不是管理策略。依赖 auto-compact 等于把"保留什么"交给模型自己判断——而它不知道你后续还要用哪段信息。主动 /compact 带聚焦指令,永远优于被动等 auto-compact。

11.3 /compact /clear /context 三命令对比

11.3.1 三命令定位

命令实际行为是否有损何时用
/compact手动压缩上下文为摘要,保留主线有损同任务继续,历史已长
/clear完全清空对话,新会话仍加载 CLAUDE.md完全清空切换到无关新任务
/context查看上下文占用与重资源项,只读观测,决定是否压缩

记忆口诀:压缩留主线,清空换任务,观测再决策

11.3.2 /context:先看钱花在哪里

text
/context

预期输出(示例,非真实转录):

text
Context Usage
─────────────────
System prompt        ~12K tokens
CLAUDE.md (project)   ~3K tokens
Auto memory           ~6K tokens
Conversation         ~78K tokens
  ├─ Tool results    ~41K tokens
  ├─ File reads      ~22K tokens
  └─ User/assistant  ~15K tokens
Total                ~99K / 200K (49%)
Auto-compact at      ~180K (90%)

验证:命令执行后,Claude 输出占用明细而非"已清空"。若输出为空或报错,核对版本(claude --version 应为 v2.1.202+)。

失败边界:/context 本身消耗少量 token,不要每五分钟执行一次。它只在三种场景有价值:会话变长、模型开始遗忘约束、任务切换前。

11.3.3 /compact:保留决策,丢弃噪音

裸用法:

text
/compact

推荐带聚焦指令的用法:

text
/compact 保留:
- 当前 Bug 的已确认根因:Redis 连接池耗尽导致 session 刷新超时
- 已修改文件:apps/api/src/auth/refresh.ts, apps/api/src/redis/pool.ts
- 尚未通过的测试:tests/auth/refresh.test.ts 第 3、7 用例
- 用户明确约束:不引入新依赖,保持 refreshSession API 签名不变
- 下一步:修复连接池归还逻辑,重跑 npm test -- auth

丢弃:
- 已排除的假设(CDN、DNS、中间件顺序)
- 旧测试输出
- 重复的文件摘要

预期输出(示例):

text
Context compacted. Summary retained key decisions and pending steps.
Freed ~45K tokens. Current usage ~54K / 200K.

验证:压缩后用一句话让 Claude 复述"当前根因、已改文件、下一步"——能准确复述说明保留有效;若答非所问,说明聚焦指令不够明确,或关键信息没写进保留清单。

失败边界:

  • /compact 有损,不要指望它保留所有细节。需要精确原文的(如错误日志逐字),应先写进文件
  • 压缩后立即切换任务是浪费——切任务用 /clear,不留摘要
  • 如果当前会话被错误假设污染,/compact 会把污染一起压缩进去。这时该用 /clear

11.3.4 /clear:任务边界就是上下文边界

text
/clear payment-timeout-fixed

这里的参数是给即将被清除的旧对话打标签,方便日后用 /resume 选择器找回——不是给"清除动作"命名。新会话仍会加载项目级 CLAUDE.md,但不携带上一项任务的临时讨论。

预期输出:新会话开始,上下文占用回到初始基线(系统提示 + CLAUDE.md + memory,约 20-30K tokens)。

验证:/clear 后执行 /context,应看到 Conversation 部分归零,只留 System prompt 与 CLAUDE.md。

失败边界:

  • /clear 不可逆。清除前若有关键决策未写文件,它会永久丢失
  • 参数标签写错不影响清除,但会让 /resume 选择器难以辨认。养成"任务名-状态"的命名习惯
  • 不要用 /clear 当"重新开始本轮"——那是 /rewind 的职责

11.4 Auto-compact 触发点与 buffer 变化

11.4.1 90% 触发与 buffer 缩小

auto-compact 在上下文利用率约 90%(即 ~180K tokens)时触发。触发前预留的 buffer 用于容纳压缩摘要与后续若干轮对话——这个 buffer 在近期版本中从约 45K tokens 减至约 33K tokens(核对日期 2026-07-08)。

buffer 缩小的含义:

  • 留给"压缩后继续工作"的空间更紧凑
  • 模型压缩能力增强,同等摘要质量需要的空间减少
  • 对用户的意味:被动触发的容错空间变小,主动管理更显重要

11.4.2 触发后会发生什么

auto-compact 触发时,Claude Code 会:

  1. 暂停当前响应
  2. 将对话历史送入压缩,生成摘要
  3. 用摘要替换原始历史
  4. 重新注入 CLAUDE.md(项目根级)与必要的稳定上下文
  5. 继续当前任务

这个过程对用户可见,会有明确提示。提示出现时,意味着你刚才那轮的细节正在被有损处理。

11.4.3 主动压缩的时机选择

与其等 90% 被动触发,不如在以下节点主动 /compact:

节点为什么
探索阶段结束,转入实施探索读取的大量文件内容已不再需要
一个子任务完成,开始下一个已完成任务的细节无后续价值
调试根因确认后已排除的假设应丢弃,只留确认根因
/context 显示 Conversation 超过 60%留出余量,避免在关键操作中被 auto-compact 打断

验证:主动 /compact 后执行 /context,确认 Conversation 占用显著下降,且摘要保留了当前任务的核心决策(让 Claude 复述验证)。

失败边界:不要在"刚投喂了关键文件、还没让 Claude 处理"时 /compact——文件原文可能被压缩成摘要,丢失你正需要的细节。先让 Claude 处理完关键信息(输出结论、写入文件),再压缩。

11.5 长会话衰减对策

11.5.1 40 轮阈值

经验上,超过 40 轮的会话开始出现明显衰减:早期约束被遗忘、已确认事实被重新怀疑、文件路径引用变模糊。这不是绝对值,但可以作为"该收尾或该压缩"的信号。

11.5.2 关键信息写文件

对抗衰减的根本对策是把"不可丢失"的信息从对话记忆迁移到文件:

信息类型写到哪里为什么
项目约束、技术栈、命令CLAUDE.md每次启动与 /compact 后自动加载
跨会话决策原因、历史教训auto memory启动时加载,跨会话持久
当前任务的根因、约束、下一步plan 文件或任务注释Claude 可随时 Read 找回
已确认的 API 契约、数据结构代码注释或 docstring读取即获得,不依赖记忆

实践:长会话中段,如果发现某条决策被 Claude 反复确认(说明它记不牢),立刻把它写进 CLAUDE.md 或 plan 文件,而不是在对话里第三次重申。

11.5.3 大型任务拆会话

一个跨日的大型任务,不要硬塞进一个会话。拆法:

会话 1:探索 + 架构方案(Plan Mode,产出 plan.md)
  ↓ /clear
会话 2:实施模块 A(读 plan.md,改代码,跑验证)
  ↓ /clear
会话 3:实施模块 B
  ↓ /clear
会话 4:集成 + 审查(/code-review)

每个会话开头让 Claude 先 Read plan.md 与相关 CLAUDE.md,把"长期记忆"从文件加载回来。这样每个会话都有干净的上下文与明确的任务边界,衰减与污染被隔离在会话内。

验证:每个会话开头让 Claude 复述当前任务在整体计划中的位置,能准确说明 plan.md 已被加载。

失败边界:拆会话的代价是"会话间状态"全部依赖文件传递。如果 plan.md 写得含糊,后续会话会偏离。plan.md 必须包含:目标、范围、约束、完成标准、当前进度——五要素缺一不可。

11.6 CLAUDE.md 重注入与 auto memory 加载机制

11.6.1 重注入:稳定锚点

/compact 与 auto-compact 触发时,Claude Code 会从磁盘重新读取项目根级 CLAUDE.md 并注入到压缩后的上下文。这意味着:

  • CLAUDE.md 是不受对话衰减影响的稳定锚点
  • 对话里说一遍的约束会衰减,写进 CLAUDE.md 的约束每次压缩后都重置为新鲜状态
  • 修改 CLAUDE.md 后,下一次 /compact 即生效,无需重启会话

实践推论:凡是被 Claude 反复遗忘的约束,都应该升级到 CLAUDE.md,而不是在对话里反复重申。重申三次的成本,高于写进 CLAUDE.md 一次的成本。

11.6.2 auto memory 加载机制

auto memory(~/.claude/projects/<project>/memory/*.md)在会话启动时加载,遵循"首 200 行/25KB"限制:

  • 单个 memory 文件超过 200 行或 25KB,只加载前半部分
  • 多个 memory 文件按索引顺序加载,总量超限时靠后的文件被截断或跳过

这意味着 memory 写作的两条纪律:

  1. 单个 memory 文件控制在 200 行/25KB 以内,关键信息前置
  2. MEMORY.md 索引文件保持精简,它是其他 memory 文件的目录,本身应能被完整加载

验证:执行 /memory,会列出当前加载的 memory 文件与是否被截断。若看到"truncated"标记,说明该文件超限,需要拆分或精简。

失败边界:

  • memory 不是代码片段仓库。存"不可从代码推导的上下文"(决策原因、团队约定、历史教训),不存代码与文件路径
  • memory 不会随 /compact 重注入——它只在会话启动时加载。长会话中段如果依赖某条 memory,应主动让 Claude Read 对应文件
  • memory 有时效性(47 天前的记忆可能已过时),关键决策应回查源文件核实

11.6.3 三层记忆模型

把上面两个机制合起来,Claude Code 的"记忆"其实是三层:

层级载体加载时机是否受衰减影响
长期记忆CLAUDE.md启动 + /compact 后重注入
跨会话记忆auto memory启动时加载(首 200 行/25KB)启动后不再重载
会话记忆对话历史持续累积是,40 轮后明显衰减

管理策略:把信息放到匹配其重要性的层级。临时讨论放对话,项目约束放 CLAUDE.md,跨项目教训放 memory。

11.7 子代理上下文独立

11.7.1 独立窗口,独立衰减

子代理(subagent)有独立的上下文窗口,与主会话隔离。主会话的 /compact、auto-compact、/clear 都不影响已启动的子代理 transcript。子代理完成后,只把最终摘要返回主上下文。

这个隔离带来两个直接好处:

  1. 并行探索不污染主上下文:派 3 个子代理分别探索 3 个模块,它们的完整探索过程留在各自 transcript,主上下文只收到 3 份摘要
  2. 主上下文压缩不影响在途子代理:即使主会话 auto-compact,正在运行的子代理仍持有自己的完整上下文

11.7.2 适合与不适合

子代理上下文独立,适合:

  • 并行探索多个模块、多个假设
  • 隔离试验:试一条不确定的方案,失败则主上下文不受污染
  • 大规模低耦合批量修改(文件间无需一致性保证)

不适合:

  • 需要精确代码引用回传主上下文的(子代理只返回摘要,行号级细节会丢失)
  • 跨文件一致性重构(主上下文操作更可靠)
  • 需要长链路记忆的任务(子代理上下文同样会衰减)

详细子代理工程实践见第 19 章。

11.8 实战:一个长会话如何分段

场景:排查"登录后刷新页面丢失会话"的 Bug,修复后还要顺带优化 session 刷新性能。这是一个跨多任务的长工作流,演示如何用三个命令分段管理。

11.8.1 阶段 1:探索(Plan Mode)

text
(进入 Plan Mode,Shift+Tab 两次或 /plan)

调查登录后刷新页面丢失会话的问题。
入口文件:
- @apps/web/src/auth/session.ts
- @apps/web/src/auth/AuthProvider.tsx
- @apps/api/src/routes/session.ts
- @packages/auth/src/token.ts

只读探索,最多读 8 个文件。
输出:候选根因、影响范围、最小修复方案。

探索完成后,Claude 输出根因与方案。此时上下文里塞满了文件原文与中间假设——该压缩了。

11.8.2 阶段 2:实施(主动 /compact 节点)

退出 Plan Mode 前,主动压缩:

text
/compact 保留:
- 确认根因:refreshSession 在 401 重试时未重置 retry 计数,导致死循环后清空 token
- 修改文件:apps/api/src/auth/refresh.ts(尚未开始)
- 约束:保持 refreshSession API 签名,不引入新依赖
- 验证:npm test -- auth 必须全过,新增 retry 计数回归测试
- 下一步:实施修复

丢弃:
- 已排除的假设(CDN、DNS、中间件顺序)
- 已读但无需再读的文件全文

验证:/compact 后让 Claude 复述"根因、约束、下一步",准确则继续实施。实施过程中跑测试、读失败日志,上下文再次增长。如果中途 /context 显示超过 60%,再次主动 /compact

11.8.3 阶段 3:切换到性能优化(/clear)

Bug 修复完成、测试通过、提交 commit 后,要切换到"优化 session 刷新性能"——这是新任务,即使主题相关,也用 /clear:

text
/clear auth-bug-fixed

新会话开始,让 Claude 先 Read 阶段 1 留下的 plan 文件(如果探索时写了)与相关 CLAUDE.md,把"长期记忆"从文件加载回来,再开始性能优化。

11.8.4 关键信息写文件的时机

整个流程中,有三个时机必须把信息写文件:

时机写什么写到哪
探索结束根因、影响范围、方案plan.md 或 issue 描述
实施中段已确认的 API 契约变更代码注释
任务完成决策原因、踩过的坑auto memory

这样即使后续会话 /clear,关键信息仍可从文件找回。

11.9 失败边界

本章的策略都有失效场景,列出最常见的五类:

11.9.1 依赖对话记忆导致幻觉

症状:Claude 引用了从未发生过的"之前讨论",或否认确实说过的约束。

根因:长会话衰减 + 模型对"是否说过"的自我判断不可靠。

对策:关键约束写进 CLAUDE.md,需要时让 Claude Read 核实,而不是问"你还记得吗"。

11.9.2 /compact 丢失关键早期信息

症状:压缩后 Claude 忘了某条早期确认的根因或约束。

根因:裸 /compact 不带聚焦指令,模型自行判断保留什么,可能丢弃你认为重要的细节。

对策:始终用带聚焦指令的 /compact,明确列出"保留"与"丢弃"清单。对必须逐字保留的信息(错误日志原文、API 响应),先写进文件再压缩。

11.9.3 子代理上下文不足

症状:子代理返回的摘要过于笼统,主上下文拿不到需要的细节。

根因:子代理上下文同样有限,且只返回最终摘要,中间过程不回传。

对策:派子代理前明确"返回什么"——要求结构化输出(根因、文件路径、行号、建议),而非开放式总结。需要行号级细节的任务,在主上下文操作,不派子代理。

11.9.4 /clear 误删有用上下文

症状:/clear 后发现上一任务的关键决策没写文件,永久丢失。

根因:/clear 不可逆,且参数标签只影响 /resume 选择器的显示名,不保留对话内容。

对策:养成"/clear 前检查关键信息是否已写文件"的习惯。具体做法:/clear 前执行一次 /context,确认当前会话是否有未落盘的决策;有则先写入 memory 或 plan 文件,再 /clear

11.9.5 auto-compact 在错误时机触发

症状:Claude 正在处理关键文件,auto-compact 突然触发,文件原文被压缩成摘要,后续处理丢失细节。

根因:被动等待 90% 触发,没有在安全节点主动压缩。

对策:在探索结束、子任务完成、根因确认等自然节点主动 /compact,把压缩时机掌握在自己手里。监控 /context 占用,超过 60-70% 时就主动处理,不要等到 90%。


上一章:测试驱动与验证闭环 下一章:Hooks 与自动化工程


下一章:Token 控本与故障恢复 | 返回目录