一、什么是上下文工程

2025 年,随着 Agent 应用从原型走向生产,"上下文工程"(Context Engineering)逐渐取代"提示工程"(Prompt Engineering),成为 AI 工程领域最热门的话题之一。

二者的区别并不微妙。提示工程关注的是如何措辞——怎样写一条好的指令让模型给出更好的回答。上下文工程关注的是怎样管理进入上下文窗口的一切信息——包括系统指令、工具定义、检索到的文档、对话历史、执行中间结果,以及它们的组织方式、检索时机和压缩策略。

Anthropic 在其技术博客中给出了一个简洁的定义:上下文工程是为每个步骤的上下文窗口填充恰当信息的艺术与科学。这不是一次性的工作——在一个多步骤的 Agent 循环中,每一步的上下文都是动态变化的,需要持续做出写入什么、检索什么、保留什么、丢弃什么的决策。

LangChain 进一步将上下文工程的操作归纳为四个类别:写入(Write)、选择(Select)、压缩(Compress)、隔离(Isolate)。这四个动词构成了一个完整的上下文管理循环。

为什么这件事现在变得如此重要?因为 Agent 的上下文窗口和人类的工作台一样——空间有限,塞满了东西就会找不到重点。随着 Agent 从简单的单轮问答演进到需要执行数十步操作的长程任务,上下文管理从"锦上添花"变成了"生死攸关"。

二、上下文窗口:约束与代价

理解上下文工程,首先要理解上下文窗口的本质约束。

2.1 注意力预算

Transformer 架构中,模型对每个 token 的理解依赖于它与其他所有 token 之间的注意力关系。这意味着 token 数量增长时,两两关系的计算量以 n² 增长。即便现代模型支持 128K 甚至更长的上下文窗口,性能并不在窗口内均匀分布。大量研究表明,模型对上下文开头和结尾的信息给予更多关注,而中间部分容易出现"注意力衰减"——被称为"Lost in the Middle"现象。

Weaviate 将这一约束形象地描述为"注意力预算":模型在每个生成步骤中分配给不同信息的注意力是有限的,如果上下文中充斥着无关内容,关键信息就会被淹没。

2.2 上下文退化

更长的上下文不仅带来更高的计算成本,还可能导致模型表现下降。Anthropic 的工程实践表明,即便上下文窗口在技术上没有溢出,过长的上下文也会导致模型出现指令遵循能力下降、关键信息遗漏、不一致的推理等问题。

这对 Agent 系统尤为致命。一个典型的 Agent 任务可能需要 50 次以上的工具调用,每次调用都会向上下文追加新的行动记录和观察结果。如果不做主动管理,上下文会像滚雪球一样膨胀,最终拖垮模型的表现。

2.3 KV-Cache:一个被忽视的性能杠杆

Manus 团队在生产环境中发现了一个关键指标:KV-Cache 命中率

KV-Cache 是 LLM 推理中的一种优化机制——如果两次请求的上下文前缀相同,之前计算过的中间结果可以被复用,大幅降低延迟和成本。以 Claude Sonnet 为例,缓存的输入 token 成本为 0.30 美元/百万 token,而未缓存的成本为 3 美元/百万 token——整整 10 倍差距。

Agent 系统天然具有长前缀重复的特点:系统提示词、工具定义在每一轮迭代中都不变,变化的是末尾追加的行动记录。这意味着 KV-Cache 的命中率直接影响 Agent 的响应速度和运行成本。

Manus 团队总结了三条实践原则:保持提示前缀稳定(避免在系统提示开头放时间戳这类每次都变的内容)、只追加不修改(确保序列化是确定性的)、显式标记缓存断点

三、四种失败模式

Weaviate 在其技术博客中系统梳理了上下文管理的四种典型失败模式。这些模式在 Anthropic 和 Manus 的工程实践中都能找到对应的实例。

3.1 上下文投毒(Context Poisoning)

错误的、有偏见的信息被引入上下文,导致后续所有推理都被污染。这与"幻觉"不同——投毒是系统性的,一条错误信息会像毒药一样扩散到整个推理链中。

