【译】上下文工程:别把窗塞满越多越糟!用写筛压隔四步,警惕投毒干扰混淆冲突,把噪声挡窗外——慢慢学AI170
写在前面
- AI 智能体的上限,不只看模型大小,更看“上下文管理”这门手艺。它就像为 CPU 配置内存,决定了智能体思考的深度和效率。
- 上下文窗口不是垃圾桶:信息过载会“投毒”、干扰、混淆 AI 的判断。精准,远比海量更重要。
- 高手用“写、筛、压、隔”四字诀管理 AI 上下文,把有限的“内存”用在刀刃上,实现降本增效。
- 未来的竞争是系统效率的竞争。用多智能体架构“隔离”任务,让每个智能体在自己的小窗口里做到极致,是构建复杂任务系统的关键。
核心摘要
智能体(Agent)执行任务离不开上下文(Context)。所谓“上下文工程”,正是在智能体执行任务的每一步,都为其上下文窗口精准注入恰当信息的艺术与科学。本文将当下主流智能体所采用的上下文工程策略,归纳为几大通用模式。
上下文工程(Context Engineering)
正如 Andrej Karpathy 所说,大语言模型(LLM)就像一种“新型操作系统”。LLM 是 CPU,而它的“上下文窗口”就是 RAM,充当着模型的工作记忆。正如 RAM 的容量有限,LLM 的上下文窗口在处理各种上下文来源时也面临容量瓶颈。操作系统的核心工作之一是管理如何高效使用 CPU 的 RAM,而“上下文工程”也扮演着类似的角色。Karpathy 对此总结得非常到位:
上下文工程是“……一门为下一步(计算)精准填充上下文窗口的精妙艺术与科学。”
在构建 LLM 应用时,我们需要管理哪些类型的上下文呢?上下文工程这个总括性概念,涵盖了以下几种不同的上下文类型:
- • 指令(Instructions) – 提示词、记忆、少样本示例、工具描述等
- • 知识(Knowledge) – 事实、记忆等
- • 工具(Tools) – 工具调用的反馈信息
面向智能体的上下文工程
今年,随着 LLM 在推理和工具调用方面能力的提升,人们对智能体的兴趣与日俱增。智能体通过交替调用 LLM 和工具来执行任务,尤其擅长处理长期运行的复杂任务。
然而,长期任务和不断累积的工具调用反馈,意味着智能体通常会消耗大量的 token。这可能引发诸多问题:超出上下文窗口的容量限制、导致成本和延迟激增,甚至降低智能体性能。Drew Breunig 曾清晰地指出,过长的上下文可能通过以下几种方式导致性能问题:
- • 上下文投毒(Context Poisoning):当幻觉(错误信息)进入上下文时。
- • 上下文干扰(Context Distraction):当上下文信息过多,淹没了模型的原始训练知识时。
- • 上下文混淆(Context Confusion):当无关的上下文信息影响了模型的响应时。
- • 上下文冲突(Context Clash):当上下文中的不同部分相互矛盾时。
考虑到这些问题,Cognition AI 公司强调了上下文工程的重要性:
“上下文工程”……实际上是构建 AI 智能体的工程师的首要任务。
Anthropic 公司也明确指出:
智能体通常需要进行数百轮的对话,这要求我们采用审慎的上下文管理策略。
那么,如今的开发者们是如何应对这一挑战的呢?我将现有方法归纳为四大类——写入(Write)、筛选(Select)、压缩(Compress)和隔离(Isolate)——并分别举例说明。
写入上下文(Write Context)
写入上下文,指将信息保存在上下文窗口之外,以备智能体执行任务时使用。
暂存区(Scratchpads)
人类在解决问题时,会做笔记并记住一些事,以便在未来处理相关任务时使用。智能体也正逐渐获得这些能力!通过“暂存区”做笔记,就是一种在智能体执行任务期间持久化信息的方法。其核心思想是将信息保存在上下文窗口之外,但又能随时供智能体取用。Anthropic 的多智能体研究系统就提供了一个清晰的例子:
“首席研究员”首先会思考解决问题的方法,并将其计划保存到“记忆”中以持久化上下文,因为一旦上下文窗口超过 20 万 token 就可能被截断,而保留计划至关重要。
暂存区的实现方式有多种。它可以是一个简单的工具调用,比如写入一个文件;也可以是运行时状态对象中的一个字段,在整个会话期间保持不变。无论哪种方式,暂存区都让智能体能够保存有用信息,以更好地完成任务。
记忆(Memories)
暂存区帮助智能体在单次会话中解决任务,但有时智能体需要跨越多次会话记住事情。Reflexion 模型引入了在每轮智能体行动后进行反思,并复用这些自我生成记忆的理念。Generative Agents 模型则能从过去智能体的反馈集合中,周期性地合成记忆。
这些概念已被应用于 ChatGPT、Cursor 和 Windsurf 等流行产品中。它们都具备基于用户与智能体交互,自动生成长期记忆的机制。
筛选上下文(Select Context)
筛选上下文,指将所需信息调入上下文窗口,以帮助智能体执行任务。
暂存区(Scratchpad)
从暂存区筛选上下文的机制,取决于其实现方式。如果它是一个工具,智能体只需通过工具调用来读取。如果它是智能体运行时状态的一部分,开发者就可以在每一步选择性地将状态的某些部分暴露给智能体。这为后续回合中向 LLM 提供暂存区上下文提供了精细的控制。
记忆(Memories)
如果智能体有能力保存记忆,它们也需要能力来筛选与当前任务相关的记忆。这非常有用,原因有几点:智能体可以选择少样本示例(情景记忆)来学习期望的行为模式;可以选择指令(程序记忆)来引导自身行为;或者选择事实(语义记忆)来为任务提供相关背景。
一大挑战是确保筛选出的记忆是相关的。一些流行的智能体仅使用一小部分固定的文件,这些文件总是被加载到上下文中。例如,许多代码智能体使用文件来保存指令(“程序记忆”),或在某些情况下保存示例(“情景记忆”)。Claude Code 使用 CLAUDE.md
,而 Cursor 和 Windsurf 则使用规则文件。
但是,如果智能体存储了大量的(例如“语义记忆”类型的)事实或关系,筛选就变得更加困难。ChatGPT 是一个很好的例子,它存储并从大量用户专属记忆中进行筛选。
向量嵌入和/或知识图谱是常用的记忆索引技术,以辅助筛选。尽管如此,记忆筛选仍然充满挑战。在 AIEngineer 世界博览会上,Simon Willison 分享了一个记忆筛选出错的例子:ChatGPT 从记忆中获取了他的位置信息,并意外地将其注入到他要求的图片中。这种意料之外或不希望发生的记忆检索,会让一些用户感觉上下文窗口“不再属于他们自己”!
工具(Tools)
智能体需要使用工具,但如果提供的工具过多,它们可能会不堪重负。这通常是因为工具描述可能重叠,导致模型在选择哪个工具时感到困惑。一种方法是对工具描述应用 RAG(检索增强生成),根据语义相似性为任务检索最相关的工具。最近的一些论文表明,这种方法能将工具选择的准确率提高 3 倍。
知识(Knowledge)
检索增强生成(RAG)本身就是一个宏大的课题,并且可以成为上下文工程的核心挑战。代码智能体是 RAG 在大规模生产应用中的最佳范例之一。Windsurf 的 Varun 很好地概括了其中的一些挑战:
索引代码 ≠ 上下文检索……我们正在做的,是通过 AST(抽象语法树)解析代码,并沿着有语义意义的边界进行分块……但随着代码库规模的增长,向量嵌入搜索作为一种检索启发式方法变得不可靠……我们必须依赖多种技术的组合,如 grep/文件搜索、基于知识图谱的检索,以及……一个重排序步骤,其中上下文会按相关性排序。
压缩上下文(Compress Context)
压缩上下文,指仅保留执行任务所必需的 token。
上下文总结(Context Summarization)
智能体的交互可能跨越数百轮,并使用消耗大量 token 的工具。总结是应对这些挑战的常用方法。如果你用过 Claude Code,你已经见过它的实际应用。当上下文窗口使用率超过 95% 时,Claude Code 会运行“自动压缩”,对用户与智能体的完整交互轨迹进行总结。这种对智能体轨迹的压缩可以采用多种策略,例如递归总结或分层总结。
在智能体的设计中适时加入总结步骤也很有用。例如,它可以用于后处理某些工具的调用(特别是像搜索工具这类消耗大量 token 的工具)。再比如,Cognition 公司提到在智能体与智能体交接的边界处进行总结,以减少知识传递过程中的 token 消耗。如果需要捕捉特定的事件或决策,总结可能会很有挑战性。Cognition 为此使用了一个微调模型,这凸显了这一步骤可能需要投入的大量工作。
上下文修剪(Context Trimming)
总结通常使用 LLM 来提炼最相关的上下文片段,而修剪则更像是过滤或如 Drew Breunig 所说的“剪枝”上下文。这可以采用硬编码的启发式规则,比如从消息列表中移除较早的消息。Drew 还提到了 Provence,一个为问答任务训练的上下文剪枝器。
隔离上下文(Isolating Context)
隔离上下文,指将上下文拆分,以帮助智能体执行任务。
多智能体(Multi-agent)
隔离上下文最流行的方式之一,就是将其分散到多个子智能体中。OpenAI 的 Swarm 库的一个动机就是“关注点分离”,即由一个智能体团队来处理子任务。每个智能体都有自己特定的工具集、指令和独立的上下文窗口。
Anthropic 的多智能体研究系统为此提供了有力论证:多个拥有独立上下文的智能体,其表现优于单个智能体,很大程度上是因为每个子智能体的上下文窗口可以专注于一个更狭窄的子任务。正如其博客所述:
子智能体们带着各自的上下文窗口并行运作,同时探索问题的不同方面。
当然,多智能体也面临挑战,包括 token 的消耗(例如,Anthropic 报告称其 token 使用量是聊天的 15 倍)、需要精心的提示工程来规划子智能体的工作,以及子智能体之间的协调问题。
通过环境隔离上下文(Context Isolation with Environments)
HuggingFace 的深度研究员项目展示了另一个有趣的上下文隔离例子。大多数智能体使用工具调用 API,这些 API 返回 JSON 对象(工具参数),然后传递给工具(如搜索 API)以获取反馈(如搜索结果)。HuggingFace 则使用一个 CodeAgent,它直接输出包含所需工具调用的代码。这些代码随后在一个沙箱环境中运行。工具调用返回的特定上下文(如返回值)才被传回给 LLM。
这使得上下文可以在环境中与 LLM 隔离。Hugging Face 指出,这是一种隔离消耗大量 token 的对象的绝佳方式:
Code Agents 能够更好地处理状态……需要存储图像/音频/其他数据以备后用?没问题,只需将其分配为一个变量,你就可以稍后使用它。
状态(State)
值得一提的是,智能体的运行时状态对象也是隔离上下文的好方法。这可以起到与沙箱类似的作用。状态对象可以设计一个模式(Schema,例如 Pydantic 模型),其中包含可以写入上下文的字段。模式中的一个字段(如 messages
)可以在智能体的每一轮交互中暴露给 LLM,但模式可以将信息隔离在其他字段中,以便更具选择性地使用。
结论
智能体上下文工程的模式仍在不断演进,但我们可以将常见方法归纳为四大类——写入、筛选、压缩和隔离:
- • 写入上下文,指将信息保存在上下文窗口之外,以备智能体执行任务时使用。
- • 筛选上下文,指将所需信息调入上下文窗口,以帮助智能体执行任务。
- • 压缩上下文,指仅保留执行任务所必需的 token。
- • 隔离上下文,指将上下文拆分,以帮助智能体执行任务。
理解并运用这些模式,是当今构建高效智能体的核心工作。