第 5 章 Agent 循环与上下文管理

举报
chunkj 发表于 2026/11/06 18:58:31 2026/11/06
【摘要】 第 5 章 Agent 循环与上下文管理摘要:上下文窗口是 Agent 系统中最核心的约束资源。本章从"上下文窗口为什么会填满"这一根本问题出发,梳理上下文的构成层次、溢出后的压缩机制、六种主动管理手段、子代理的隔离原理以及提示缓存的工作方式,帮助开发者建立对 Agent 上下文生命周期的完整认知,并在实际工程中做出正确的操作选择。关键词: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 自动处理上下文溢出,分两步执行:
  1. 优先清除较早的工具输出(那些大块的命令返回结果)
  2. 若仍不足,则总结整段对话
    用户的请求和关键代码片段会被保留,但早期对话中的细致要求可能丢失。
    随后,部分内容会从磁盘重新注入上下文。各类内容在压缩后的处理方式如下:
    机制
    压缩后行为
    系统提示和输出风格
    仍然生效
    项目根 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
    重新执行,并将输出加入压缩后的上下文
    两条实用结论
  3. 持久规则应写在项目根 CLAUDE.md 中,压缩后会自动恢复;写在对话里的要求则会消失。
  4. 带 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 工具可以复用。
子代理在独立的上下文窗口中读取文件、执行搜索;返回主会话的只有一份摘要。那几十个文件的全文不会进入主会话的上下文。
工作流程:

  1. 主会话发起委派请求
  2. 子代理在独立上下文中执行(可能读取数十个文件)
  3. 子代理完成后仅返回摘要
  4. 主会话上下文只增加摘要内容
    适用场景
  • 调研型任务:如"找出所有调用 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
    全新会话,无缓存
    新开会话
    全新会话,无缓存
    正常提问、工具调用
    前缀不变,继续命中
    实操结论
  1. 不要在会话中途反复修改 CLAUDE.md。如需修改,改完后执行 /clear 或新开会话;否则每次修改都会导致缓存失效,成本上升。
  2. 密集的短会话比一个长会话更贵,因为每次都要重建缓存。因此"任务相关"时保持长会话是合理的,"任务无关"时才应执行 /clear。
  3. 这也解释了为什么官方既建议"别让上下文变脏",又建议"别太频繁清空"——两者需要平衡。
    5.9 本章小结
  4. 上下文是核心资源,填满则性能下降——所有最佳实践都从这个约束出发。
  5. 启动时 CLAUDE.md、auto memory、MCP 工具名、Skill 描述已经在占用上下文。
  6. 压缩后项目根 CLAUDE.md 会恢复,对话中的要求不会。
  7. 六种管理手段:/clear、/compact <焦点>、/rewind 部分压缩、/context、/btw、子代理。
  8. 大日志文件使用管道或 grep 处理,不要直接 cat。
  9. 不要在会话中途修改 CLAUDE.md,会导致缓存失效。
    下一章:第 6 章 提示词与协作方法
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。