Skip to content

【翻译】上下文工程在 AI 智能体中的最佳实践

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

上下文是 AI 智能体的关键但有限的资源。本文将探讨如何有效策划和管理驱动智能体运行的上下文。

在应用人工智能领域,提示词工程(Prompt Engineering)成为焦点数年之后,一个新的术语正逐渐崭露头角:上下文工程(Context Engineering)。使用语言模型进行构建,已不再仅仅是寻找提示词中的恰当词语和短语,而是更多地转向回答一个更广泛的问题:"什么样的上下文配置最有可能让模型产生我们期望的行为?"

上下文指的是从大语言模型(LLM)采样时所包含的一组令牌(Token)。当前面临的工程问题是,在 LLM 固有约束条件下,优化这些令牌的效用,以持续达成期望的结果。要有效驾驭 LLM,通常需要具备"上下文思维"——换言之,即考虑 LLM 在任何给定时刻可用的整体状态,以及该状态可能产生的潜在行为。

本文将探讨新兴的上下文工程艺术,并提供一个精炼的心智模型,用于构建可控且高效的人工智能体。

上下文工程 vs. 提示词工程

在 Anthropic,我们认为上下文工程是提示词工程的自然演进。提示词工程指的是为优化输出结果而编写和组织 LLM 指令的方法(请参阅我们的文档以获取概述和有用的提示词工程策略)。上下文工程则是指在 LLM 推理过程中,策划和维持最优令牌(信息)集合的一系列策略,这包括了提示词之外所有可能进入上下文的其他信息。

在 LLM 工程应用的早期,提示词工程是 AI 工程工作的主要组成部分,因为除了日常聊天交互之外的大多数用例,都需要针对单次分类或文本生成任务进行优化的提示词。顾名思义,提示词工程的主要焦点是如何编写有效的提示词,尤其是系统提示词。然而,随着我们转向构建能够在多次推理轮次和更长时间跨度上运行的、更强大的智能体,我们需要管理整个上下文状态(系统指令、工具、模型上下文协议 MCP、外部数据、消息历史等)的策略。

在循环中运行的智能体会产生越来越多可能与下一轮推理相关的数据,这些信息必须被循环地提炼。上下文工程正是从这不断演化的可能信息宇宙中,策划哪些内容将进入有限上下文窗口的艺术与科学。

提示词工程 vs. 上下文工程

提示词工程 vs. 上下文工程;与编写提示词这种离散任务不同,上下文工程是迭代性的,并且每次我们决定向模型传递什么信息时,都会发生策划阶段。

为何上下文工程对构建强大智能体至关重要

尽管 LLM 速度飞快且能处理越来越庞大的数据量,但我们观察到,和人类一样,LLM 在某个节点也会失去焦点或感到困惑。针对"大海捞针"式基准测试的研究揭示了"上下文腐化" (context rot)的概念:随着上下文窗口中令牌数量的增加,模型从该上下文中准确回忆信息的能力会下降。

虽然某些模型表现出的性能下降程度相对温和,但这一特性在所有模型中都会出现。因此,必须将上下文视为一种收益递减的有限资源。与工作记忆容量有限的人类类似,LLM 在解析大量上下文信息时,会动用其"注意力预算"(attention budget)。引入的每一个新令牌都会在一定程度上消耗这个预算,从而增加了精心策划 LLM 可用令牌的必要性。

这种注意力稀缺性源于 LLM 的架构限制。LLM 基于Transformer 架构,该架构使得每个令牌都能关注到整个上下文中的其他所有令牌。这导致了对于 n 个令牌,存在 n² 的成对关系。

随着上下文长度的增加,模型捕捉这些成对关系的能力变得捉襟见肘,从而在上下文大小和注意力焦点之间造成了天然的张力。此外,模型从训练数据分布中形成其注意力模式,而训练数据中短序列通常比长序列更常见。这意味着模型对于上下文范围内的依赖关系经验较少,并且缺乏专门的参数。

像位置编码插值这样的技术,通过让模型适应最初训练的较小上下文窗口,使其能够处理更长的序列,尽管在令牌位置理解方面会有所下降。这些因素共同造成了性能梯度,而非硬性悬崖:模型在较长上下文中仍然保持高度能力,但与在较短上下文中的表现相比,在信息检索和长程推理方面的精度可能会降低。

这些现实意味着,深思熟虑的上下文工程对于构建强大的智能体至关重要。

高效上下文的剖析

鉴于 LLM 受限于有限的注意力预算,良好的上下文工程意味着找到能够最大化期望结果发生概率的、尽可能小的高信号令牌集合。将这一实践原则付诸实施说起来容易做起来难,但在以下部分中,我们将阐述这一指导原则在不同上下文组件中的实际含义。

