🏠 总目录📚 本教程 04 · 上下文工程
📑 本页目录(点开跳转)

04 · 上下文工程

24 分钟 | ⭐⭐ 理解后面一切的钥匙


🎯 一句话

上下文窗口不是硬盘,是有限的注意力预算。整个 Agent 工程的核心命题只有一句: 找到能达成目标的最小高信号 token 集合。


🧠 一、上下文腐烂(Context Rot)

100%50%只放相关的(精简)什么都往里塞(腐烂)塞满上下文占用 →任务准确率上下文越长,模型越难用好它 —— 无关内容会让它塌得更快
两条线的起点一样,差别只在往里塞了什么。⭐ 这就是「少即是多」的来源:上下文窗口是容量上限,不是使用建议 —— 能塞 100 万 token 不代表塞满了还好用。

现象:上下文里的 token 越多,模型准确回忆和使用其中信息的能力越差不是到了上限才出问题——是渐进式劣化,从很早就开始了。

三个架构性原因(短期内不会消失)

 ① 注意力是 n² 的
    每个 token 要和所有 token 算关系
    token 翻倍 → 每个 token 分到的"注意力份额"被稀释
    → 不是容量问题,是【分配】问题

 ② 训练数据里长序列本来就少
    互联网上 100 万字的连贯文档极少
    → 模型在超长上下文上"练得少",能力天然弱

 ③ 位置编码在长距离上要外推
    训练时见过的最长序列有限
    → 超出部分靠插值/外推,定位精度下降

💡 人话类比

模型像人一样有工作记忆。你把 300 页资料拍在同事桌上说「都看看」, 和把关键 3 页划好重点递过去——得到的工作质量完全不同,哪怕他都"读"了

⚠️ 一个必须破除的误解

   ❌ 「窗口 200K,所以我可以塞 200K」
   ✅ 「窗口 200K 是容量上限,有效工作区远小于它」

   厂商宣传的"大海捞针"测试(在长文里藏一句话让模型找)
   ↑ 这只测【检索】,不测【推理】

   真实任务需要:同时用上散落在多处的信息 + 做多步推理
   → 这个能力衰减得比"捞针"快得多

🧰 二、对抗腐烂的四件武器

武器一:压缩(Compaction)

接近上限时,把历史对话总结成摘要,用摘要 + 最近几轮重新开始。

   [90K token 的对话历史]
        ↓ 总结
   [2K 摘要] + [最近 3 轮原文]
        ↓
   继续工作,注意力恢复清爽

⚠️ 压缩最容易做砸的地方:摘要提示词写得太笼统,导致丢关键细节。

# ❌ 会丢东西的写法
"总结上面的对话"

# ✅ 必须显式列出要保留什么
"""总结以下 Agent 工作历史。必须逐条保留:
1. 已完成的事(做了什么,结果如何)
2. 当前状态(正在做什么,卡在哪)
3. 下一步计划
4. 所有关键事实:文件路径、做过的决策及理由、报错原文、数字

不要省略任何路径或报错 —— 省略会导致重复犯已经犯过的错。
"""

🔑 判断压缩做得好不好的方法:压缩后问模型「我们刚才为什么放弃了方案 A?」 答不上来 = 摘要丢了决策理由 = 它会重新尝试方案 A。

武器二:结构化笔记(外置记忆)

把重要状态写到上下文之外的文件里,需要时再读回来:

   progress.md    ← 做到哪了(人可读,方便你介入)
   decisions.md   ← 为什么这么选(防止反复推翻)
   todo.json      ← 还剩什么 ⭐ 用 JSON 不用 Markdown

💡 为什么状态文件推荐 JSON:模型更不容易随手改坏或覆盖结构化格式。 Markdown 太"软",模型编辑时容易顺手重写整个文件。格式的刚性提供了保护。

这是第 12 章长时任务 harness 的地基。

🗃️ 注意这里只是记忆的一种实现:把状态写进文件,是为了「这一轮少塞点东西进去」。 但跨会话该留下什么、什么时候该写、旧的记忆过期了怎么办、两条记忆打架听谁的—— 这些问题这一章不管。它们在 04b · Agent 记忆。 ⭐ 一句话分工:上下文工程管「这一轮塞什么进去」,记忆管「跨轮次留下什么」。

