第 5 章 Agent 循环与上下文管理
第 5 章 Agent 循环与上下文管理
摘要:上下文窗口是 Agent 系统中最核心的约束资源。本章从"上下文窗口为什么会填满"这一根本问题出发,梳理上下文的构成层次、溢出后的压缩机制、六种主动管理手段、子代理的隔离原理以及提示缓存的工作方式,帮助开发者建立对 Agent 上下文生命周期的完整认知,并在实际工程中做出正确的操作选择。
关键词:Agent;上下文窗口;自动压缩;提示缓存;子代理
适用版本:Claude Code 2.1.x
5.1 理解一切最佳实践的出发点
官方文档中的一句话,是理解后续所有最佳实践的关键:
“Most best practices are based on one constraint: Claude’s context window fills up fast, and performance degrades as it fills.”
大多数最佳实践都源于同一个约束:上下文窗口填满得很快,而随着填充,性能会下降。
问题的本质不在于"模型不够聪明",而在于单次会话能够保留的信息量有限。当 Agent 读取了 50 个文件、执行了 20 条命令之后,它对原始需求的记忆就会被稀释。具体表现为以下几类现象:
- 遗忘先前约定的规则
- 重复犯已经纠正过的错误
- 修改一处、破坏另一处
- 声称"已完成",但实际遗漏了需求
因此,所有技巧本质上都在做两件事:减少无关内容进入上下文,把重要内容放在可靠的位置。
5.2 上下文窗口的构成
一次会话的上下文窗口包含以下内容,按加载时机可分为三层。
第一层:固定开销(始终存在)
内容
说明
系统提示(system prompt)
平台预置,不可更改
输出风格(output style)
用户可配置的回复风格
第二层:会话启动时自动加载
内容
说明
CLAUDE.md(项目根目录及各级子目录)
每次会话自动读取
自动记忆 auto memory(前 200 行 / 25KB)
持久化记忆片段
Skills 描述(非正文,仅摘要信息)
常驻但体积小
MCP 工具名与服务器说明
正文按需加载
git 状态快照
仓库当前状态
第三层:会话过程中动态增长
内容
可控性
增长速度
用户输入的每一句话
完全可控
—
Agent 的每一次回复
间接可控
中
读取的每个文件的全文
可控
最快
每条命令的完整输出
可控
最快
每次工具调用的参数和结果
间接可控
中
子代理返回的摘要(非完整过程)
间接可控
低
启动时已消耗的上下文
在用户输入任何内容之前,以下内容已经进入上下文: - CLAUDE.md
- 自动记忆
- MCP 工具名和服务器说明
- Skill 描述
- output style(如果配置了)
- –append-system-prompt 追加的内容(如果使用了)
说明:这就是安装大量 MCP 服务器会导致明显变慢、变贵的原因——每个服务器即使不被调用,其工具定义也要占用位置。Claude Code 目前默认对 MCP 工具定义采用延迟加载(tool search)策略,只有工具名和服务器说明常驻,用到某个工具时才拉取正文。即便如此,服务器数量仍需克制。
5.3 最容易消耗上下文的三种行为
行为
代价
替代做法
“帮我调查一下鉴权系统”
可能读取上百个文件
缩小范围,或交给子代理处理(见 5.6 节)
cat 一个大日志文件
整份内容进入上下文
tail -200 app.log | claude -p “找异常”,或使用 grep
一个会话做五件事
前四件事的残留全部挤占空间
任务切换时执行 /clear
注意:最常见的失控场景是"无限探索"——给定一个没有边界的动词(investigate、look into、understand),Agent 会持续读取文件。正确做法是给出明确边界:指定目录、指定文件、指定查找目标。
5.4 上下文填满后的处理机制
Claude Code 自动处理上下文溢出,分两步执行:
- 优先清除较早的工具输出(那些大块的命令返回结果)
- 若仍不足,则总结整段对话
用户的请求和关键代码片段会被保留,但早期对话中的细致要求可能丢失。
随后,部分内容会从磁盘重新注入上下文。各类内容在压缩后的处理方式如下:
机制
压缩后行为
系统提示和输出风格
仍然生效
项目根 CLAUDE.md 和无路径限定的 rules
从磁盘重新注入
自动记忆
从磁盘重新注入
Skill 描述
按当前 skills 重建并重新注入(v2.1.304+)
git 状态快照
重新读取仓库状态
plan mode 中编写的计划
从磁盘重新注入
带 paths: 前置元数据的 rules
按需重新加载
子目录中的嵌套 CLAUDE.md
按需重新加载
读过或改过的文件
重新读取最多 5 个,最近修改的优先
已调用的 skill 正文
重新注入,每个上限 5000 token,总计 25000 token,最旧的先丢弃
后台命令和后台子代理
继续运行,并提醒 Agent 哪些任务仍在执行
早先由 hook 注入的上下文
随对话一起被总结
匹配 compact 的 SessionStart hook
重新执行,并将输出加入压缩后的上下文
两条实用结论 - 持久规则应写在项目根 CLAUDE.md 中,压缩后会自动恢复;写在对话里的要求则会消失。
- 带 paths: 的 rules 在压缩后会被总结掉。如果某条规则必须始终有效,应去掉 paths:,或将其移至项目根 CLAUDE.md。
说明:压缩后重新读取文件时,超过 5000 token 的文件只保留路径引用(显示为 Referenced file),不保留内容。因此,超大的单文件不适合反复读取。
5.5 主动管理上下文的六种手段
手段一:/clear——切换任务时清空
/clear
在无关任务之间使用 /clear 重置上下文。这是成本最低、最有效的操作。
经验法则:如果需要解释"另外一件事",就应该先执行 /clear。
手段二:/compact——带焦点的定向压缩
/compact Focus on the API changes
不带参数时执行普通压缩;带指令时可以让总结保留所关心的部分。
也可以在 CLAUDE.md 中预设压缩指令:
Compact Instructions
压缩时务必保留:修改过的文件清单、所有测试命令、当前的实现计划。
手段三:/rewind 的部分压缩
按两次 Esc 或输入 /rewind 打开菜单,选择一条消息后可选择:
选项
效果
Summarize from here
从该消息往后压缩,之前的上下文完整保留
Summarize up to here
之前的上下文压缩为摘要,近期消息原样保留
说明:在长会话中"前半段调研、后半段实施"的场景下,使用 Summarize up to here 将调研部分压缩为摘要、保留实施细节,效果优于全量执行 /compact。
手段四:/context——查看当前上下文占用
/context
按类别显示上下文占用情况,给出优化建议,并列出实际加载的 CLAUDE.md 和自动记忆文件。
当感觉 Agent 响应质量下降时,第一件事就是运行 /context 排查。
手段五:/btw——不污染上下文的边角提问
/btw 这个项目用的 Node 版本是多少?
答案不会进入会话历史,问完即弃。
说明:这是一个容易被低估的命令。查询一个常量、确认一个命令的拼写、随口问一句——使用 /btw 而非正常提问,可以省掉一整轮往返的上下文成本。
手段六:子代理隔离——将大块阅读挡在主上下文之外
详见下一节。
5.6 子代理:上下文的隔离舱
在主会话中发起委派:
用子代理调查我们的鉴权系统怎么处理 token 刷新,以及有没有现成的 OAuth 工具可以复用。
子代理在独立的上下文窗口中读取文件、执行搜索;返回主会话的只有一份摘要。那几十个文件的全文不会进入主会话的上下文。
工作流程:
- 主会话发起委派请求
- 子代理在独立上下文中执行(可能读取数十个文件)
- 子代理完成后仅返回摘要
- 主会话上下文只增加摘要内容
适用场景
- 调研型任务:如"找出所有调用 X 的地方"
- 大规模文件搜索:需要在大量文件中定位信息
- 独立验证:让一个全新上下文的评审者检查 diff(见第 6 章)
不适用场景 - 小任务:启动子代理本身有开销
- 需要交互确认的任务:子代理不能与用户直接交互
详细用法见第 13 章。
5.7 上下文窗口容量与压缩触发时机
Fable 系列、Sonnet 5 及之后、Haiku 5.5、Opus 4.6 及之后、Sonnet 4.6 支持 100 万 token 上下文窗口。具体可用性取决于套餐,选择 [1m] 模型变体即可启用。压缩机制在大窗口下的工作方式相同。
触发压缩的时机取决于模型和配置。如需提前触发压缩,避免 Agent 自行猜测重点,可执行:
/autocompact 500k
也可以在启动时指定:
claude --autocompact 500k
参数值
含义
auto
由 Claude Code 按模型自动决定(默认)
100k–1M
达到指定量时自动压缩
注意:压缩抖动(thrashing)。如果某个文件或某次工具输出大到"压缩完立刻又满"的程度,Claude Code 在数次尝试后会停止自动压缩并报错,而不是无限循环。恢复步骤可参考官方排障说明中关于"自动压缩因 thrashing 报错而停止"的条目。根因通常是:Agent 反复读取一个巨大的生成文件、打包产物或日志。解决方法是将该文件加入 .gitignore,或明确告知 Agent 不要读取。
5.8 提示缓存:为什么"同样的开头"能省钱
Claude Code 使用 prompt caching,缓存的对象是请求前缀。其核心原理是: - 会话早期内容不变 → 后续每一轮都能命中缓存 → 成本降低、速度提升
- 一旦前缀变化 → 缓存失效,按全价重新计算
影响缓存前缀的操作
操作
对缓存的影响
会话中途修改 CLAUDE.md
前缀变化,缓存失效
切换模型
缓存失效
增删 MCP 服务器或重连
可能失效
/clear
全新会话,无缓存
新开会话
全新会话,无缓存
正常提问、工具调用
前缀不变,继续命中
实操结论
- 不要在会话中途反复修改 CLAUDE.md。如需修改,改完后执行 /clear 或新开会话;否则每次修改都会导致缓存失效,成本上升。
- 密集的短会话比一个长会话更贵,因为每次都要重建缓存。因此"任务相关"时保持长会话是合理的,"任务无关"时才应执行 /clear。
- 这也解释了为什么官方既建议"别让上下文变脏",又建议"别太频繁清空"——两者需要平衡。
5.9 本章小结 - 上下文是核心资源,填满则性能下降——所有最佳实践都从这个约束出发。
- 启动时 CLAUDE.md、auto memory、MCP 工具名、Skill 描述已经在占用上下文。
- 压缩后项目根 CLAUDE.md 会恢复,对话中的要求不会。
- 六种管理手段:/clear、/compact <焦点>、/rewind 部分压缩、/context、/btw、子代理。
- 大日志文件使用管道或 grep 处理,不要直接 cat。
- 不要在会话中途修改 CLAUDE.md,会导致缓存失效。
下一章:第 6 章 提示词与协作方法
- 点赞
- 收藏
- 关注作者
评论(0)