系统提示词 应极其清晰,并使用简单、直接的语言,以适合智能体的 恰当层面 呈现观点。这个 恰当层面 处于两种常见失败模式之间的 "Goldilocks 区"(刚刚好的状态)。在一个极端,我们看到工程师在提示词中硬编码复杂、脆弱的逻辑,以引发精确的智能体行为。这种方法会带来脆弱性,并随着时间推移增加维护的复杂性。在另一个极端,工程师有时提供模糊、高层次的指导,未能为 LLM 提供期望输出的具体信号,或者错误地假设了共享上下文。最优的高度在于取得平衡:既要足够具体以有效指导行为,又要足够灵活,为模型提供强有力的启发式引导。

在上下文工程过程中校准系统提示词

在上下文工程过程中校准系统提示词:在频谱的一端,我们看到脆弱的、硬编码了 if-else 逻辑的提示词;在另一端,我们看到过于笼统或错误假设共享上下文的提示词。

我们建议将提示词组织成不同的部分(例如 <background_information>, <instructions>, <tool_guide>, <output_description> 等),并使用 XML 标签或 Markdown 标题等技术来划分这些部分,尽管随着模型能力的提升,提示词的具体格式化方式可能变得不那么重要。

无论你决定如何构建系统提示词,你都应该力求使用能够完整勾勒出期望行为的最小信息集。(请注意,"最小"不一定意味着"短";你仍然需要预先给智能体足够的信息,以确保它遵循期望的行为。)最佳做法是,首先用一个最小的提示词测试可用的最佳模型,观察其在你的任务上的表现,然后根据初始测试中发现的故障模式,添加清晰的指令和示例来改进性能。

工具 使得智能体能够与其环境互动,并在工作中引入新的、额外的上下文。由于工具定义了智能体与其信息/行动空间之间的契约,因此工具必须促进效率,这既通过返回令牌高效的信息来实现,也通过鼓励高效的智能体行为来实现。

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

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

提供示例,也称为少样本提示,是一个众所周知的最佳实践,我们继续强烈建议采用。然而,团队常常会将一长串边缘案例塞进提示词中,试图阐明 LLM 为完成特定任务应遵循的所有可能规则。我们不推荐这样做。相反,我们建议努力策划一组多样化的、规范的示例,以有效描绘智能体的期望行为。对于 LLM 而言,示例就是"一图胜千言"的"示例图片"。

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

上下文检索与智能体搜索

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

在与客户合作的过程中,我们看到该领域正朝着这一简单范式汇聚。随着底层模型变得愈发强大,智能体的自主性水平得以扩展:更聪明的模型使得智能体能够独立驾驭细致入微的问题空间并从错误中恢复。

我们现在看到工程师在设计智能体上下文时的思维方式正在发生转变。如今,许多 AI 原生应用采用某种形式的基于嵌入的推理前检索,来为智能体的推理提供重要的上下文信息。随着该领域向更具智能体特性的方法过渡,我们越来越多地看到团队用"即时"上下文策略来增强这些检索系统。

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

除了存储效率之外,这些引用的元数据也提供了一种有效优化行为的机制,无论这些元数据是明确提供的还是直观的。对于一个在文件系统中运行的智能体来说,名为 test_utils.py 的文件出现在 tests 文件夹中,与出现在 src/core_logic/ 中的同名文件相比,其用途暗示是不同的。文件夹层次结构、命名约定和时间戳都提供了重要的信号,帮助人类和智能体理解如何以及何时利用信息。

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

当然,这里存在一个权衡(trade-off):运行时探索比检索预先计算的数据要慢。不仅如此,还需要经过深思熟虑的工程化设计,以确保 LLM 拥有有效的工具和启发式方法,来高效地导航其信息环境。如果没有适当的指导,智能体可能会因误用工具、追逐死胡同或未能识别关键信息而浪费上下文。

在某些场景下,最高效的智能体可能会采用混合策略,为了速度预先检索一些数据,同时根据其判断自主进行进一步的探索。"正确"自主性水平的决策边界取决于任务。Claude Code 就是一个采用这种混合模型的智能体:CLAUDE.md 文件会被预先直接放入上下文,而像 glob 和 grep 这样的原语允许它即时导航环境并检索文件,从而有效规避了过时索引和复杂语法树的问题。

混合策略可能更适合内容动态性较弱的场景,例如法律或金融工作。随着模型能力的提高,智能体设计将趋向于让智能模型智能地行动,逐渐减少人为策划。鉴于该领域的快速发展,对于在 Claude 之上构建智能体的团队来说,"做最简单且有效的事"很可能仍然是我们最好的建议。

面向长周期任务的上下文工程

长周期任务要求智能体在一系列行动中保持连贯性、上下文意识和目标导向行为,这些行动所产生的令牌数量可能超过 LLM 的上下文窗口。对于持续数十分钟到数小时的连续工作任务,例如大型代码库迁移或综合性研究项目,智能体需要专门的技术来绕过上下文窗口大小的限制。