典型场景:RAG 系统检索到了过时的文档,Agent 基于这些文档做出错误的决策,而后续步骤又引用了这些错误决策作为依据。

3.2 上下文干扰(Context Distraction)

上下文中存在大量正确但无关的信息,导致模型注意力被分散,忽略了真正关键的内容。

典型场景:Agent 需要查询一条用户记录,但检索返回了整个数据库的 schema 说明。虽然信息都是准确的,但模型在大量无关 schema 定义中难以准确定位到目标字段。

3.3 上下文混淆(Context Confusion)

来自不同来源或不同任务的信息在上下文中交织,导致模型产生跨领域的错误关联。

典型场景:在多轮对话中,用户先讨论了项目 A 的需求,然后转向项目 B。模型在回答项目 B 的问题时,错误地引用了项目 A 的上下文。

3.4 上下文冲突(Context Clash)

上下文中存在互相矛盾的信息,模型无法判断应该以谁为准。

典型场景:系统指令要求 Agent 以正式语气回复,但少样本示例中使用了轻松的口吻。两条信息在上下文中直接冲突,模型的行为变得不可预测。

四、上下文工程的核心策略

按照第一节介绍的四个类别,逐一看每个操作的具体实践。

4.1 写入(Write):精心构造输入

写入解决的问题是:在上下文中放入什么内容、以什么形式呈现。

系统提示词是写入中最关键的部分。Anthropic 强调要找到合适的粒度——系统提示既不能太抽象("你是一个有用的助手"),也不能过于冗长地列举每一个边界情况。好的系统提示应该在合适的抽象层次上提供清晰的行为指引。

渐进式披露是一种重要的写入策略:不是一次性把所有信息都塞进系统提示,而是根据任务进展动态添加相关信息。Anthropic 建议,只在模型需要某个信息时才将其引入上下文,而非"以防万一"地预加载。

Manus 的实践提供了一个有趣的角度:他们刻意设计了让 Agent 在执行复杂任务时创建 todo.md 文件、并在任务推进中持续更新的机制。这本质上是一种通过复述操控注意力的设计——Agent 不断将当前目标重写到上下文末尾,将全局计划推入模型最近的注意力范围内,避免"迷失在中间"的问题。这是一个精心设计的机制,而非偶然涌现的行为。

4.2 选择(Select):检索正确的信息

选择解决的问题是:从可用信息中挑选最相关的内容进入上下文。

RAG(检索增强生成)是最典型的选择机制。但有效的选择远不止"检索出最相似的 top-K 文档"。Anthropic 强调了"适时检索"(Just-in-time Retrieval)的重要性——不是在对话开始时就加载大量背景知识,而是在每一步决策时才检索当前步骤真正需要的信息。

工具定义的选择同样重要。随着 MCP 等协议让工具集成变得越来越容易,Agent 的工具空间可能迅速膨胀到数百个。Manus 团队发现,工具越多,模型选择错误工具的概率就越高——"你的全副武装的 Agent 变得更笨了"。

他们的解决方案不是动态增删工具,而是使用上下文感知的状态机来管理工具可用性,通过在解码阶段遮蔽 token logits 来约束模型的工具选择。这样既避免了修改工具定义导致的 KV-Cache 失效,又防止了模型在上下文中看到已被移除的工具引用时产生混淆。

4.3 压缩(Compress):控制上下文长度

压缩解决的问题是:在保留关键信息的前提下缩减上下文体积。

Anthropic 详细描述了两种压缩技术。第一种是 Compaction:当上下文接近长度限制时,用一个 LLM 调用将当前上下文总结为精简版本,然后用这个总结重新初始化一个干净的新上下文,继续执行。这种方法比简单的截断更安全,因为它保留了高层语义,而非粗暴地丢弃最新的信息。

