当你的 AI Coding Agent 开始重复之前解决过的问题、忘记关键设计决策、工具调用开始出错——不是因为它”变笨了”,而是因为它的”工作内存”满了。
📖 目录
- 🤔 Context window 的本质
- 🔥 Context 压力的三个典型症状
- 💡 五大 Context 优化策略
- 🛠️ 工具层面的 Context 优化
- 📊 Context 消耗与输出质量的非线性关系
- 🚀 实战场景中的 Context 管理
🤔 Context Window 的本质
什么是 Context Window
Context window 是 AI 模型在一次推理中能处理的 token 总数上限。你可以把它理解为 AI 的”工作内存”。
人类程序员的工作内存:约 7 个短期记忆项
AI Coding Agent 的 Context Window:200K tokens(Claude 3.5/3.7 Sonnet)
听起来 200K tokens 是个巨大的数字,足以装下整个代码库。但实际情况是:大多数 AI coding agent 的 context 消耗速度快得惊人,而且消耗掉的 token 并不等于有效信息。
Context 消耗的真实速度
让我们量化一下:
| 场景 | Token 消耗 | 备注 |
|---|---|---|
| 读取一个中等规模代码库(50 文件,每文件 500 行) | ~150K | 一次全量读取几乎用满 |
| 代码审查(diff + 相关文件 + 历史讨论) | 50-100K | 长任务累积很快 |
| 调试 session(错误堆栈 + 多次试错) | 80-200K | 试错过程消耗巨大 |
| 长任务对话历史(20+ 轮) | 100-150K | 对话历史是隐形杀手 |
关键问题:这些消耗中,有效信息密度往往只有 20-40%。大量的 context 被”过程性内容”占据:试错步骤、错误尝试、解释性对话,而不是真正解决问题的核心信息。
Context 的三层结构
理解 context 消耗,需要分清三层:
┌─────────────────────────────────────────┐
│ Layer 3: 会话历史(Conversation History)│ ← 累积最快,密度最低
├─────────────────────────────────────────┤
│ Layer 2: 工具调用结果(Tool Results) │ ← 膨胀最快
├─────────────────────────────────────────┤
│ Layer 1: 代码库内容(Codebase) │ ← 初始消耗大
└─────────────────────────────────────────┘
每一层的优化策略不同。
🔥 Context 压力的三个典型症状
当 context 接近上限时,AI coding agent 会表现出明显的”能力退化”。识别这些症状,可以帮助你判断是否需要干预 context。
症状一:指令遵循退化
表现:简单的任务开始出错,明明是之前讨论过的需求,Agent 却给出了与之前完全不同的答案。
根本原因:关键背景信息被截断,Agent 无法”看见”之前的决策。
症状二:工具调用退化
表现:Agent 开始用错误的工具,或者忘记可用的工具。例如:
- 应该用
Read读取文件,却用Grep搜索 - 应该修改文件 A,却修改了文件 B
- 完全忘记某个可用的 MCP 工具
根本原因:工具描述和使用记录被 context 压缩或截断,Agent 的”工具意识”减弱。
症状三:”急救箱”行为
表现:Agent 开始频繁说这些话:
- “让我回顾一下之前的讨论”
- “考虑到 context 限制,让我先总结一下已知信息”
- “我需要重新聚焦于核心问题”
这是 Agent 在主动做 context 压缩,但它不会告诉你:”我的 context 压力已经影响到了工作质量。”
💡 五大 Context 优化策略
策略一:精准锚定(Precision Anchoring)
核心思想:不是”让 Agent 自己找”,而是”告诉 Agent 精确位置”。
这是降低 context 消耗最有效的策略,可以将消耗降低 10-50 倍。
反面案例:
User: "帮我理解这个代码库的用户认证模块"
Agent: (读取 30 个文件,构建整体认知)
→ context 消耗:~80K tokens
→ 有效信息:约 15K tokens
→ 信息密度:18.75%
正面案例:
User: "只看 auth 模块的 login.py 和 token.py 两个文件,
以及 permission_decorator.py,分析它们之间的数据流"
Agent: (只读取 3 个文件)
→ context 消耗:~8K tokens
→ 有效信息:约 7K tokens
→ 信息密度:87.5%
实操技巧:
-
使用文件路径而非搜索:告诉 Agent “读取
src/auth/login.py:30-80“,而不是 “帮我找到登录相关的代码” -
明确边界:在指令中加一句”只读 X 文件,不要自动探索其他文件”
-
指定行号范围:大文件中只需要某一段时,明确写出行号范围
# 精准锚定的指令模板
"只分析以下文件中的 [具体功能]:
- src/models/user.py(User 模型定义)
- src/services/auth.py(认证逻辑,50-120行)
不要读取其他文件"
策略二:分块处理(Chunked Processing)
核心思想:大任务拆成小任务,每个子任务消耗独立的 context。
反面案例:
# 一次性处理 100 个 PR 的审查
task = "审查这 100 个 PR 的安全性"
# → context 爆炸,任务无法完成
正面案例:
# 分块处理:每个 PR 独立 context
results = []
for pr in pr_list:
result = agent.review_pr(pr) # 每个 PR 独立 context
save_to_file(result) # 结果保存到文件,不是 context
results.append(result)
# → 最终汇总所有结果
Claude Code 的 --resume 模式天然支持分块处理:
# 第一块:处理前 20 个文件
claude --print --system "审查这批文件的安全问题" -- file1.md file2.md ... file20.md > review_batch1.md
# 第二块:处理后 20 个文件(用 --resume 延续)
claude --resume --system "继续审查剩余文件" -- file21.md file22.md ... file40.md > review_batch2.md
# 最终:汇总
cat review_batch1.md review_batch2.md > full_review.md
分块处理的关键原则:
- 每个块的交付物必须保存到文件,不要留在 context 里
- 块与块之间有明确的边界,不互相依赖
- 汇总工作由最后一个块完成
策略三:上下文压缩(Context Compression)
Claude Code 的 compact 命令是 context 压缩的核心工具。
compact 的工作原理:
- 将当前 context 的核心内容压缩成摘要
- 保留关键决策、结论、当前状态
- 丢弃过程性的试错、错误尝试
- 用压缩后的摘要重建 context(通常压缩到 50-70%)
最佳触发时机:
❌ 错误:等到 context 消耗到 95% 再 compact
→ 最后 20% 的 context 往往是试错过程,信息密度最低
→ 截断风险最高
✅ 正确:context 消耗到 70-80% 时主动 compact
→ 保留高价值信息
→ Agent 仍有清晰的上下文
主动 compact 的信号(Agent 出现这些行为时,你应该干预):
- Agent 开始重复之前已经解决过的问题
- Agent 说”让我回顾一下之前的讨论”
- 工具调用结果开始被截断(输出中有 “… (truncated)”)
- Agent 建议”我们换个方向”或”让我重新思考”
compact 后的最佳实践:
# compact 后,给 Agent 一个重新聚焦的指引
"我们刚刚 compact 了 context。现在专注于:
1. 当前任务的剩余部分
2. 如果需要之前的信息,从 TASK.md 文件中读取
3. 不要重新探索已经放弃的方向"
策略四:信息密度分级(Information Triage)
不是所有信息都需要完整保留在 context 中。对信息做分级,决定保留粒度:
Tier 1(必须完整保留):
- 当前任务的核心目标
- 已确定的设计决策
- 关键代码逻辑(当前正在修改的部分)
Tier 2(可压缩保留):
- 相关但不紧急的背景信息
- 历史决策的摘要(完整文档在外部文件)
- 次要代码模块的简要说明
Tier 3(完全丢弃):
- 试错过程
- 错误尝试及结果
- 无关模块的详细代码
# 主动提示 Agent 做信息分级
Claude Code: """
当前任务:修复 user_service.py 的并发问题
Context 分配策略:
- user_service.py: 完整保留(核心修改对象)
- user_repository.py 并发访问部分: 完整保留
- 其他模块: 一句话概括即可,不需要详细代码
- 试错过程: 不要记录,发现某个方向走不通直接放弃
"""
策略五:会话边界设计(Session Boundary Design)
不同任务应该有不同的 session,而不是所有问题都在同一个 session 里解决。
Session A(需求澄清):2-5 轮,理解需求
→ 完成,关闭 session
→ 交付物:需求文档(写入文件)
Session B(方案设计):5-10 轮,设计架构
→ 完成,关闭 session
→ 交付物:设计文档 + CLAUDE.md 更新
Session C(编码实现):可能几十轮
→ 每个子任务用 --resume 延续
→ 避免跨无关任务的 context 污染
Session D(代码审查):独立 session
→ 审查完成后关闭
→ 不与实现 session 混用
核心原则:context 里只保留当前任务相关的历史,不要让无关历史持续消耗空间。
CLARENCE.md 的 Session 边界预设:
# CLAUDE.md - Context 使用策略
## Session 边界规则
- 每个任务目标完成后,将结论写入文件,然后关闭 session
- 不要在同一个 session 中混合多个无关任务
- 长任务中途需要换方向时,先 compact,再继续
## Context 警戒线
- 当 context 消耗超过 70% 时,我会主动提醒你 compact
- 如果我开始重复之前的讨论,说明 context 已经不足
🛠️ 工具层面的 Context 优化
Claude Code 的 –max-turns 参数
--max-turns N 限制 Agent 在当前 session 中最多执行 N 轮对话。配合 --resume 使用:
# 每 20 轮强制 compact + resume,防止 context 无限膨胀
claude --print --max-turns 20 --resume --output-format tracelog
这个组合在 CI/CD 场景中特别有用:每个 job 的 context 窗口是干净的。
tracelog:Context 消耗的诊断工具
--output-format tracelog 生成每次运行的完整轨迹,包含:
- 每个步骤消耗的 token 数量
- context 剩余量变化
- 被截断的内容
通过分析 tracelog,可以识别:
消耗黑洞:哪个文件/操作消耗了最多 context
{
"step": 12,
"tool": "Read",
"input": "src/**/*.java",
"tokens_consumed": 47320,
"useful_tokens": 8200,
"efficiency": "17.3%"
}
无效读取:读了很多但没用的文件
{
"step": 5,
"tool": "Read",
"input": "docs/changelog.md",
"tokens_consumed": 12800,
"referenced_in_output": false,
"verdict": "unnecessary_read"
}
过早 compact:是否在 context 还充足时就触发了 compact
CLAUDE.md:Session 启动时的 Context 预设
CLAUDE.md 是 session 开始时自动加载的上下文文件,是控制初始 context 质量的关键:
# CLAUDE.md
## 当前项目概述
微服务电商平台,共 12 个服务,主技术栈 Python/FastAPI + PostgreSQL
## 架构决策记录(ADR)
- ADR-001: 认证使用 JWT,具体逻辑见 docs/adr/auth.md
- ADR-002: 数据库连接池使用 PgBouncer
<!-- 不要在 context 中复制完整 ADR 内容,只需要摘要 -->
## Context 使用策略(重要!)
- 只读任务相关的文件,不要自动探索全代码库
- 读取文件时优先使用行号范围
- Context 消耗超过 70% 时主动提醒我 compact
- 试错过程不要记录在 context 中,发现走不通直接放弃
📊 Context 消耗与输出质量的非线性关系
传统观点认为:context 越多,输出质量越高。
实际情况更复杂:
Context 消耗率 vs 输出质量:
0-30%: 质量随 context 增加而提升(信息不足 → 充足)
30-60%: 质量平台期(信息充足,继续增加边际效益很低)
60-80%: 质量开始波动(无关信息开始干扰注意力)
80-100%: 质量急剧下降(截断和压缩导致信息丢失)
⚠️ 这个区间的 Agent 表现最不可靠
关键洞察:60-80% 的 context 消耗率是最佳工作区间。
这意味着:
- 不要追求”最大化 context 利用”
- 主动管理 context,保持在健康区间
- 当 context 超过 70% 时,优先压缩而非继续添加
不同模型的 Context 效率
| 模型 | Context Window | 信息密度效率 | 适用场景 |
|---|---|---|---|
| Claude 3.5 Sonnet | 200K | 高 | 中等规模任务首选 |
| Claude 3.7 Sonnet | 200K | 更高(推理能力更强) | 复杂推理任务 |
| GPT-4o | 128K | 中等 | 快速简单任务 |
Context 效率(每 token 能有效利用的信息)比原始 window 大小更重要。一个 200K context 但信息密度高的 session,往往比一个 1M context 但大量冗余的 session 更有效。
🚀 实战场景中的 Context 管理
场景一:大型代码库重构(涉及 50+ 文件)
问题:重构涉及 50+ 文件,一次性处理 context 不够用。
方案:分阶段 + 分块
Phase 1:影响分析(独立 session)
→ 精准读取涉及重构的 10-15 个核心文件
→ 输出影响分析报告(保存到 docs/refactoring/impact.md)
→ 关闭 session
Phase 2:模块化重构(多个并行的子 session)
→ 子 session A:重构数据访问层
→ 子 session B:重构业务逻辑层
→ 子 session C:重构 API 层
→ 每个 session 只处理自己的模块
Phase 3:集成检查(独立 session)
→ 读取 Phase 1 的影响分析文档
→ 检查所有模块的集成点
→ 关闭 session
关键:每个阶段的交付物必须保存到文件,不要留在 context 里。
场景二:长周期调试(同一个 bug 调试了 50 轮)
问题:调试 session 越来越慢,Agent 开始遗忘最初的错误现象。
方案:外部化状态 + 定期 compact
调试开始时:
→ 告诉 Agent:"把错误现象和已尝试的方案记录在 TASK.md 里"
→ Agent 创建 TASK.md,内容包含:错误现象、已尝试的方案列表、当前状态
调试过程中:
→ 每次尝试前先读取 TASK.md
→ 每次尝试后更新 TASK.md(记录:这次尝试了什么、结果如何)
→ 如果 context 超过 70%,立即 compact,并确认 TASK.md 是最新的
调试结束时:
→ 最终结论和解决方案写入 TASK.md
→ 关闭 session,不要让调试历史污染其他任务
→ 下次遇到相关问题,从 TASK.md 恢复,不从对话历史恢复
场景三:代码审查(PR 涉及 20 个文件)
问题:PR 涉及 20 个文件,全读 context 不够,即使够,信息密度也很低。
方案:风险分级 + 精准审查
Step 1:读取 PR 概览
→ PR 描述、变更摘要、涉及的服务/模块
Step 2:风险分级
→ 高风险(必须深度审查):数据层变更、安全相关、认证授权逻辑
→ 中风险(快速扫描):UI/UX 变更、配置变更
→ 低风险(瞥一眼):文档更新、格式调整、测试用例
Step 3:精准审查
→ 高风险文件:完整读取 + 深度分析
→ 中风险文件:只读 diff 相关部分
→ 低风险文件:只读摘要,如果摘要没问题就跳过
Step 4:输出审查报告(保存到文件)
总结:Context 管理的五个核心原则
- 精准锚定:告诉 Agent 精确要读什么,不要让它搜索
- 分块处理:大任务拆分,每个块独立 context
- 主动压缩:context 达到 70% 时主动 compact,不要等截断
- 信息分级:不同层级的信息用不同的保留粒度
- 会话边界:不同任务用不同 session,交付物写文件而非留在 context
Context 管理不是”省着点用”,而是”用得更聪明”。理解了 context 的运作机制,你就掌握了 AI coding agent 能力的上限和效率的关键杠杆。
下次当你觉得 Agent”变笨了”的时候,先问自己:是我的 context 管理出了问题吗?