作者|LangChain
原文|https://blog.langchain.com/context-engineering-for-agents/
出品|码个蛋(ID:codeegg)
整理|陈宇明
智能体(Agents)执行任务需要上下文。上下文工程是在智能体运行轨迹的每个步骤中,为其上下文窗口填充恰到好处信息的艺术与科学。在本文中,我们通过回顾各类热门智能体及相关论文,拆解了上下文工程的几种常见策略——写入、选择、压缩和隔离。
大型语言模型(LLMs)就像一种新型操作系统。LLM好比中央处理器(CPU),其上下文窗口则类似随机存取存储器(RAM),充当着模型的工作内存。和RAM一样,LLM的上下文窗口容量有限,无法容纳所有来源的上下文信息。而正如操作系统会精心筛选适合存入CPU内存的内容,“上下文工程”也扮演着类似的角色。
【上下文工程是】“……一种精妙的艺术与科学,旨在为下一步操作的上下文窗口填充恰好所需的信息。”
在构建LLM应用时,我们需要管理哪些类型的上下文呢?上下文工程作为一个统称,涵盖了以下几种不同的上下文类型:
- 指令(Instructions)——提示词、记忆、少样本示例、工具描述等
- 知识(Knowledge)——事实、记忆等
- 工具(Tools)——工具调用的反馈
今年,随着LLM在推理和工具调用能力上的提升,人们对智能体的兴趣急剧增长。智能体将LLM调用与工具调用交织进行,通常用于处理长期任务。它们通过工具反馈来决定下一步行动,形成“LLM调用—工具调用—工具反馈—LLM调用”的循环。
然而,长期任务的执行以及工具调用反馈的不断累积,意味着智能体往往会消耗大量tokens。这可能引发诸多问题:超出上下文窗口容量、成本/延迟飙升,或导致智能体性能下降。德鲁·布赖尼格(Drew Breunig)清晰地列出了长上下文可能导致的具体性能问题,包括:
- 上下文污染(Context Poisoning):幻觉信息混入上下文
- 上下文干扰(Context Distraction):上下文内容过多超出模型训练适应范围
- 上下文混淆(Context Confusion):冗余上下文影响响应结果
- 上下文冲突(Context Clash):上下文各部分信息相互矛盾
工具调用产生的上下文会在智能体的多轮交互中不断累积。
鉴于此,Cognition公司强调了上下文工程的重要性:
“上下文工程”……实际上是构建AI智能体的工程师的首要工作。
Anthropic公司也明确指出:
智能体通常会参与数百轮的对话,这需要精心的上下文管理策略。
那么,如今人们是如何应对这一挑战的呢?我们将智能体上下文工程的常见策略归纳为四类——写入、选择、压缩和隔离,并通过回顾热门智能体产品和相关论文,为每种策略提供实例。随后,我们将阐释LangGraph是如何为这些策略提供支持的!
写入上下文指将信息存储在上下文窗口之外,以帮助智能体执行任务。
人类解决任务时会做笔记,以便记住未来相关任务的信息。智能体也正在获得这种能力!通过“便签本”做笔记是一种在智能体执行任务时持久化信息的方法。其核心思路是将信息存储在上下文窗口之外,确保智能体可随时获取。Anthropic的多智能体研究案例就清晰展示了这一点:
首席研究员(LeadResearcher)首先思考方法,并将计划保存到“记忆(Memory)”中以持久化上下文,因为如果上下文窗口超过200,000个tokens就会被截断,而保留计划至关重要。
便签本的实现方式有多种:可以是简单写入文件的工具调用,也可以是会话期间持久化的运行时状态对象中的字段。无论哪种方式,便签本都能让智能体保存有用信息,助力任务完成。
便签本帮助智能体在特定会话(或线程)内解决任务,但有时智能体需要跨多个会话记住信息!Reflexion提出了在智能体每轮交互后进行反思,并复用这些自主生成记忆的理念。生成式智能体(Generative Agents)则会从过往智能体反馈集合中定期合成记忆。
这些概念已被应用到热门产品中,如ChatGPT、Cursor和Windsurf,它们都具备基于用户与智能体的交互,自动生成可跨会话持久化的长期记忆的机制。
选择上下文指将外部信息拉入上下文窗口,以辅助智能体执行任务。
从便签本中选择上下文的机制取决于便签本的实现方式。如果是工具型便签本,智能体可通过工具调用直接读取;如果是智能体运行时状态的一部分,开发者可选择在每一步向智能体暴露状态的哪些部分。这为在后续交互中向LLM暴露便签本上下文提供了精细的控制能力。
如果智能体能够存储记忆,那么它也需要具备选择与当前任务相关记忆的能力。这有诸多用处:智能体可能会选择少样本示例(情节记忆)作为期望行为的范例、选择指令(程序记忆)来引导行为,或选择事实(语义记忆)作为任务相关的上下文。
记忆类型 | 存储内容 | 人类示例 | 智能体示例 |
---|---|---|---|
语义记忆 | 事实 | 学校学到的知识 | 关于用户的事实 |
情节记忆 | 经历 | 亲身做过的事 | 智能体过往的行为 |
确保选择相关记忆是一项挑战。一些热门智能体仅使用一小组固定文件,这些文件始终会被拉入上下文。例如,许多代码智能体会使用特定文件保存指令(“程序”记忆),在某些情况下还会保存示例(“情节”记忆)。Claude Code使用`CLAUDE.md`文件,Cursor和Windsurf则使用规则文件。
但如果智能体存储了大量事实和/或关系(如语义记忆),选择就会变得更困难。ChatGPT是一个典型例子,作为热门产品,它需要从大量用户特定记忆中进行存储和选择。
嵌入(Embeddings)和/或知识图谱常用于记忆索引,辅助记忆选择。尽管如此,记忆选择仍颇具挑战。在AI工程师世界博览会上,西蒙·威利森(Simon Willison)分享了一个选择失误的例子:ChatGPT从记忆中获取了他的位置信息,并意外地将其注入到用户请求生成的图像中。这种意外或非期望的记忆检索可能会让用户感觉上下文窗口“不再属于自己”!
智能体会使用工具,但如果提供的工具过多,它们可能会不堪重负。这通常是因为工具描述存在重叠,导致模型难以确定使用哪种工具。一种解决方法是将检索增强生成(RAG)应用于工具描述,仅获取与当前任务最相关的工具。近期一些论文表明,这种方法可将工具选择准确率提高3倍。
RAG是一个丰富的主题,也是上下文工程的核心挑战之一。代码智能体是大规模生产环境中应用RAG的典范。来自Windsurf的瓦伦(Varun)精准概括了其中的一些挑战:
代码索引≠上下文检索……我们正在进行索引和嵌入搜索……通过AST解析代码,并沿着语义有意义的边界进行分块……随着代码库规模增长,嵌入搜索作为检索启发式方法会变得不可靠……我们必须依赖多种技术的组合,如grep/文件搜索、基于知识图谱的检索,以及……对[上下文]按相关性排序的重排序步骤。
压缩上下文指仅保留执行任务所需的tokens。
智能体交互可能跨越数百轮,且工具调用会消耗大量tokens。总结是应对这些挑战的常见方法。如果你使用过Claude Code,可能已经见过这种机制:当上下文窗口使用率超过95%时,Claude Code会运行“自动压缩(auto-compact)”功能,总结用户与智能体交互的完整轨迹。这种跨智能体轨迹的压缩可采用多种策略,如递归总结或分层总结。
总结也可应用于智能体设计的特定节点。例如,可用于后处理某些工具调用(如消耗大量tokens的搜索工具);再如,Cognition公司提到在智能体之间的知识交接时进行总结,以减少tokens消耗。若需要捕捉特定事件或决策,总结会面临挑战。Cognition公司为此使用了微调模型,这凸显了这一步骤所需的工作量。
与总结通常使用LLM提炼上下文最相关部分不同,修剪通常可通过过滤或如德鲁·布赖尼格所指出的“修剪(prune)”来实现。这可采用硬编码启发式规则,如从列表中移除较旧的消息。德鲁还提到了Provence,这是一种用于问答任务的训练型上下文修剪器。
隔离上下文指拆分上下文,以帮助智能体执行任务。
隔离上下文最流行的方法之一是在子智能体之间拆分上下文。OpenAI Swarm库的设计动机之一是关注点分离,即由一组智能体处理特定子任务。每个智能体拥有特定的工具集、指令和独立的上下文窗口。
Anthropic的多智能体研究证明了这一点:具有隔离上下文的多个智能体的性能优于单个智能体,这很大程度上是因为每个子智能体的上下文窗口可专注于更具体的子任务。正如博客中所述:
【子智能体】以各自的上下文窗口并行运行,同时探索问题的不同方面。
当然,多智能体面临的挑战包括tokens使用量(如Anthropic报告的tokens消耗高达普通聊天的15倍)、需要精心设计提示词以规划子智能体工作,以及子智能体之间的协调问题。
HuggingFace的深度研究员(deep researcher)展示了另一个有趣的上下文隔离示例。大多数智能体使用工具调用API,这些API返回可传递给工具(如搜索API)的JSON对象(工具参数),以获取工具反馈(如搜索结果)。HuggingFace使用代码智能体(CodeAgent),其输出包含所需的工具调用。代码随后在沙箱中运行,工具调用的选定上下文(如返回值)会传递回LLM。
这允许上下文在环境中与LLM隔离。HuggingFace指出,这是隔离大量tokens对象的极佳方式:
【代码智能体】能更好地处理状态……需要存储此图像/音频/其他内容供以后使用?没问题,只需将其分配为状态中的变量,之后就可以[使用它]。
值得一提的是,智能体的运行时状态对象也是隔离上下文的好方法,其作用类似于沙箱。状态对象可设计为具有特定 schema 的结构,其中包含可写入上下文的字段。schema 的某个字段(如`messages`)可在智能体每轮交互中暴露给LLM,而schema 可将其他字段中的信息隔离,以供更有选择性地使用。
上下文工程正成为智能体构建者应着力掌握的技能。本文涵盖了当今众多热门智能体中常见的几种模式: