面向 AI 智能体的上下文工程:完整攻略

你的 AI 智能体在前 10 步运行得很棒。

然后到了第 15 步左右,它开始变得潦草。

调错工具。忘掉你最初的指令。输出质量低下。

大多数人会怪模型。

可这几乎从来都不是模型的问题。

问题在于模型看到的是什么。

组织模型所看到的东西,这件事叫做上下文工程(context engineering)

它正在迅速成为任何搭建 AI 智能体的人最重要的技能。

下面就是这份完整攻略。


提示词工程已死。如今真正要紧的是上下文工程。

你听说过提示词工程(prompt engineering)。

写清晰的指令。好的示例。告诉模型该扮演什么角色。

对一个聊天机器人来说,这套办法完美奏效。

可一旦你搭建的是一个智能体,它就不再管用了。

原因如下。

聊天机器人回答一个问题,然后停下。

而智能体会采取行动——浏览网页、调用 API、写代码、运行命令——一步接一步又一步,有时多达几十步。

每一步都产生输出,被加进模型的上下文里。

而那个上下文是有限的。

Anthropic 的工程团队是这样定义的:

「上下文是你从一个 LLM 采样时所包含的那组 token。上下文工程,就是优化这些 token 的效用,从而稳定地达成期望的结果。」

简单说:确保你的智能体在正确的时间、以正确的格式,看到正确的信息。

提示词工程是上下文工程的一个子集。

上下文工程则是全部。


你智能体的上下文窗口就是内存(RAM)。而它正在被填满。

LangChain 对此有个恰当的类比。

把一个 LLM 想象成一种新型的操作系统。

模型是 CPU——它负责思考。

上下文窗口是内存(RAM)——那块工作记忆,模型当前能看到、能推理的一切都住在那里。

就像你的电脑在内存被填满时会变慢一样,你智能体的推理能力也会在上下文窗口变得拥挤时退化。

这叫做上下文腐烂(context rot)

Chroma 做过一项研究,评估了 18 个前沿模型——GPT-4.1、Claude 4、Gemini 2.5、Qwen3 以及其他。

每一个模型的表现,都随着输入长度的增加而退化。

不是在硬性上限处退化,而是远在那之前就开始了。

一个拥有 200K token 窗口的模型,可能在 50K token 时就显示出明显的退化。

这种下滑是连续的,不是一道断崖。

为什么?Transformer 的工作方式是让每个 token 都关注其他每一个 token——这制造出 n 的平方级别的关系。随着上下文增长,模型把所有这些关系都把握住的能力,就被稀释了。

然后还有「迷失在中间」(Lost in the Middle)的问题。

LLM 表现出一条 U 形的注意力曲线。

→ 上下文的开头:记得很牢

→ 上下文的结尾:记得很牢

→ 中间:基本被忽略

研究者测得,当相关信息从上下文的开头移到中间时,准确率下降超过 30 个百分点。

你那些最初的指令——被埋在 50,000 个 token 的工具输出之下——实际上就消失了。

Claude Code 的用户发现,输出质量在上下文容量的 40%–60% 处就开始退化。远在任何硬性上限之前。


究竟有哪些东西在争抢你智能体上下文里的空间

7 个类别。全都在争夺同一个有限的窗口。

1. 系统提示词(System Prompt)

智能体的身份。行为规则。控制流逻辑。针对不同任务类型的指令。在一个智能体里,这不只是「乐于助人」那么简单。它可以定义整个架构。

2. 工具定义(Tool Definitions)

智能体可能调用的每一个工具,都需要一份 schema 来描述它做什么、接受哪些参数、什么时候该用它。

3. 工具调用结果(Tool Call Results)

每一次工具调用都会把它的输出加进上下文。一次网页抓取:5,000–10,000 个 token。一次文件读取:差不多。这些累积得很快。

4. 检索到的知识(RAG)

从向量数据库拉取的文档、搜索结果、API 响应——任何为给智能体的决策提供信息而检索来的东西。

5. 对话历史(Conversation History)

所发生一切的完整记录。用户消息、智能体回复、推理、先前的决定。每一轮都让它线性增长。

