过去两年很多团队都把精力放在 prompt engineering 上,但一旦 Agent 开始跨多轮、多工具、长时程工作,真正的瓶颈很快就会从“提示词怎么写”转移到另一个问题:哪些信息应该进入上下文,何时进入,保留多久,什么信息应该被压缩,什么状态根本不该暴露给模型。
这就是 context engineering。
如果把大模型看成一个新的计算运行时,那么上下文窗口更像它的工作内存。模型每一步推理都依赖这块内存里当前可见的状态,而工程工作的目标,不是盲目把更多信息塞进去,而是让每一步恰好拥有最小但足够的高信号信息集。
一、为什么 Agent 时代必须重视上下文工程
单轮问答时代,系统提示词往往就能覆盖大部分需求。可一旦进入 Agent 模式,系统立刻变得复杂:
- 有系统提示词
- 有工具描述
- 有工具输出
- 有消息历史
- 有外部知识
- 有运行时状态
- 有长期记忆
这些内容都可能进入上下文窗口,而上下文窗口本身又是有限资源。更麻烦的是,资源变大不等于效果线性提升。上下文变长之后,模型通常会出现一系列问题:
- 注意力被稀释
- 无关信息干扰当前判断
- 早期错误被写进历史并持续污染后续推理
- 多个来源之间的规则互相冲突
Anthropic 提到过一个很关键的现象:context rot。随着 token 数继续增长,模型对上下文中具体信息的精准提取能力会下降。这不是个别模型的问题,而是当前大模型架构下都要面对的现实。
LangChain 那篇文章则把这些失效模式拆得更细,包括:
Context PoisoningContext DistractionContext ConfusionContext Clash
所以对 Agent 来说,上下文不是“越多越好”,而是注意力预算。多一个 token 并非总是多一分收益,它也可能是在消耗后续推理的清晰度。
二、上下文工程不只是管理 prompt,而是管理整段运行态
这也是为什么 context engineering 不该被理解成“prompt engineering 的同义词升级版”。
Prompt 只是上下文的一部分。到了 Agent 体系里,需要管理的是整个运行态:
- 系统提示词
- few-shot 示例
- 工具及工具说明
- 外部检索结果
- 工具执行结果
- 运行时 scratchpad
- 长期记忆
- 子代理返回摘要
换句话说,Agent 的表现不只取决于“你怎么对它说”,还取决于“你让它在当前时刻能看到什么、看不到什么、怎么获取更多信息,以及什么时候应该忘掉一部分信息”。
三、一个实用框架:写入、选择、压缩、隔离
LangChain 给了一个非常适合工程落地的框架,可以把上下文工程拆成四个动作:
- 写入上下文
- 选择上下文
- 压缩上下文
- 隔离上下文
这个框架比“优化 prompt”更有操作性,因为它直接对应了一个 Agent 系统里最常见的设计决策。

1. 写入:先决定哪些状态要被保存到窗口之外
很多信息没必要一直留在上下文窗口里,但又不能完全丢掉。这时就需要把它们写到窗口外的某个持久介质里。
典型做法包括:
- scratchpad
- todo 文件
NOTES.md- 线程级状态对象
- 长期记忆库
这些信息的作用不是立刻喂给模型,而是作为后续可检索、可回读的工作记忆。
从记忆类型上看,可以至少分成三类:
procedural memory
保存规则、操作方法、偏好约束。semantic memory
保存事实、关系和稳定知识。episodic memory
保存过去做过什么、哪些案例成功过、哪些路径踩过坑。
这类写入动作的价值非常大。因为 Agent 在长任务里最容易丢的是“已经做过什么、为什么这么做、接下来该接哪一步”。如果没有外部化状态,长链路任务很快就会漂。
2. 选择:不是所有已保存的信息都该重新读回来
会写还不够,更难的是会选。
选择上下文,本质上就是决定下一轮推理应该把哪些窗口外信息重新拉进来。
这件事最容易出错的地方有两个:
- 选少了,模型缺关键上下文
- 选多了,模型又重新被噪声淹没
Anthropic 在这方面强调的是 just-in-time 检索思路。与其预先把所有相关资料一次性塞进窗口,不如只保留轻量引用,例如:
- 文件路径
- URL
- 查询语句
- 目录索引
等到任务真正需要时,再通过工具按需读取。
这种做法在代码智能体里尤其有效。比如让模型先看到:
CLAUDE.md- 目录结构
- 文件命名
- 时间戳
- 测试路径
然后通过 grep、glob、head、tail 或数据库查询去逐步探索,而不是把整个仓库或整张表直接送进上下文。
这类“引用先行、内容后取”的策略,本质上是在把静态检索改造成动态探索。速度会慢一点,但上下文质量通常更高。
3. 压缩:上下文迟早会满,关键是怎么压
只要 Agent 连续工作得够久,压缩就是必选项。
最常见的压缩方法有两类:
- 总结
- 修剪
总结是让模型把当前轨迹浓缩成较短的新上下文;修剪则更偏规则化过滤,比如:
- 去掉过旧消息
- 清除冗余工具输出
- 删除不再相关的长日志
- 保留决策,丢弃执行噪声
Anthropic 在这里给的建议很实用:压缩的目标不是“摘要写得漂亮”,而是高保真保留后续仍然可能影响决策的信息。例如:
- 架构决策
- 未解决的问题
- 已知失败路径
- 关键实现细节
- 最近访问文件
而像深历史里的原始工具返回值,很多时候可以直接清掉。因为这些内容的原始字节量很大,但对后续推理的边际收益很低。
LangChain 也提到,压缩不一定只能发生在“窗口快满的时候”。它还可以被设计在一些固定边界上,例如:
- 搜索工具返回之后先做结果压缩
- 子代理完成任务后只回摘要
- 某个工作阶段结束时做阶段总结

