5501 字
28 分钟
AI Agent 的有效上下文工程

原文:Effective context engineering for AI agents(Anthropic,2025-09-29,Applied AI 团队)。本文为中文翻译,插图来自原文。

上下文(context)是 AI 代理(agent)的关键但有限的资源。在这篇文章中,我们探讨如何有效地策展和管理支撑代理的上下文。

在应用 AI 领域聚焦于提示词工程(prompt engineering)数年之后,一个新术语开始崭露头角:上下文工程(context engineering)。

使用语言模型构建应用,越来越不只是为你的提示词找到合适的词句,而是要回答一个更大的问题:“什么样的上下文配置,最有可能让模型产生我们想要的行为?”

上下文指的是从大语言模型(LLM)采样时纳入的词元(token)集合。这里的工程问题是:在 LLM 固有的约束下,优化这些词元的效用,从而持续达成期望的结果。有效地驾驭 LLM,往往需要”在上下文中思考”——也就是说,考虑 LLM 在任意时刻可用的整体状态,以及该状态可能产生的潜在行为。

在这篇文章中,我们将探讨新兴的上下文工程艺术,并提供一个构建可控、高效代理的精细心智模型。

上下文工程与提示词工程#

在 Anthropic,我们认为上下文工程是提示词工程的自然演进。

提示词工程指的是编写和组织 LLM 指令以获得最优结果的方法(参见我们的文档获取概览和有用的提示词工程策略)。

上下文工程指的是在 LLM 推理期间策展并维护最优词元(信息)集合的策略集合,包括提示词之外所有可能进入上下文的其他信息。

在使用 LLM 工程化的早期,编写提示词是 AI 工程工作中最大的组成部分,因为除日常聊天交互外,大多数用例都需要为一次性分类或文本生成任务优化的提示词。顾名思义,提示词工程的主要焦点是如何编写有效的提示词,尤其是系统提示词(system prompt)。

然而,随着我们迈向构建更强的代理——它们在多轮推理和更长的时间跨度上运作——我们需要管理整个上下文状态的策略:系统指令、工具(tools)、模型上下文协议(Model Context Protocol,MCP)、外部数据、消息历史(message history)等。

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

提示词工程与上下文工程的对比

提示词工程与上下文工程的对比。与编写提示词这一离散任务不同,上下文工程是迭代的,策展阶段发生在我们每次决定给模型传递什么内容时。

为什么上下文工程对构建强大的代理至关重要#

尽管 LLM 速度很快、能管理越来越大规模的数据,但我们观察到,LLM 和人类一样,在某个临界点会失去焦点或感到困惑。针对”大海捞针”式基准测试的研究揭示了上下文衰退(context rot)的概念:随着上下文窗口中词元数量的增加,模型准确回忆其中信息的能力会下降。

虽然某些模型比其他模型退化得更平缓,但这一特性在所有模型中都存在。因此,上下文必须被视为一种边际收益递减的有限资源。与拥有有限工作记忆容量的人类一样,LLM 在解析大量上下文时依赖一个”注意力预算(attention budget)“。每引入一个新词元都会消耗一部分预算,因此需要更加仔细地策展提供给 LLM 的词元。

这种注意力稀缺源于 LLM 的架构约束。LLM 基于 Transformer 架构,使每个词元都能注意到整个上下文中的每个其他词元。对于 n 个词元,这意味着 n² 个两两关系。

随着上下文长度增加,模型捕获这些两两关系的能力会被摊薄,在上下文大小与注意力聚焦之间形成天然张力。此外,模型的注意力模式是从训练数据分布中习得的,而较短的序列通常比较长的更常见。这意味着模型对跨上下文的远距离依赖经验更少、专门参数也更少。

像位置编码插值(position encoding interpolation)这样的技术,通过让模型适应其原本训练的较小上下文来处理更长的序列,尽管词元位置理解会有一定退化。这些因素共同造就了一条性能渐变曲线而非陡峭悬崖:模型在较长上下文下仍保持很强的能力,但在信息检索和远距离推理的精确性上,可能比短上下文时略有下降。

这些现实意味着:深思熟虑的上下文工程,是构建强大代理的必要条件。

有效上下文的构成#

鉴于 LLM 受有限的注意力预算约束,好的上下文工程,意味着找到尽可能小的、高信号(signal)的词元集合,以最大化某种期望结果的概率。将这一原则付诸实践说起来容易做起来难,接下来我们概述它在上下文各个组成部分中的具体含义。