6. 记忆(Memory)

来自当前会话的短期记忆。来自先前会话的长期记忆——用户偏好、过往结果、学到的模式。

7. 智能体状态(Agent State)

当前的计划、待办清单、进度标记、草稿笔记。那些追踪智能体在一个多步任务里走到哪一步的元信息。

7 项全都在争夺同一个窗口。

上下文工程,就是决定谁胜出。


4 个核心策略

LangChain 发布了一套框架,把每一种上下文工程技术都归进 4 个桶里。

你将来会学到的每一种技术,都能装进其中之一。

写入。选择。压缩。隔离。


策略 1 —— 写入(Write) (智能体会遗忘。给它一个记住的办法。)

当一个智能体的上下文被填满、随后被压紧(compacted)时,它会丢失信息。

如果在那之前智能体什么都没记下来——那条信息就永远没了。

写入意味着给智能体一些办法,把信息持久化到上下文窗口之外。

三种形式:

草稿区(Scratchpads)

给智能体一个工具,让它在执行任务的过程中记笔记。中间发现。做出的决定。它知道自己稍后会需要的信息。

Anthropic 造了一个「think」工具——一块让 Claude 把问题想透的专用空间。

在 tau-bench 基准测试上,这在某些任务上把表现提升了高达 54%。

规则文件(Rules Files)

持久化的流程记忆。

如果你用过 Claude Code,就见过 CLAUDE.md。

每次会话开始时加载的指令——项目架构、约定、怎么跑测试、要当心什么。

智能体每次启动都会读它。

它永远不会忘掉那些根本性的东西。

记忆提取(Memory Extraction)

智能体把事实、用户偏好和学到的模式保存下来,以便跨会话检索它们。

完全活在上下文窗口之外。

智能体明天需要的信息,等明天来临时就在那里等着。


策略 2 —— 选择(Select) (别把所有东西都给智能体。给它此刻需要的那些。)

一个拥有 40 个工具、一个庞大知识库,以及好几个会话历史的智能体,没法一次性把这些全都加载进来。

总得有什么来决定,对这一步来说什么才是相关的。

传统 RAG: 由系统来决定。

用户提问 → 检索文档 → 塞进提示词 → 完事。

静态。一次性。模型没有发言权。

智能体式 RAG(Agentic RAG): 由智能体来决定。它搜索自己需要的东西,精炼查询,挑选工具,判断自己什么时候信息已经够了。

把检索当成一个迭代的过程,而不是一条一次性的流水线。

这之所以要紧,是因为「什么才相关」在每一步都在变——而只有智能体知道自己下一步需要什么。

工具选择问题,是最让人栽跟头的那一个。

如果你的智能体有 40 多个工具,那就可能是 10,000 个 token 的工具定义,在任何工作开始之前就坐在上下文里。

解法:对工具描述做 RAG。

不要在每次调用时都把所有工具定义一股脑倒进去,而是用语义搜索,只把与当前这一步相关的工具浮现出来。

一篇叫 RAG-MCP 的论文测试了这个做法。

工具选择准确率:14% → 43%(提升 3 倍)。token 用量:大致砍掉一半。

Anthropic 称之为一种混合策略:把核心上下文(比如 CLAUDE.md)预先加载好,让智能体对其余一切做即时(just-in-time)检索。

把基础的东西前置加载。其余的按需检索。


策略 3 —— 压缩(Compress) (上下文会累积。留住含义,砍掉 token。)

哪怕做了好的选择,上下文还是会累积。

每一次工具调用、检索来的文档、做出的决定,都留在窗口里。

设想你的智能体已经做了 20 次工具调用。

上下文:80,000 个 token 的累积工具输出、对话历史、推理痕迹。

其中大部分已经不再相关了。智能体早就基于它们采取过行动。

但它还在那里,占着空间、拖累注意力、推高成本和延迟。

你可以在 3 个点上做压缩。

在信息进入上下文之前:

→ 在检索之前,把大文档切成连贯的小块

→ 重排序(rerank),让只有最有用的块才进得来

→ 在工具输出进入主上下文之前,即时地把它们摘要掉