武器三:子 Agent(上下文隔离)

把「大量阅读、少量结论」的任务派给一个独立上下文的子 Agent:

   主 Agent(上下文珍贵)
        │ "去调查这个报错的根因"
        ▼
   子 Agent:翻 50 个文件、读 8000 行日志
             (脏活在【自己的】上下文里干)
        │
        ▼ 只返回 200 字结论
   主 Agent 继续,完全没被污染 ✅

什么任务适合派给子 Agent

特征 例子
输入大、输出小 日志分析、代码库搜索、文档调研
探索性强、可能白跑 「看看有没有类似实现」
需要完全不同的上下文 用另一套规则审查
不适合 需要主 Agent 全程上下文才能判断的任务

武器四:⭐ 渐进式披露(Just-in-Time)—— 全领域最重要的模式

不要预加载所有可能用到的信息,让 Agent 在需要时自己去取。

这个思想在整个体系里反复出现:

应用 机制 在哪讲
Skills 元数据(100 token)常驻 → 正文按需 → 附件更按需 第 10 章
Tool Search 工具定义延迟加载,先只给一个搜索工具 第 8 章
文件系统 给 ls/grep/read,让模型自己探索,而不是把仓库塞进去 Claude Code 的做法
即时检索 用时才查,而不是全库入上下文 第 11 章

🔑 一句话把"可能有用"的东西变成"可以取到"的东西,而不是"已经在这"的东西。


📉 三、Claude 5 时代的新规则:少即是多

模型变强后,上下文工程的方向从「教它做事」转向「别挡它的路」:

旧习惯 新规则 为什么变了
系统提示词写几千行流程指导 砍掉 80% 模型已经知道怎么做,冗长指导变成噪声
为旧模型缺陷打的补丁提示 每次换代重新审视,删掉过时的变通 补丁编码了会过期的假设
手工编排每一步 给目标和验证手段,让模型自己规划 模型的规划能力超过了你的预设流程
写大量示例教它用工具 好的工具描述 + 一个示例通常够了 第 7 章

🔑 这和第 12 章 harness的核心命题同源: 「你为模型缺陷写的每一段提示词,都编码了一个会过时的假设。」

所以要定期问:我可以停止做什么?


💰 四、上下文与成本:两个立刻能省钱的动作

① Prefix Caching(前缀缓存)

   Agent 每轮都重发完整历史(第 1 章)
   → 前缀完全相同 → 可以被缓存复用 → 只为新增部分付费

   ⭐ 命中缓存的前提:前缀【逐字节相同】

所以要遵守一条布局铁律

系统提示词(稳定)
  • 工具定义(稳定)
对话历史(追加)
当前时间戳/随机ID

⚠️ 一个真实的常见事故:在系统提示词里塞「当前时间:2026-08-01 14:23:05」 → 每次请求前缀都不同 → 缓存 100% 失效 → 成本翻好几倍。 要放时间就放在最后

② 控制工具返回的体积

工具返回的内容会永久占据上下文(除非压缩)。

   read_logs() 返回 5000 行  → 这 5000 行会一直待在上下文里
   search_logs(pattern) 返回 20 行 → 只占 20 行

   ⭐ 一次贪心的全量读取,会拖累后面所有轮次

第 7 章会展开工具设计。


🔨 五、动手:给你的长会话做尸检

  1. 找一次你觉得「AI 后来变笨了」的长对话
  2. 定位它开始出错的那一轮
  3. 数一下当时上下文里的构成:
   真正相关的信息      ____%
   失败的尝试          ____%
   过时的文件版本      ____%
   跑偏的讨论          ____%
  1. 在那个节点新开会话,只带 3 句话的状态摘要重试

大概率立刻变聪明。这个体验会让你永远记住:清空重来 > 长会话里拉扯。


🕳️ 六、五个常见坑

症状
把窗口当硬盘 塞满了却效果变差 主动筛选,不是能塞就塞
压缩丢关键事实 压缩后重复犯已犯过的错 摘要提示词显式列出要保留什么
该派子 Agent 却在主线干 主上下文被日志/搜索结果淹没 大输入小输出的任务派出去
时间戳放前面 成本莫名其妙很高 动态内容一律放最后
工具一次返回太多 前几轮就把预算烧光 工具要支持过滤/分页(第 7 章)

