面向 AI 智能体的高效上下文工程

原文:https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents/

在应用人工智能领域,经过几年的提示工程(prompt engineering)成为关注焦点后,一个新的术语开始崭露头角:上下文工程(context engineering)。使用语言模型进行构建不再仅仅是寻找提示中的正确词语和短语,而更多地是回答一个更广泛的问题:”什么样的上下文配置最有可能让模型产生我们期望的行为?”

上下文指的是从大型语言模型(LLM)采样时包含的 token 集合。工程问题在于针对 LLM 的固有约束优化这些 token 的效用,以持续实现期望的结果。有效驾驭 LLM 通常需要在上下文中思考——换句话说:考虑 LLM 在任何给定时间可用的整体状态,以及该状态可能产生的潜在行为。

在这篇文章中,我们将探讨上下文工程这一新兴艺术,并为构建可操控、有效的智能体提供精炼的心智模型。

在 Anthropic,我们将上下文工程视为提示工程的自然演进。提示工程指的是编写和组织 LLM 指令以获得最佳结果的方法(请参阅 我们的文档 以获取概述和有用的提示工程策略)。上下文工程指的是在 LLM 推理过程中策划和维护最优 token(信息)集合的策略集合,包括可能出现在提示之外的所有其他信息。

在 LLM 工程的早期阶段,提示是 AI 工程工作的最大组成部分,因为除了日常聊天交互之外的大多数用例都需要针对一次性分类或文本生成任务优化的提示。顾名思义,提示工程的主要焦点是如何编写有效的提示,特别是系统提示。然而,随着我们朝着构建更强大的智能体方向发展,这些智能体在多次推理轮次和更长的时间范围内运行,我们需要管理整个上下文状态的策略(系统指令、工具、模型上下文协议(Model Context Protocol,MCP)、外部数据、消息历史等)。

在循环中运行的智能体会生成越来越多的数据,这些数据 可能 与下一轮推理相关,这些信息需要持续优化与筛选。上下文工程是从不断演变的可能信息宇宙中策划将进入有限上下文窗口的内容的 艺术和科学

图 1:提示工程与上下文工程

与编写提示的离散任务相比,上下文工程是迭代的,策划阶段每次在我们决定传递给模型的内容时发生。

为什么上下文工程对构建强大智能体很重要

尽管 LLM 具有速度和处理越来越大数据量的能力,但我们观察到 LLM 像人类一样,在某个时刻会失去焦点或感到困惑。“针在干草堆”式基准测试的研究揭示了 上下文衰减(context rot)的概念:随着上下文窗口中 token 数量的增加,模型准确回忆该上下文中信息的能力会下降。

虽然某些模型的衰减比其他模型更温和,但这种特性在所有模型中都会出现。因此,上下文必须被视为具有递减边际收益的有限资源。像具有 有限工作记忆容量 的人类一样,LLM 有一个“注意力预算(attention budget)”,在解析大量上下文时会消耗这个预算。每个新引入的 token 都会在一定程度上消耗这个预算,增加了仔细策划可供 LLM 使用的 token 的需求。

这种注意力稀缺源于 LLM 的架构约束。LLM 基于 Transformer 架构,该架构使每个 token 能够 关注整个上下文中的每个其他 token。这导致 n 个 token 产生 n² 个成对关系。

随着上下文长度的增加,模型捕获这些成对关系的能力会变得受限,在上下文大小和注意力焦点之间形成天然的张力。此外,模型从训练数据分布中发展出注意力模式,其中较短的序列通常比较长的序列更常见。这意味着模型对上下文范围依赖性的经验较少,专门参数也较少。

位置编码插值(Position Interpolation)这样的技术允许模型通过将它们适应到最初训练的较小上下文来处理更长的序列,尽管在 token 位置理解方面会有一些退化。这些因素创造了性能梯度而不是硬性悬崖:模型在较长的上下文中仍然具有强大的能力,但在信息检索和长程推理方面的精度可能比在较短上下文中的性能有所降低。

这些现实意味着周密的上下文工程对于构建强大的智能体至关重要。

有效上下文的解剖结构

鉴于 LLM 受到有限注意力预算的约束,良好的上下文工程意味着找到最小可能的高信号 token 集合,以最大化某些期望结果的可能性。实施这一实践说起来容易做起来难,但在以下部分中,我们概述了这一指导原则在不同上下文组件中的实际含义。