在智能体工作的过程中:

→ 对话历史的滚动摘要——持续更新

→ 流行的混合做法:保留最近 10 条消息的原文 + 把更早的全部摘要

→ 硬性裁剪:一旦上下文达到某个尺寸阈值,就移除较早的消息

→ Claude Code 的自动压紧:在 95% 容量处触发,自动摘要整条轨迹

在智能体已经基于某样东西采取过行动之后:

→ 工具结果清除:某个工具结果在 15 步之前用过了,就丢掉它

→ 用一行摘要替换,或者干脆移除

→ 智能体并不需要它 20 步之前抓取的某个网页的全文

目标是:减少 token 数量。保留真正要紧的东西。


策略 4 —— 隔离(Isolate) (最强大的策略。它让多智能体系统成为可能。)

这里有一个关于长时间智能体运行的、更深层的问题。

它不只是空间问题,而是污染问题。

来自研究阶段的那些详尽的文件搜索,在智能体转去写代码时,仍然坐在上下文里。

那段陈旧的研究上下文,现在成了噪声。在一个本该专注于干净实现的阶段里,它正分散着模型的注意力。

隔离意味着给工作的不同部分各自独立的上下文窗口。

子智能体(Sub-agents)

一个父智能体把一个聚焦的子任务——「在代码库里搜索所有与认证相关的文件」——委派给一个子智能体。

子智能体在它自己干净的上下文窗口里工作。

当它回报时,只返回一份浓缩的摘要。

所有杂乱的搜索操作,都隔离在子智能体的上下文里,永远不会污染父智能体。

状态 schema 隔离(LangGraph 的做法)

把智能体的状态设计成:不同的字段存储不同类型的上下文。

LLM 只看到与当前这一步相关的那些字段。

工具结果坐在一个「后台」字段里——在被显式浮现出来之前,对模型不可见。

无需开出独立的子智能体,就能对智能体在每一步看到什么进行细粒度的控制。

正是隔离,让复杂的多步工作流真正变得可靠。

不同的活儿。不同的上下文窗口。没有污染。


智能体失败的 4 种方式 (给失败命名。然后修好它。)

Drew Breunig 辨认出了随着智能体上下文增长而出现的四种截然不同的失败模式。

你见过的每一个出故障的智能体,都落在其中之一里。

失败 1:上下文投毒(Context Poisoning)

一个幻觉或一个错误进入了上下文。

智能体在随后的步骤里一次又一次地引用它。

第 5 步的坏数据,会复利式地累积进之后的每一步。

修法: 在工具输出进入上下文之前先验证它们。从一个错误中恢复之后,把失败尝试的历史压缩掉。当只有最终解法才要紧时,别把 10 步死胡同里的调试过程留着可见。

━━━

失败 2:上下文分心(Context Distraction)

上下文变得太长,模型开始过度依赖近期的历史。

它不再综合出一个新颖的计划,而是只把自己最近做过的事重新炒一遍。

它停止了思考。它开始了重复。

修法: 积极地摘要和修剪。哪怕你手头有一个很大的上下文窗口可用。窗口大,不意味着就要把它填满。

━━━

失败 3:上下文混淆(Context Confusion)

多余的内容把模型引向低质量的决策。

经典例子:一个模型在给它 46 个工具时在某基准测试上失败——尽管上下文远在限度之内——但只给 19 个工具时却运行良好。

工具的数量,对上下文来说并不算多到装不下。

而是对模型来说,多到没法把它们想清楚。

修法: 动态工具管理。用 RAG-MCP 只把与当前这一步相关的工具浮现出来。让工具集与当前阶段相匹配。

━━━

失败 4:上下文冲突(Context Clash)

新信息与上下文里已有的某样东西相矛盾。

系统提示词说一套。一份检索来的文档说的是另一套。

智能体没法调和这个矛盾。于是产生前后不一致的行为。

修法: 确立一个清晰的权威排序。系统提示词 > 检索来的事实 > 对话历史。在注入新信息之前,拿它对照已有的上下文做验证。用 XML 标签和清晰的标题,让模型知道该信任哪个来源。