📚 延伸阅读


✅ 检查点

  1. 什么是上下文腐烂?三个架构性原因?
  2. 为什么说"大海捞针测试通过"不代表长上下文真的好用?
  3. 四件武器分别是什么?各解决什么问题?
  4. 压缩最容易做砸的地方是什么?怎么检验压缩质量?
  5. 为什么外置状态文件推荐 JSON 而不是 Markdown?
  6. 什么样的任务适合派给子 Agent?
  7. 为什么时间戳不能放在系统提示词开头?
  8. Claude 5 时代的新规则一句话是什么?
👀 答案
  1. token 越多,模型使用其中信息的能力越差,且是渐进式的。原因:①注意力 n² 导致份额被稀释 ②训练数据里长序列少 ③位置编码长距离要外推。
  2. 大海捞针只测检索(找一句藏起来的话),不测推理(同时用上散落多处的信息做多步推理)。后者衰减快得多。
  3. 压缩(历史→摘要)、外置笔记(状态写文件)、子 Agent(脏活隔离只回摘要)、渐进式披露(按需取用不预载)。
  4. 摘要提示词太笼统导致丢关键细节。检验方法:压缩后问「我们为什么放弃了方案 A」——答不上来说明丢了决策理由,它会重新尝试 A。
  5. JSON 格式刚性更强,模型不容易随手改坏或整体重写;Markdown 太"软",编辑时容易被覆盖。
  6. 输入大输出小(日志分析、代码搜索)、探索性可能白跑、需要完全不同的上下文。不适合:需要主 Agent 全程上下文才能判断的任务。
  7. 会让每次请求的前缀都不同,Prefix Caching 100% 失效,成本翻倍。动态内容一律放最后。
  8. 少即是多——砍掉教模型做事的冗长指导,删掉为旧模型打的补丁,给目标和验证手段而非手把手编排。

🛑 可以停在这里

走神救援

上下文=有限注意力预算不是硬盘,核心命题只有一句:找到能达成目标的最小高信号 token 集合腐烂三因:注意力n²稀释份额(是分配问题不是容量问题)、长序列训练少、位置编码外推;⚠️它不是到上限才出问题,是从很早就开始的渐进式劣化。⚠️大海捞针只测检索不测推理,所以「窗口 200K 就能塞 200K」是错的。四武器:①压缩(90K 历史→2K 摘要 + 最近 3 轮原文;摘要提示词必须显式列出要保留什么——做过什么、卡在哪、下一步,以及文件路径、决策理由、报错原文、数字,否则会重复犯错;⭐检验方法是压缩后问它「我们刚才为什么放弃了方案 A」,答不上来它就会重新去试 A)②外置笔记(progress/decisions/todo 三件套,用JSON不用MD,格式刚性防改坏,MD 太软容易被整体重写)③子Agent隔离(大输入小输出的任务派出去:翻 50 个文件、读 8000 行日志都在它自己的上下文里干,只返回 200 字结论)④渐进式披露(最重要,贯穿Skills/ToolSearch/检索——Skills 只让 100 token 的元数据常驻、正文按需;把"可能有用"变成"可以取到",而不是"已经在这")。Claude5新规则:少即是多——系统提示词砍掉 80%,删掉给旧模型打的补丁,定期问"我可以停止做什么"。省钱两招:Prefix Caching(命中前提是前缀逐字节相同,所以动态内容必须放最后,💀时间戳放前面会毁掉全部缓存,100% 失效、成本翻好几倍)、控制工具返回体积(read_logs 的 5000 行会永久占着上下文,search_logs 只占 20 行)。

下一节 👉 04b-Agent记忆.md

🧭 为什么紧接着是记忆:这一章讲的「压缩、外置笔记、子 Agent 隔离」全是在管当前这一轮的上下文。 一旦 Agent 要跨会话记住用户偏好、记住上次踩过的坑,就是另一套问题了。 只想先把 Claude Code 用起来的话,可以直接去 05-ClaudeCode实操-指令该放哪.md

打卡记录保存在你的浏览器里,首页能看到总进度