系统提示应该极其清晰,并使用简单、直接的语言,以正确的高度为智能体呈现想法。正确的高度是介于两种常见失败模式之间的 Goldilocks 区域【注:指恰到好处的区间】。在一个极端,我们看到工程师在提示中硬编码复杂、脆弱的逻辑以实现精确的智能体行为。这种方法会创建脆弱性,并随着时间的推移增加维护复杂性。在另一个极端,工程师有时提供模糊、高级别的指导,无法为 LLM 提供期望输出的具体信号,或者错误地假设了共享上下文。最优高度达到了平衡:足够具体以有效指导行为,又足够灵活以为模型提供强大的启发式方法来指导行为。

图 2:在上下文工程过程中校准系统提示

在频谱的一端,我们看到脆弱的 if-else 硬编码提示,在另一端我们看到过于笼统或错误假设共享上下文的提示。

我们建议将提示组织成不同的部分(如 <background_information><instructions>## 工具指导## 输出描述 等),并使用 XML 标记或 Markdown 标题等技术来划分这些部分,尽管随着模型能力的提高,提示的确切格式可能变得不那么重要。

无论您决定如何构建系统提示,都应该努力实现完全概述期望行为的最小信息集。(请注意,最小不一定意味着简短;您仍然需要为智能体提供足够的信息,以确保它遵循期望的行为。)最好从使用最佳可用模型测试最小提示开始,看看它在您的任务上的表现如何,然后根据初始测试中发现的失败模式添加清晰的指令和示例来改进性能。

工具允许智能体与其环境交互,并在工作时引入新增上下文。因为工具定义了智能体与其信息/行动空间之间的契约,因此必须高度强调效率:既要返回 token 高效的信息,又要引导智能体采取高效行为。

为 AI 智能体编写工具——与 AI 智能体一起 中,我们讨论了构建 LLM 易于理解且功能重叠最少的工具。与设计良好的代码库的功能类似,工具应该是自包含的、对错误具有鲁棒性,并且在其预期用途方面极其清晰。输入参数同样应该是描述性的、明确的,并发挥模型的固有优势。

我们看到的最常见的失败模式之一是臃肿的工具集,这些工具集覆盖了太多功能,或者导致关于使用哪个工具的模糊决策点。如果人类工程师无法明确说出在给定情况下应该使用哪个工具,那么就不能期望 AI 智能体做得更好。正如我们稍后将讨论的,为智能体策划一个最小可行工具集也可以导致在长时间交互中更可靠的维护和上下文修剪。

提供示例,也称为少样本提示(few-shot prompting),是我们继续强烈建议的众所周知的最佳实践。然而,团队经常将一长串边缘案例塞入提示中,试图阐明 LLM 应该为特定任务遵循的所有可能规则。我们不推荐这样做。相反,我们建议努力策划一组多样化、规范的示例,有效地描绘智能体的期望行为。对于 LLM 而言,示例相当于 “一图胜千言”。

我们在不同上下文组件(系统提示、工具、示例、消息历史等)方面的总体指导是:要深思熟虑,保持您的上下文信息丰富但又紧凑。现在让我们深入探讨在运行时动态检索上下文。

上下文检索和智能体搜索

构建有效的 AI 智能体 中,我们强调了基于 LLM 的工作流和智能体之间的区别。自从我们写了那篇文章以来,我们倾向于对智能体采用一个 简单的定义:在循环中自主使用工具的 LLM。

与客户合作的过程中,我们看到该领域正在向这个简单范式汇聚。随着底层模型变得更强大,智能体的自主水平可以扩展:更聪明的模型允许智能体独立导航细微的问题空间并从错误中恢复。

我们现在看到工程师在设计智能体上下文的方式上发生了转变。今天,许多 AI 原生应用程序采用某种形式的基于嵌入的推理前检索来为智能体提供重要的上下文进行推理。随着该领域向更多智能体方法过渡,我们越来越多地看到团队用 “即时(just-in-time)” 上下文策略增强这些检索系统。

与预先处理所有相关数据不同,采用“即时”方法构建的智能体维护轻量级标识符(文件路径、存储的查询、网络链接等),并使用这些引用通过工具在运行时动态将数据加载到上下文中。Anthropic 的智能体编码解决方案 Claude Code 使用这种方法对大型数据库执行复杂的数据分析。模型可以编写有针对性的查询,存储结果,并利用像 head 和 tail 这样的 Bash 命令来分析大量数据,而无需将完整的数据对象加载到上下文中。这种方法反映了人类认知:我们通常不会记忆整个信息库,而是引入外部组织和索引系统,如文件系统、收件箱和书签,以按需检索相关信息。

除了存储效率之外,这些引用的元数据也提供了优化行为的有效机制;这些信号既可能是显式的,也可能是隐式的。对于在文件系统中操作的智能体,tests 文件夹中名为 test_utils.py 的文件的存在暗示了与位于 src/core_logic/ 中同名文件不同的目的。文件夹层次结构、命名约定和时间戳都提供了重要的信号,帮助人类和智能体理解如何以及何时利用信息。

让智能体自主导航和检索数据还支持渐进式披露(progressive disclosure)——换句话说,允许智能体通过探索逐步发现相关上下文。每次交互都会产生为下一个决策提供信息的上下文:文件大小暗示复杂性;命名约定暗示目的;时间戳可以作为相关性的替代指标。智能体可以逐层构建理解,仅在工作记忆(working memory)中维护必要的内容,并利用笔记策略实现额外的持久性。这种自我管理的上下文窗口使智能体专注于相关子集,而不是淹没在详尽但可能无关的信息中。

当然,这里有一个权衡:运行时探索比检索预先检索到的数据更慢。不仅如此,还需要有方向性且周密的工程设计,来确保 LLM 拥有正确的工具和启发式方法,以便有效地导航其信息景观。没有适当的指导,智能体可能会通过误用工具、追逐死胡同或未能识别关键信息而耗尽上下文预算。

在某些设置中,最有效的智能体可能采用混合策略,预先检索一些数据以提高速度,并根据其判断进行进一步的自主探索。自主的“正确”水平的决策边界取决于任务。Claude Code 是一个采用这种混合模型的智能体: CLAUDE.md 文件被直接预置到上下文中,而像 glob 和 grep 这样的原语允许它导航其环境并即时检索文件,有效绕过陈旧索引和复杂语法树的问题。

混合策略可能更适合内容动态性较低的上下文,如法律或金融工作。随着模型能力的提高,智能体设计将趋向于让更智能的模型更自主地行动,逐渐减少人工策划。鉴于该领域的快速发展, “do the simplest thing that could possibly work” 可能仍然是我们为在 Claude 之上构建智能体的团队提供的最佳建议。

长时域任务的上下文工程

长时域任务要求智能体在 token 计数超过 LLM 上下文窗口的动作序列中保持连贯性、上下文和目标导向行为。对于跨越数十分钟到数小时连续工作的任务,如大型代码库迁移或综合研究项目,智能体需要专门的技术来绕过上下文窗口大小限制。

等待更大的上下文窗口可能看起来是一个明显的策略。但很可能在可预见的未来,所有大小的上下文窗口都会受到上下文污染(context pollution)和信息相关性问题的困扰——至少在需要最强智能体性能的情况下。为了使智能体能够在扩展的时间范围内有效工作,我们开发了一些直接解决这些上下文污染约束的技术:压缩、结构化笔记和多智能体架构。

压缩(compaction)

压缩是一种实践:当对话接近上下文窗口上限时,对其内容进行总结,并用该摘要重新初始化新的上下文窗口。压缩通常作为上下文工程中的第一个杠杆,以推动更好的长期连贯性。压缩的核心是以高保真方式提炼上下文窗口的内容,使智能体能够以最小的性能降级继续工作。

例如,在 Claude Code 中,我们将消息历史传递给模型,请其对关键细节进行总结与压缩,从而实现这一点。模型保留架构决策、未解决的错误和实施细节,同时丢弃冗余的工具输出或消息。然后智能体可以继续使用这个压缩后的上下文,并结合最近访问的五个文件。用户获得连续性,而无需担心上下文窗口限制。

压缩的艺术在于选择保留什么与丢弃什么,因为过于激进的压缩可能导致微妙但关键上下文的丢失,这些上下文的重要性只有在后来才变得明显。对于实施压缩系统的工程师,我们建议围绕复杂智能体的状态跟踪,仔细调优您的压缩提示。首先最大化召回率,确保您的压缩提示捕获跟踪中的每个相关信息,然后迭代以提高精度,消除多余内容。

最易清理的冗余之一是清除久远的工具调用及其结果——一旦一个工具在消息历史深处被调用,为什么智能体需要再次看到原始结果?最安全、最轻量级的压缩形式之一是工具结果清除,最近作为 Claude 开发者平台上的功能 推出。

结构化笔记(structured note-taking)

结构化笔记(structured note-taking),或称智能体记忆(agent memory),是一种技术:智能体会定期将笔记持久化到上下文窗口之外的存储中,并在之后的时刻将这些笔记重新拉回到上下文窗口。

这种策略以最小的开销提供持久记忆。像 Claude Code 创建待办事项列表,或您的自定义智能体维护 NOTES.md 文件一样,这种简单模式允许智能体跟踪复杂任务的进度,维护关键上下文和依赖关系;否则这些信息会在数十次工具调用中丢失。

Claude 玩宝可梦展示了记忆如何在非编码领域改变智能体能力。智能体在数千个游戏步骤中保持精确的计数——例如:“在过去的 1,234 步中,我一直在 1 号道路训练我的宝可梦,皮卡丘已经向 10 级的目标提升了 8 级。”无需任何关于记忆结构的提示,它自行形成了已探索区域的地图,记住了已解锁的关键成就,并维护战斗策略的战略笔记,帮助它了解哪些攻击对不同对手最有效。

在上下文重置后,智能体读取自己的笔记并继续多小时的训练序列或地下城探索。这种跨摘要步骤的连贯性实现了长时域策略,这在将所有信息保留在 LLM 的上下文窗口中是不可能的。

作为我们 Sonnet 4.5 发布 的一部分,我们在 Claude 开发者平台上发布了 一个记忆工具 的公开测试版,通过基于文件的系统,使在上下文窗口之外存储和查询信息更加容易。这允许智能体随时间构建知识库,跨会话维护项目状态,并在需要时复用先前的工作成果,而无需将所有内容保留在上下文中。

子智能体架构(sub-agent architecture)

子智能体架构提供了另一种绕过上下文限制的方法。与其让一个智能体尝试在整个项目中维护状态,专门的子智能体可以用干净的上下文窗口处理重点任务。主智能体协调高级计划,而子智能体执行具体实施。这种方法将复杂问题分解为更小、更易管理的部分,每个部分都有自己的优化上下文。

通过将责任分配给专门的子智能体,系统可以保持每个智能体的上下文窗口精简和专注,减少上下文污染并提高整体效率。子智能体可以专注于特定领域,如代码生成、测试或文档,而主智能体维护高级战略和监督。

这种架构特别适合大型、复杂的项目,其中单一智能体难以维护所有必要的上下文。通过分工,系统可以更有效地扩展,同时保持每个组件的性能和可靠性。


结论

上下文工程代表了我们使用 LLM 构建方式的一次根本性转变。随着模型能力不断提升,挑战不再只是打造完美的提示——而是在每一步谨慎策划进入模型有限“注意力预算”的信息。无论是为长时域任务实施压缩、设计 token 高效的工具,还是让智能体以 “即时” 方式探索其环境,指导原则始终不变:找到最小的高信号 token 集合,以最大化实现期望结果的可能性。

我们概述的这些技术会随着模型的进步而持续演化。我们已经看到,更聪明的模型需要更少的规定性工程,使智能体能够以更高的自主性运行。但即使能力不断扩展,将上下文视为稀缺、有限的资源,仍将是构建可靠且高效智能体的核心。

现在就通过 Claude 开发者平台开始进行上下文工程吧,并通过我们的 memory and context management cookbook 获取有用的技巧和最佳实践。

致谢

本文由 Anthropic 的 Applied AI 团队撰写:Prithvi Rajasekaran、Ethan Dixon、Carly Ryan 和 Jeremy Hadfield;并得到团队成员 Rafi Ayub、Hannah Moran、Cal Rueb 和 Connor Jennings 的贡献。特别感谢 Molly Vorwerck、Stuart Ritchie 和 Maggie Vo 的支持。