怎样为智能体写系统提示词 (不是为聊天机器人。是为智能体。)

聊天机器人的系统提示词定的是一种基调。

「你是一个乐于助人的助手。要简洁、友好。」

智能体的系统提示词定的是架构。

它规定控制流——怎么应对各种任务类型、什么时候用哪些工具、出错时怎么办、要遵守哪些护栏。

它更接近于给一名自主的员工写一份岗位说明书,而不是写一段人格提示词。

Anthropic 称之为在「正确的海拔高度」上写作。

太过规定死:「如果用户提到账单,并且提到退款,并且金额超过 100 美元,就调用工具 X。」脆弱。在每一个你没预料到的边界情形上都会崩。

太过含糊:「乐于助人,并使用恰当的工具。」这等于什么都没给智能体。没有具体的信号,它做不出好的自主决策。

**那个甜蜜点:**具体到足以引导自主行为。又灵活到足以让模型在新情形里运用判断。强有力的启发式经验法则。而不是僵硬的死规矩。

实用建议:

→ 用 XML 标签或 markdown 标题来组织——背景、指令、工具指引

→ 从最小开始,在失败中迭代——别想着一上来就预料到每一个边界情形

→ 最小不等于短——一个复杂智能体的系统提示词可以有好几千个 token,这没问题,只要每个 token 都对得起它占的位置

→ 用少样本(few-shot)示例——给智能体看看好的行为是什么样,而不是试图用文字描述每一条规则


KV 缓存:你该在意上下文顺序的那个「$$$」理由

大多数搭建智能体的人都不知道这东西的存在。

当你把 token 发给一个 LLM 时,模型会为每个 token 计算键值(key-value)表示。

计算开销很大。

所以推理服务商会把这些表示缓存起来。

如果你上下文的开头——那个前缀——在多次 API 调用之间保持不变,服务商就会复用缓存下来的计算,只处理结尾处那些新的 token。

快。便宜。

但如果你在两次调用之间重排或改动了上下文的早期部分——你就让缓存失效了。服务商会从头把一切重新算一遍。

在 Claude Sonnet 上的成本差异:

→ 缓存命中的输入 token:每百万 0.30 美元

→ 未缓存的输入 token:每百万 3.00 美元

10 倍的差异。

对一个每个任务要做 30–40 次 API 调用的智能体来说,这积累得很快。

KV 缓存效率的实用规则:

→ 稳定的内容放在上下文的最顶部——系统提示词、工具定义,以及任何在轮次之间不变的东西

→ 动态的内容放在最底部——对话历史、当前步骤、智能体状态 → 不要在对话进行到一半时动态地增删工具——那会让缓存失效

→ 用**工具屏蔽(tool masking)**而不是工具移除——让所有工具定义在前缀里保持稳定(被缓存),只是把不相关的那些标记为在当前阶段不可用


那套在 7 小时里交付 35,000 行代码的工作流

Dex Horthy(HumanLayer 的 CEO)在 AI Engineer Code Summit 上展示了这套方法。

据称,他的团队用它在一次 7 小时的会话里,向一个庞大的 Rust 代码库交付了大约 35,000 行代码。

方法是:频繁的、刻意的压紧(Frequent Intentional Compaction)。

把智能体的工作组织成一个个阶段。每个阶段产出一份压紧后的产物。每个新阶段都从一个全新的上下文窗口开始,里面只装着那份产物。

始终刻意地待在上下文窗口的 40%–60% 以下。

阶段 1 —— 研究

子智能体探索代码库。读文件。追踪数据流。绘制架构图。

所有杂乱的 grep 结果和文件内容都留在子智能体的上下文里。从不碰到父智能体。(隔离)

产出:一份紧凑的 research.md——文件路径、函数签名、模式、坑点。(写入)

上下文重置:原始研究用掉了窗口的 60–80%。研究产物把它压缩到了 15–20%。(压缩)

阶段 2 —— 规划

全新的上下文窗口。只包含:研究文档 + 问题定义。

智能体产出一份详尽的实现计划。

这是最重要的一处人工审查检查点。