等待更大的上下文窗口似乎是一个显而易见的策略。但很可能在可预见的未来,所有大小的上下文窗口都会受到上下文污染和信息相关性问题的困扰——至少在需要最强智能体性能的情况下是如此。为了使智能体能够在延长的时间跨度上有效工作,我们开发了一些直接应对这些上下文污染约束的技术:压缩、结构化笔记和多智能体架构。

压缩

压缩是指将接近上下文窗口限制的对话内容进行总结,并用该总结重新初始化一个新的上下文窗口的实践。压缩通常是上下文工程中驱动更好长期连贯性的首要手段。其核心在于,以高保真度提炼上下文窗口的内容,使智能体能够以最小的性能损失继续工作。

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

压缩的艺术在于选择保留什么与丢弃什么,因为过于激进的压缩可能导致细微但关键的上下文丢失,而这些上下文的重要性可能直到后期才显现出来。对于实施压缩系统的工程师,我们建议在复杂的智能体运行轨迹上仔细调整你的提示词。首先最大化召回率,确保你的压缩提示词能捕捉到轨迹中的每一个相关信息,然后通过迭代来提高精确度,消除多余的内容。

低垂的多余内容的一个例子是清理工具调用和结果——一旦一个工具在消息历史深处被调用过,为什么智能体需要再次看到原始结果呢?最安全、最轻量级的压缩形式之一是工具结果清理,该功能最近已在 Claude 开发者平台上作为一项功能发布。

结构化笔记

结构化笔记,或称智能体记忆,是一种技术,智能体定期将笔记写入上下文窗口之外持久化的存储器中。这些笔记在后续时间会被重新拉入上下文窗口。

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

Claude 玩《宝可梦》的演示展示了记忆如何在非编码领域改变智能体的能力。该智能体在数千个游戏步骤中保持精确的记录——追踪诸如"在过去的 1234 步中,我一直在 1 号道路训练我的宝可梦,皮卡丘已经提升了 8 级,目标是 10 级"这样的目标。在没有任何关于记忆结构提示的情况下,它绘制了已探索区域的地图,记住了已解锁的关键成就,并保留了战斗策略的战略笔记,帮助它了解哪些攻击对不同对手最有效。

在上下文重置后,智能体阅读自己的笔记,并继续执行持续数小时的训练序列或地下城探索。这种跨越总结步骤的连贯性,使得执行长周期策略成为可能,而这些策略若将所有信息仅保存在 LLM 的上下文窗口中是根本无法实现的。

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

子智能体架构

子智能体架构提供了另一种绕过上下文限制的方法。与其让一个智能体试图在整个项目中维持状态,不如让专门的子智能体处理具有清晰上下文窗口的聚焦任务。主智能体协调一个高层次的计划,而子智能体则执行深度的技术工作或使用工具查找相关信息。每个子智能体可能会进行广泛的探索,使用数万个甚至更多的令牌,但只返回其工作的浓缩、提炼后的总结(通常为 1000-2000 个令牌)。

这种方法实现了清晰的关注点分离——详细的搜索上下文保留在子智能体内部,而主导智能体则专注于综合和分析结果。在我们如何构建我们的多智能体研究系统 一文中讨论的这种模式,在复杂的研究任务上显示出相对于单智能体系统的显著改进。

这些方法之间的选择取决于任务特性。例如:

  • 压缩 对于需要大量来回沟通的任务,能保持对话的流畅性;
  • 笔记 对于具有清晰里程碑的迭代开发表现出色;
  • 多智能体架构 处理复杂的研究和分析任务,在这些任务中并行探索能带来回报。

即使模型持续改进,在扩展的交互中保持连贯性的挑战,仍将是构建更有效智能体的核心问题。

结论

上下文工程代表了我们如何使用 LLM 进行构建的根本性转变。随着模型变得愈发强大,挑战不再仅仅是精心设计完美的提示词——而是要在每个步骤中深思熟虑地策划进入模型有限注意力预算的信息。无论你是在为长周期任务实施压缩、设计令牌高效的工具,还是让智能体能够即时探索其环境,指导原则始终如一:找到能够最大化期望结果发生概率的、尽可能小的高信号令牌集合。

我们概述的这些技术将随着模型的改进而不断演进。我们已经看到,更聪明的模型需要更少的指令性工程,从而允许智能体以更高的自主性运行。但即使能力不断提升,将上下文视为一种宝贵且有限的资源,对于构建可靠、高效的智能体而言,仍将是至关重要的。

立即通过 Claude 开发者平台 开始你的上下文工程之旅,并通过我们的 记忆和上下文管理指南 获取有用的提示和最佳实践。

致谢

本文由 Anthropic 应用人工智能团队撰写:Prithvi Rajasekaran, Ethan Dixon, Carly Ryan, 和 Jeremy Hadfield,团队成员 Rafi Ayub, Hannah Moran, Cal Rueb, 和 Connor Jennings 亦有贡献。特别感谢 Molly Vorwerck, Stuart Ritchie, 和 Maggie Vo 的支持。