第二种是结构化笔记(Structured Note-taking):在长程任务的执行过程中,让 Agent 定期生成结构化的中间总结,作为后续步骤的精简参考。与 Compaction 的"压缩后重启"不同,结构化笔记是"边走边记"——Agent 在保留原始上下文的同时,维护一份独立的摘要记录,在需要回顾时优先参考笔记而非重新扫描整个历史。

Manus 提出了一种更激进的压缩哲学:将文件系统视为终极上下文。文件系统天然具有无限容量、持久化、可直接操作三个特性。Agent 学会按需读写文件——不再把所有信息都塞进上下文窗口,而是将文件系统当作结构化的外部记忆。

关键的设计原则是:所有压缩都应该是可恢复的。网页内容可以从上下文中删除,只要 URL 被保留;文档内容可以省略,只要文件路径仍在沙箱中可用。这种"可逆压缩"让 Agent 能够在不永久丢失信息的前提下大幅缩短上下文长度。

4.4 隔离(Isolate):子代理架构

隔离解决的问题是:将不同的任务分解到独立的上下文中执行,避免上下文污染和膨胀。

Anthropic 推荐使用子代理架构(Sub-agent Architecture):主代理(Orchestrator)负责任务分解和结果汇总,子代理负责具体执行。每个子代理拥有独立的上下文窗口,只包含与当前子任务相关的信息。子代理完成后,只将最终结果返回给主代理,中间过程不污染主代理的上下文。

这种架构带来的好处是多方面的:每个上下文更短、更聚焦;子代理之间不会互相干扰;并行执行成为可能;且即使某个子代理的上下文出现了问题,也不会影响其他部分。

LangChain 在 LangGraph 中实现了这一模式:通过创建独立的状态图(StateGraph),每个子代理拥有自己的状态和上下文,主代理通过消息传递协调它们的工作。

五、保留错误与对抗模式固化

Manus 的两则实践洞察值得单独展开,因为它们挑战了常见的直觉。

5.1 保留错误记录

Agent 会犯错——这是现实,不是 bug。一个常见的反应是清理错误的执行痕迹、重试动作、或者重置模型状态。但这有一个隐性代价:擦除失败就是擦除证据。没有证据,模型就无法学习避免相同的错误。

Manus 团队发现,改善 Agent 行为最有效的方法之一出乎意料地简单:把错误留在上下文中。当模型看到一个失败的动作及其结果(如错误堆栈),它会隐式地调整内部判断,降低后续执行类似动作的概率。错误恢复能力是判断一个系统是否具备真正"智能体"特征的最清晰指标之一。

5.2 对抗 Few-shot 陷阱

Few-shot 提示是提升 LLM 输出质量的常见技术。但在 Agent 系统中,它可能适得其反。

语言模型是天生的模仿者。当上下文中充满了相似的"动作-观察"对时,模型倾向于延续这个模式——即使这个模式在当前步骤已经不是最优选择。例如,当 Manus 批量审查 20 份简历时,Agent 容易陷入节奏——因为上下文中看到的都是类似的操作,它就继续重复类似动作,导致漂移、过度泛化,甚至幻觉。

Manus 的应对方式是引入结构化变异:使用不同的序列化模板、改变措辞、在顺序和格式上添加微小噪声。这种受控的随机性帮助打破模式,让模型的注意力更均衡地分布。

六、总结

上下文工程正在成为 AI Agent 工程中与模型能力同等重要的维度。

回顾这一领域的核心洞察:写入决定了模型"看到什么",选择决定了什么信息"在正确的时刻被看到",压缩确保模型"不会看到太多",隔离确保不同的任务"不会互相干扰"。这四个操作构成了上下文管理的基本循环。

从工程实践的角度,Manus 团队的一句话精准概括了上下文工程的本质:你如何塑造上下文,最终定义了你的 Agent 如何表现——它运行多快、恢复多好、扩展多远。 模型也许会越来越强、越来越快、越来越便宜,但没有任何原始能力可以替代对记忆、环境和反馈的精心设计。

上下文工程仍然是一门年轻的学科。但有一点已经清晰:Agent 的能力上限由模型决定,而它的实际表现,取决于每一次上下文的工程质量。


主要参考资料