4. 隔离:有些上下文不该给当前模型看
隔离是很多团队最容易忽略、但收益极高的一步。
一个常见误区是:既然某些信息将来可能有用,那就先都放在 messages 里。问题在于,暴露给模型的每一份状态,都会参与下一轮注意力竞争。
更稳的方式是把状态拆开:
- 一部分进
messages - 一部分留在运行时
state - 一部分留在沙箱环境
- 一部分交给子代理独立处理
例如:
- 大图像、音频、JSON、大搜索结果保留在环境变量或沙箱对象里
- 工具调用明细写入运行时状态对象
- 子代理在自己的上下文里展开搜索,主代理只拿摘要
这背后的核心思想是:不是所有状态都应该成为模型的直接思考材料。
多代理就是一种典型隔离方式。每个子代理有自己的工具集、自己的上下文窗口、自己的任务边界。这样主代理不需要被搜索过程、试错过程和海量中间结果污染,只需要接收结构化结论。
当然,隔离不是没有代价。多代理通常会带来更高 token 成本和更复杂的协调问题。是否值得做,取决于任务是否真的存在明显的可分解边界。
四、系统提示词仍然重要,但重点变了
上下文工程并不意味着系统提示词不重要,而是意味着系统提示词不再是唯一杠杆。
Anthropic 对系统提示词的建议可以总结成一句话:把提示词写在正确的高度。
常见的两个极端都不理想:
- 太低:把脆弱的流程逻辑硬编码进 prompt
- 太高:只写抽象原则,缺少可执行信号
比较稳的做法是:
- 用分段结构组织提示词
- 语言直接、短句、少歧义
- 明确工具使用边界
- 用少量高质量示例代替大量边缘规则
这和上下文工程并不冲突。提示词负责设定大方向,而写入、选择、压缩、隔离负责管理运行时状态。
五、工具设计本身也是上下文工程的一部分
工具经常被当成执行层问题,但实际上它也是上下文工程的一部分。
原因很简单:工具不仅定义“能做什么”,还定义“会带回什么上下文”。
如果工具返回:
- 巨大的原始 JSON
- 含糊不清的错误信息
- 多个功能重叠的接口
那模型就会在选择和理解工具时被迫消耗更多注意力。
比较好的工具设计应该满足几件事:
- 单一职责
- 参数含义清晰
- 返回值尽量面向下一步决策
- 错误结构化
- 少返回无关噪声
LangChain 还提到一个很有用的方向:如果工具很多,可以先对工具描述做检索,只把当前任务最相关的少量工具暴露出来,而不是一开始就把全部工具列表给模型。
六、长期记忆不是“越会记越好”,而是“越会取越好”
上下文工程里另一个经常被高估的点,是长期记忆。
很多人会把长期记忆理解成“尽量多存”。但真正难的是检索质量。
如果记忆系统会在不合时宜的时候把旧信息拉回来,用户会明显感觉上下文窗口“不再属于自己”。这不仅影响体验,也会直接干扰推理。
所以长期记忆系统至少要回答三个问题:
- 存什么
- 什么时候存
- 什么时候取
从工程角度看,比起“无差别自动记忆”,更稳的路径通常是:
- 先把高价值规则和少量稳定事实结构化保存
- 再补充案例、轨迹和用户偏好
- 最后才考虑更大规模的语义记忆集合
也就是说,记忆系统应该先追求高信噪比,再追求覆盖率。
七、真正落地时,先做最小闭环
这两篇文章有一个共同点:都不建议一上来做过度复杂的体系。
比较合理的落地顺序通常是:
- 先把系统提示词写到合适高度
- 给 Agent 一套最小可用工具
- 把关键状态外写到文件或状态对象
- 做最基础的上下文选择逻辑
- 再补压缩和清理
- 最后才考虑多代理和复杂记忆
这里最关键的不是“功能完整”,而是“每个环节都有可观察性”。
如果没有 tracing、token 统计和评测,团队很难知道:
- 上下文到底在哪一步膨胀了
- 哪些文件经常被误检索
- 哪类工具输出最污染窗口
- 压缩之后到底是变好了还是变差了
这也是 LangChain 为什么反复强调 observability 和 evals。上下文工程不是靠感觉调出来的,它本质上是一个需要持续测量、验证和迭代的系统工程问题。
结语
对 Agent 来说,上下文窗口不是被动容器,而是主动设计对象。
当系统开始进入多轮推理、工具循环、长期任务和跨会话状态之后,真正决定效果的往往不是模型本身,而是你是否认真设计了以下四件事:
- 什么信息写到窗口外
- 什么信息在当前时刻被选进来
- 什么信息应该被压缩或修剪
- 什么状态应该被隔离而不是暴露给模型
Prompt engineering 解决的是“怎么告诉模型要做什么”,而 context engineering 解决的是“怎样让模型在每一步都看到最该看到的信息”。对正在构建 Agent 的团队来说,后者已经越来越接近核心工程工作本身。
参考来源:
https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
https://www.langchain.com/blog/context-engineering-for-agents