系统提示词#

系统提示词应当极其清晰,使用简单直接的语言,以适合代理的”恰当高度”呈现思想。恰当的高度,是两个常见失败模式之间的”金发姑娘区”(Goldilocks zone,即恰到好处的区间)。

一个极端是,工程师在提示词中硬编码复杂、脆弱的逻辑,以诱导精确的自主行为。这种方法会带来脆弱性,并随时间增加维护复杂度。

另一个极端是,工程师提供模糊、高层级的指导,无法给 LLM 关于期望输出的具体信号,或错误地假设了共享上下文。

最佳高度是一种平衡:足够具体以有效引导行为,又足够灵活,给模型提供引导行为的强启发式(heuristics)。

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

上下文工程过程中校准系统提示词。光谱一端是脆弱的 if-else 硬编码提示词,另一端是过于笼统或错误假设共享上下文的提示词。

我们建议将提示词组织成不同的区块(如 <background_information>、<instructions>、## Tool guidance、## Output description 等),并使用 XML 标签或 Markdown 标题等技术来划分这些区块——尽管随着模型能力增强,提示词的确切格式可能变得不那么重要。

无论你决定如何组织系统提示词,你都应追求完整勾勒期望行为所需的最小信息集。(注意:最小并不必然意味着短;你仍需提前给代理足够的信息,确保它遵守期望行为。)最好的做法是:先用可用的最佳模型测试一个最小提示词,观察它在你的任务上的表现,然后根据初测中发现的失败模式,添加明确的指令和示例来提升性能。

工具#

工具让代理能与环境交互,并在工作中拉取新的、额外的上下文。由于工具定义了代理与其信息/行动空间之间的契约,因此工具促进效率极其重要——既要返回词元高效的信息,也要鼓励高效的代理行为。

在与 AI 代理一起编写代理工具(Writing tools for AI agents)中,我们讨论了构建能被 LLM 充分理解、且功能重叠最小的工具。与设计良好的代码库中的函数类似,工具应当自包含、对错误鲁棒、对其预期用途极其清晰。输入参数同样应当描述性强、无歧义,并发挥模型的固有优势。

我们见到的最常见失败模式之一是:臃肿的工具集合覆盖了过多功能,或导致”该用哪个工具”的决策点含糊不清。如果人类工程师都无法确定在特定情境下应该用哪个工具,就不能指望 AI 代理做得更好。正如我们稍后将讨论的,为代理策展一个最小可行工具集合,也能让长交互中的上下文维护与修剪更可靠。

示例#

提供示例——也就是少样本提示(few-shot prompting)——是众所周知的最佳实践,我们仍然强烈推荐。然而,团队常常把一长串边界情况(edge cases)塞进提示词,试图罗列 LLM 在特定任务中应遵守的每一条规则。

我们不建议这样做。相反,我们建议策展一组多样化、典范式(canonical)的示例,有效描绘代理的期望行为。对 LLM 而言,示例就是”一图胜千言”中的那张图。

我们针对上下文各组成部分(系统提示词、工具、示例、消息历史等)的总体指导是:深思熟虑,让上下文信息丰富但紧凑。接下来,让我们深入探讨在运行时动态检索上下文。

上下文检索与代理式搜索#

在构建有效的 AI 代理(Building effective AI agents)中,我们强调了基于 LLM 的工作流(workflow)与代理的区别。自那以后,我们倾向于一个简单的代理定义:LLM 在循环中自主使用工具。

在与客户的合作中,我们看到业界正收敛到这个简单的范式。随着底层模型能力增强,代理的自主程度可以扩展:更智能的模型让代理能独立地在细微的问题空间中导航,并从错误中恢复。

我们现在看到工程师设计代理上下文的思路正在转变。如今,许多 AI 原生应用采用某种形式的基于嵌入(embedding)的推理前检索,为代理呈现需要推理的重要上下文。随着领域转向更自主的方法,我们越来越多地看到团队用**“即时”上下文策略**增强这些检索系统。

基于”即时”方法构建的代理,不会预先处理所有相关数据,而是维护轻量级标识符(文件路径、存储的查询、网页链接等),并在运行时使用工具按引用动态加载数据到上下文中。

Anthropic 的自主编码方案 Claude Code 就用这种方法对大型数据库执行复杂的数据分析。模型可以编写针对性查询、存储结果,并利用 head、tail 等 Bash 命令分析大量数据,而无需将完整数据对象加载进上下文。

这种方法映射了人类的认知方式:我们通常不会背下整个语料库,而是引入文件系统、收件箱、书签等外部组织与索引系统,按需检索相关信息。

除了存储效率,这些引用的元数据还提供了一种高效精炼行为的机制,无论其是显式提供还是凭直觉感知。对于一个在文件系统中运作的代理,tests 目录下名为 test_utils.py 的文件,与位于 src/core_logic/ 下的同名文件含义截然不同。目录层级、命名约定和时间戳都提供了重要信号,帮助人类和代理理解何时以及如何利用信息。

让代理自主导航和检索数据,还能实现渐进式披露(progressive disclosure)——也就是说,让代理通过探索增量地发现相关上下文。每次交互都会产生指导下一步决策的上下文:文件大小暗示复杂度;命名约定暗示用途;时间戳可以作为相关性的代理指标。代理可以一层层地拼装理解,只在工作记忆中保留必要内容,并利用记笔记策略实现额外持久化。这种自我管理的上下文窗口,让代理聚焦于相关的子集,而不是淹没在海量但可能无关的信息中。

当然,这里有取舍:运行时探索比检索预计算数据更慢。不仅如此,还需要有主见且深思熟虑的工程,确保 LLM 拥有合适的工具和启发式,以有效地在其信息疆域中导航。没有适当的引导,代理会因误用工具、追逐死胡同或未能识别关键信息而浪费上下文。

在某些场景中,最高效的代理可能采用混合策略:预先检索部分数据以保证速度,再自主决定是否进一步探索。“正确”自主程度的决策边界取决于任务。

Claude Code 就是采用这种混合模型的代理:CLAUDE.md(claude.md) 文件会被直接放入上下文,而 glob、grep 等原语则让它能在环境中导航并按需即时检索文件,有效绕开陈旧索引与复杂语法树的问题。

混合策略可能更适合内容动态性较低的场景,例如法律或金融工作。随着模型能力提升,自主设计将趋向于让智能模型自主行动,人工策展越来越少。鉴于该领域进展迅速,“做最简单且有效的事”很可能仍是我们给在 Claude 之上构建代理的团队的最佳建议。

面向长时程任务的上下文工程#

长时程(long-horizon)任务要求代理在一系列动作中保持连贯性、上下文和目标导向行为,而其中词元数会超过 LLM 的上下文窗口。对于持续数十分钟到数小时的连续工作(如大型代码库迁移或综合性研究项目),代理需要专门技术来绕开上下文窗口的尺寸限制。

等待更大的上下文窗口似乎是显而易见的策略。但在可预见的未来,各种尺寸的上下文窗口都可能受上下文污染与信息相关性问题的困扰——至少在追求最强代理性能的场景下如此。为了让代理在更长的时间跨度上有效工作,我们开发了几项直接应对这些上下文污染约束的技术:上下文压缩(compaction)、结构化笔记与多代理架构。

上下文压缩

上下文压缩是这样一种实践:将近乎触达上下文窗口上限的对话取出,总结其内容,然后用摘要重新开启一个新的上下文窗口。上下文压缩通常是上下文工程中驱动长期连贯性的第一根杠杆。其核心是以高保真方式蒸馏上下文窗口的内容,让代理能以最小的性能退化继续工作。

例如在 Claude Code 中,我们通过把消息历史交给模型,让它总结并压缩最关键细节来实现这一点。模型会保留架构决策、未解决的 bug 和实现细节,同时丢弃冗余的工具输出或消息。随后,代理可以带着这份压缩后的上下文,外加最近访问的五个文件继续工作。用户获得了连续性,而不必担心上下文窗口的限制。

上下文压缩的艺术在于选择保留什么、丢弃什么——过度激进的压缩可能导致丢失微妙但关键、其重要性要到后来才显现的上下文。对于实现上下文压缩系统的工程师,我们建议在复杂的代理轨迹(trace)上仔细调优你的提示词:先从最大化召回率(recall)开始,确保压缩提示词捕获轨迹中的每一条相关信息,然后迭代提升精确率(precision),剔除多余内容。

一个唾手可得的冗余内容例子是清理工具调用与结果——一旦某个工具在消息历史深处被调用过,代理为何还要再看一遍原始结果?最安全、最轻量的压缩形式之一是清除工具结果,最近已作为 Claude Developer Platform 的一项功能推出。

结构化笔记

结构化笔记(structured note-taking),又称代理记忆(agentic memory),是这样一种技术:代理定期把笔记写入上下文窗口之外的持久化记忆,并在之后的某个时间点将这些笔记拉回上下文窗口。

这一策略以极小的开销提供持久记忆。就像 Claude Code 创建待办清单,或你的自定义代理维护一个 NOTES.md 文件,这个简单模式让代理能跨复杂任务跟踪进度,保留那些否则会在数十次工具调用中丢失的关键上下文与依赖。

Claude 玩宝可梦 展示了记忆如何在非编码领域改变代理的能力。代理在数千个游戏步骤中维持精确计数——跟踪诸如”过去 1,234 步我一直在 1 号道路训练我的宝可梦,皮卡丘已经升了 8 级,距离 10 级的目标还差 2 级”这样的目标。在没有任何记忆结构提示的情况下,它会绘制已探索区域的地图,记住自己解锁了哪些关键成就,并维护战斗策略笔记,帮助自己学习哪些招式对不同对手最有效。

在上下文重置后,代理会读取自己的笔记,继续数小时的训练序列或地牢探索。这种跨总结步骤的连贯性,使得仅靠把所有信息放在 LLM 的上下文窗口中不可能实现的长程策略成为可能。

作为 Sonnet 4.5 发布的一部分,我们在 Claude Developer Platform 上以公开测试(public beta)形式发布了一个记忆工具,通过基于文件的系统,让在上下文窗口之外存储和查阅信息变得更加容易。这让代理能随时间构建知识库、跨会话维护项目状态,并在不把所有内容留在上下文中的情况下参考先前的工作。

子代理架构

子代理(sub-agent)架构提供了绕过上下文限制的另一种方式。与其让一个代理尝试维护整个项目的状态,不如让专门的子代理以干净的上下文窗口处理聚焦的任务。主代理用高层计划进行协调,而子代理执行深层技术工作或使用工具查找相关信息。每个子代理都可能广泛探索、消耗数万甚至更多词元,但只返回一份浓缩、蒸馏的工作摘要(通常 1,000–2,000 词元)。

这种方法实现了清晰的关注点分离——详细的搜索上下文隔离在子代理内部,而主导代理专注于综合与分析结果。这一模式在我们如何构建多代理研究系统(How we built our multi-agent research system)中讨论过,在复杂研究任务上相比单代理系统有显著改进。

在不同方法之间做选择取决于任务特征。例如:

  • 上下文压缩维持对话流,适合需要大量来回交互的任务;
  • 笔记擅长有清晰里程碑的迭代式开发;
  • 多代理架构处理复杂的调研与分析,并行探索能带来回报。

即使模型持续进步,在扩展交互中维持连贯性的挑战,仍将是构建更高效代理的核心。

结语#

上下文工程代表着我们使用 LLM 构建方式的一个根本转变。随着模型能力增强,挑战不再只是打磨完美的提示词——而是在每一步深思熟虑地策展哪些信息进入模型有限的注意力预算。无论你是在为长时程任务实现上下文压缩、设计词元高效的工具,还是让代理即时地探索环境,指导原则始终如一:找到最小的高信号词元集合,最大化期望结果出现的概率。

我们概述的这些技术将随模型改进而持续演进。我们已经看到,更智能的模型需要更少的指令式工程,让代理能以更高的自主性运作。但即使能力在扩展,把上下文视为珍贵而有限的资源,仍将是构建可靠、高效代理的核心。

今天就从 Claude Developer Platform 开始实践上下文工程,并通过我们的记忆与上下文管理手册获取有用的技巧与最佳实践。

致谢#

由 Anthropic 的 Applied AI 团队撰写 Rajasekaran、Ethan Dixon、Carly Ryan 与 Jeremy Hadfield;团队成员 Rafi Ayub、Hannah Moran、Cal Rueb 与 Connor Jennings 亦有贡献。特别感谢 Molly Vorwerck、Stuart Ritchie 与 Maggie Vo 的支持。

AI Agent 的有效上下文工程
https://tech.boboee.com/posts/anthropic-effective-context-engineering-zh/
作者
boboee
发布于
2025-09-29
许可协议
CC BY-NC-SA 4.0