在这里抓出逻辑错误,此时修正它们既容易又免费。到了后面,那要花上好几个小时。

阶段 3 —— 实现

又一个全新的上下文窗口。只包含:那份计划。

智能体一步一步地照着做。

对于复杂的任务:用一份 progress.md 追踪什么已经完成、什么还剩下。(写入)

结果:在每个阶段都是一个干净、专注的智能体。没有污染。没有上下文腐烂。没有「潦草的第 20 步」。


最优秀的平台是如何以不同方式处理这件事的

Claude Code

混合检索。CLAUDE.md 在前面加载。glob 和 grep 这类工具负责对代码库做即时导航。

在 95% 处自动压紧——保留架构决策,以及最近访问的 5 个文件。

可以为复杂的子任务开出子智能体,每一个都有自己干净的上下文。

理念:「做能奏效的最简单的事。」让模型自己聪明地判断它需要什么,并给它工具去把那东西找到。

Manus

KV 缓存感知的上下文排序:稳定的前缀,动态的后缀。工具屏蔽,而非移除。

观测结果压缩流水线——每一份工具输出在进入智能体上下文之前都经过处理。

用一份持久的待办清单来追踪状态。

把文件系统当作被驱逐出去的上下文的溢出记忆。

为规模而生。服务着数十万用户,在那里效率是一个关乎经营成本的问题。

ChatGPT Agent

视觉优先的路子。智能体与一个 GUI 浏览器交互。

截图作为视觉快照被加进上下文。模型基于它所看到的进行推理。

视觉 token 很贵,所以智能体对截图数量很挑剔。

用强化学习(RL)在成千上万台虚拟机上学习最优的工具使用策略,而不是把它们显式地编程进去。

Google ADK

最讲原则的架构路子。

三条设计原则:

  1. 把存储与呈现分开——持久的状态,和每次 API 调用里出现的东西,不是一回事
  2. 显式的变换——具名的、有序的处理器,以可测试、可组合的步骤来变换上下文
  3. 默认就给上下文划定范围——每一次模型调用都只看到所需的最少信息

工程纪律,重于提示词雕琢。


通用的智能体回合流水线

每一个严肃的平台,在每个智能体回合里都收敛到同样的 5 步循环:

收集(Collect)——用户输入、对话历史、工具结果、检索来的文档、智能体状态

选择(Select)——在剩余的 token 预算之内,挑出对这一步相关的东西

压缩(Compress)——摘要、截断或重构,以塞进上下文 → 排列(Arrange)——稳定的内容在前(缓存),动态的内容在后

组装 + 调用(Assemble + call)——最终的上下文 → API 调用 → 拿到输出 → 循环

这就是那个在你用过的每一个生产级智能体内部运行着的循环。

理解它,正是把那些交付出可靠智能体的搭建者,与那些纳闷自己的智能体为何在第 15 步变潦草的搭建者,区分开来的东西。


总结

上下文腐烂是真实存在的,而且远在你的上下文上限之前就开始了。

修好它的 4 个策略:

写入——把信息持久化到上下文之外,这样智能体就不会遗忘

选择——只拉进这一步所需要的东西

压缩——砍掉 token,留住含义,要主动而非被动

隔离——为不同的活儿用不同的上下文,互不污染

要提防的 4 种失败模式:

投毒——坏数据复利式地贯穿每一步

分心——冗长的历史让智能体只会炒冷饭而不思考

混淆——太多工具拉低决策质量

冲突——矛盾产生前后不一致的行为

KV 缓存值得你为之省下 10 倍的成本。把稳定的内容放在最前面。

最好的工作流:研究 → 压紧 → 规划 → 压紧 → 实现。在每个阶段都用全新的上下文。

对于严肃的智能体工作,上下文工程不是可选项。

它就是工作本身。


如果这篇对你有用:

→ 转发,把它分享给你认识的每一个搭建智能体的人

→ 关注 @sairahul1,获取更多在你睡觉时也照样运转的系统

→ 收藏这篇——你会回头来看那套 4 策略框架的

我写的是关于 AI、做产品,以及真正奏效的系统。