把「上下文是有限资源」当第一性原理,你就能解释自己 Agent 项目里大多数质量下滑:不是模型不行,是 token 没管好。

最值得拿走的是三层东西:一是诊断视角——上下文腐坏(context rot)与 n² 注意力预算解释了为什么塞得越满效果越差;二是策展原则——系统提示要写在对的高度、工具要做最小可行集、示例要多样而典型;三是长时程三件套——压缩先求召回再求精度、结构化笔记让 Agent 跨窗口保持连贯、子代理用干净上下文换深度探索。最常见的误用是把压缩当成「越狠越好」,丢掉后面才显现价值的关键上下文。

中文读者要读这篇,是因为国内关于 Agent 的讨论大多还停留在提示词技巧与框架选型,而这篇代表一线厂商的共识:工程重心正在转向上下文的全生命周期管理。叠加国内语境,团队常在弱工具生态与自建检索上起步,文中「轻量标识符 + 即时加载」的路径比堆 RAG 管道更值得先试。

读完做一件事:把你 Agent 的系统提示按区段重写一遍,删掉所有硬编码的 if-else 逻辑,跑一遍现有任务对比效果。

—— FDEChina编辑部 · 架构师视角

在应用 AI 领域被提示工程(prompt engineering)占据注意力数年之后,一个新词开始崭露头角:上下文工程(context engineering)。用大语言模型做构建,正变得越来越不在于为提示词挑选恰当的字句,而越来越多地在于回答一个更宏观的问题:「什么样的上下文配置,最有可能让模型生成我们期望的行为?」

上下文(context)指的是从大语言模型(LLM)采样时纳入输入的那组 token。这里的工程问题,是在 LLM 的固有约束下优化这批 token 的效用,从而稳定地达成预期结果。要有效驾驭 LLM,往往需要在上下文中思考(thinking in context)——换句话说:通盘考虑 LLM 在任一时刻可获得的整体状态,以及这种状态可能诱发的行为。

本文将探讨上下文工程这门新兴技艺,并给出一个经过打磨的心智模型,帮助你构建可控、高效的 Agent。

上下文工程 vs 提示工程

在 Anthropic,我们把上下文工程视为提示工程的自然演进。提示工程指的是为获得最优结果而编写和组织 LLM 指令的方法(概述与实用策略见我们的文档)。上下文工程则指在 LLM 推理期间策划并维护最优 token(信息)集合的一系列策略,涵盖可能落入上下文、而超出提示本身范围的所有其他信息。

在 LLM 工程的早期,编写提示是 AI 工程工作的最大组成部分,因为日常聊天交互之外的大多数用例,都需要针对一次性分类或文本生成任务优化过的提示。顾名思义,提示工程的核心是「如何写出有效的提示」,尤其是系统提示(system prompt)。然而,当我们转向构建能力更强、在多轮推理和更长时间跨度上运行的 Agent 时,我们需要的是管理整个上下文状态的策略——系统指令、工具、模型上下文协议(Model Context Protocol,MCP)、外部数据、消息历史等。

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

与「写一条提示」这个离散任务不同,上下文工程是迭代式的:每一次决定向模型传递什么,都是一次策展(curation)。

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

尽管 LLM 速度飞快、能管理的数据量越来越大,我们观察到:和人类一样,LLM 到了某个程度也会失焦或陷入混乱。针对「大海捞针」(needle-in-a-haystack)类基准的研究揭示了一种名为上下文腐坏(context rot)的现象:随着上下文窗口中 token 数量的增加,模型从该上下文中准确召回信息的能力会下降。

虽然有些模型的退化比其他模型更平缓,但这一特征在所有模型上都会出现。因此,上下文必须被当作一种边际收益递减的有限资源。就像工作记忆容量有限的人类一样,LLM 在解析大体量上下文时也要消耗一份「注意力预算」(attention budget)。每引入一个新 token,都会按某种比例消耗这份预算,这更加凸显了精心策展可供 LLM 使用的 token 的必要性。

这种注意力稀缺源于 LLM 的架构约束。LLM 基于 transformer 架构,它允许每个 token 关注(attend to)整个上下文中的其他每一个 token,对 n 个 token 就意味着 n² 个成对关系。

随着上下文长度增加,模型捕捉这些成对关系的能力被摊薄,上下文规模与注意力聚焦之间形成天然张力。此外,模型的注意力模式学自训练数据分布,而训练数据中短序列通常远多于长序列。这意味着模型在全局依赖上经验更少,专门参数也更少。

位置编码插值(position encoding interpolation)等技术让模型可以借由适配回最初训练时的较小上下文来处理更长序列,但会损失一定的 token 位置理解能力。这些因素共同造成的是一条性能梯度,而非断崖:模型在长上下文中依然能力很强,但与短上下文相比,信息检索与长程推理的精度可能下降。

这些现实意味着:要构建强大的 Agent,深思熟虑的上下文工程必不可少。

高效上下文的构成

既然 LLM 受限于有限的注意力预算,好的上下文工程就意味着:找出最小的那组高信号(high-signal)token,使期望结果出现的概率最大化。实践远比说起来难,但在接下来的小节中,我们会逐一说明这条指导原则落在上下文各个组成部分上意味着什么。

系统提示应当极其清晰,使用简单直接的语言,在适合 Agent 的正确「高度」(altitude)上陈述想法。所谓正确高度,是两种常见失败模式之间的「刚刚好」区间。一个极端是:工程师在提示里硬编码复杂而脆弱的逻辑,试图逼出精确的 Agent 行为——这会带来脆弱性,并随时间推高维护复杂度。另一个极端是:工程师给出含糊的高层指导,既没有给 LLM 提供关于期望输出的具体信号,又错误地假设了共享上下文。最优高度介于两者之间:足够具体以有效引导行为,又足够灵活以给模型留下强有力的启发式(heuristics)。

光谱的一端是脆弱的 if-else 式硬编码提示,另一端是过于泛化或错误假设共享上下文的提示。

我们建议把提示组织成不同的区段(如 <background_information>、<instructions>、## Tool guidance、## Output description 等),并使用 XML 标签或 Markdown 标题来划分这些区段——不过,随着模型能力增强,提示的具体格式正变得越来越不重要。

无论你决定如何组织系统提示,都应该追求「能完整勾勒预期行为的最小信息集」。(注意:最小不等于短;你仍需要预先给 Agent 足够的信息,确保它遵循期望行为。)最好的做法是:先用可用的最强模型测试一条极简提示,看它在你的任务上表现如何,再根据首轮测试中暴露的失败模式,补充清晰的指令与示例来改进。

工具让 Agent 能作用于环境,并在工作中拉取新的补充上下文。工具定义了 Agent 与其信息/行动空间之间的契约,因此工具必须促进效率——既返回 token 高效的信息,也鼓励高效的 Agent 行为——这一点极其重要。

在《Writing tools for AI agents – with AI agents》一文中,我们讨论过如何构建 LLM 易于理解、功能重叠最少的工具。与设计良好的代码库中的函数类似,工具应当自包含、对错误健壮、对其预期用途极其清晰。输入参数同样应当具有描述性、无歧义,并顺应模型的固有优势。

我们最常见到的失败模式之一,是臃肿的工具集:要么覆盖了过多功能,要么在「该用哪个工具」上制造模糊的决策点。如果人类工程师都无法断言某个情境下应该用哪个工具,就不能指望 AI Agent 做得更好。正如后文将讨论的,为 Agent 策划一个最小可行工具集,还有助于在长交互中更可靠地维护和修剪上下文。

提供示例——也就是少样本提示(few-shot prompting)——是人尽皆知的最佳实践,我们至今仍然强烈建议使用。但团队常会把一长串边缘情况塞进提示,试图穷举 LLM 在某项任务上应遵守的每一条规则。我们不建议这样做。更好的做法是:精心策划一组多样、典型的示例,让它们有效呈现 Agent 的预期行为。对 LLM 而言,示例就是「值千字」的图画。

我们对上下文各组成部分(系统提示、工具、示例、消息历史等)的总体建议是:深思熟虑,让上下文信息量足,同时紧凑。接下来我们深入运行时的动态上下文检索。

上下文检索与代理式搜索

在《Building effective AI agents》中,我们强调过基于 LLM 的工作流(workflow)与 Agent 的区别。自那篇文章之后,我们逐渐收敛到一个关于 Agent 的简单定义:在循环中自主使用工具的 LLM。

在与客户的合作中,我们看到整个领域正在向这个简单范式收敛。随着底层模型能力增强,Agent 的自主程度可以随之扩展:更聪明的模型让 Agent 能够独立穿行于微妙的问题空间,并从错误中恢复。

我们也看到工程师为 Agent 设计上下文的思路正在转变。今天,许多 AI 原生应用采用某种基于嵌入(embedding)的推理前检索,把重要上下文提前浮出,供 Agent 推理。随着领域转向更代理化的方式,我们越来越多地看到团队在这些检索系统之上叠加「即时」(just-in-time)上下文策略。

「即时」方式的 Agent 不预先处理所有相关数据,而是维护轻量的标识符(文件路径、存储的查询、网页链接等),并在运行时通过工具把这些引用动态加载进上下文。Anthropic 的代理式编程方案 Claude Code 就用这种方式在大型数据库上执行复杂数据分析:模型可以编写有针对性的查询、存储结果,并利用 head、tail 等 Bash 命令分析海量数据,而从不把完整数据对象载入上下文。这种方式与人类认知如出一辙:我们通常不会背下整个语料库,而是借助文件系统、收件箱、书签这类外部组织与索引系统,按需检索相关信息。

除了存储效率,这些引用的元数据还提供了一种高效微调行为的机制——无论这些线索是显式给出的还是直觉性的。对一个在文件系统中作业的 Agent 来说,tests 文件夹里出现名为 test_utils.py 的文件,与 src/core_logic/ 目录下同名文件的用途暗示截然不同。文件夹层级、命名约定、时间戳都在提供重要信号,帮助人和 Agent 判断如何以及何时使用某条信息。

让 Agent 自主导航与检索数据还带来渐进式披露(progressive disclosure):Agent 可以通过探索逐步发现相关上下文。每次交互产出的上下文都会塑造下一个决策:文件大小暗示复杂度;命名约定透露用途;时间戳可作为相关性的代理指标。Agent 可以一层层组装理解,只在工作记忆中保留必要内容,并用笔记策略做额外持久化。这种自管理的上下文窗口让 Agent 聚焦于相关子集,而不是淹死在详尽却可能无关的信息里。

当然,这里有取舍:运行时探索比取回预计算数据更慢。不仅如此,要让 LLM 拥有合适的工具与启发式、高效导航它的信息版图,也需要有态度、有章法的工程。缺乏恰当引导时,Agent 可能因滥用工具、钻进死胡同或未能识别关键信息而浪费上下文。

在某些场景下,最有效的 Agent 或许会采用混合策略:为速度预先检索一部分数据,同时自行决定是否继续自主探索。「恰当自主度」的决策边界取决于任务本身。Claude Code 就是采用这种混合模型的 Agent:CLAUDE.md 文件会被「无脑」预载进上下文,而 glob、grep 这类原语让它能导航环境、即时取回文件,从而有效绕开了索引过期与复杂语法树的问题。

混合策略可能更适合内容动态性较低的场景,比如法务或金融工作。随着模型能力提升,代理式设计的趋势会是让聪明的模型聪明地行事,人类策展的比重逐步下降。考虑到这个领域推进的速度,「做最简单可行的事」(do the simplest thing that works)很可能仍是我们给基于 Claude 构建 Agent 的团队的最佳建议。

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

长时程(long-horizon)任务要求 Agent 在 token 数量超出 LLM 上下文窗口的连续动作序列中,保持连贯性、上下文与目标导向行为。对于跨越数十分钟到数小时连续工作的任务——比如大型代码库迁移或全面的研究项目——Agent 需要专门的技术来绕开上下文窗口大小的限制。

等更大的上下文窗口出现,看起来是个显而易见的策略。但很可能在可预见的未来,各种尺寸的上下文窗口都逃不开上下文污染(context pollution)与信息相关性问题——至少在你追求最强 Agent 表现的场景如此。为了让 Agent 能在更长的时间跨度上有效工作,我们开发了几个直接应对上下文污染约束的技术:压缩(compaction)、结构化笔记(structured note-taking)与多代理架构(multi-agent architectures)。

压缩

压缩是指:当对话逼近上下文窗口上限时,总结其内容,然后用这份摘要重新初始化一个新的上下文窗口。压缩通常是上下文工程中驱动长期连贯性的第一个杠杆。它的核心是以高保真的方式蒸馏上下文窗口的内容,让 Agent 能在几乎不损失性能的情况下继续工作。

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

压缩的艺术在于取舍:过于激进的压缩会丢失那些微妙却关键的上下文——它们的重要性往往要在很久之后才显现。对实现压缩系统的工程师,我们建议在复杂的 Agent 轨迹(trace)上仔细调优你的提示。先最大化召回(recall),确保压缩提示捕获轨迹中每一条相关信息;再迭代提升精确率(precision),剔除多余内容。

一个唾手可得的冗余内容例子是清除工具调用与结果——当某次工具调用已经深埋在消息历史里,Agent 为什么还需要再看一遍原始结果?最安全、最轻量的压缩形式之一就是工具结果清除(tool result clearing),最近已作为功能在 Claude Developer Platform 上线。

结构化笔记

结构化笔记,或称代理式记忆(agentic memory),是指 Agent 定期把笔记持久化到上下文窗口之外的记忆中,并在之后把笔记拉回上下文窗口的技术。

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

Claude 玩宝可梦(Claude playing Pokémon)展示了记忆如何在非编程领域改变 Agent 的能力。这个 Agent 在数千个游戏步骤中维持精确的计数——跟踪诸如「过去 1234 步我一直在 1 号道路训练我的宝可梦,皮卡丘已升了 8 级,目标是 10 级」之类的目标。无需任何关于记忆结构的提示,它自己发展出已探索区域的地图,记住解锁了哪些关键成就,并维护战斗策略的战术笔记,帮助它学会对不同对手哪些招式最有效。

在上下文重置之后,Agent 会读自己的笔记,继续数小时的训练流程或地牢探索。这种跨越摘要步骤的连贯性,使得长时程策略成为可能——若只靠 LLM 上下文窗口容纳全部信息,这些策略根本无法实现。

作为 Sonnet 4.5 发布的一部分,我们在 Claude Developer Platform 上发布了公测版记忆工具(memory tool),通过基于文件的系统更方便地在上下文之外存储和查阅信息。这让 Agent 能随时间积累知识库、跨会话维护项目状态、引用之前的工作,而不必把一切都留在上下文里。

子代理架构

子代理架构提供了绕开上下文限制的另一条路。与其让一个 Agent 试图在整个项目上维持状态,不如让专门的子代理(sub-agent)在干净的上下文窗口中处理聚焦的任务。主代理以高层计划进行协调,子代理执行深入的技术工作或用工具查找相关信息。每个子代理可能进行大范围探索,消耗数万甚至更多 token,但只返回一份浓缩的、蒸馏过的摘要(通常 1000-2000 token)。

这种做法实现了清晰的关注点分离——详细的搜索上下文被隔离在子代理内部,主代理专注于综合与分析结果。我们在《How we built our multi-agent research system》中讨论过这个模式,它在复杂研究任务上大幅优于单代理系统。

在这些方法之间如何选择,取决于任务特征。例如:

  • 压缩适合需要大量来回对话的任务,保持会话的连续性;
  • 笔记擅长有清晰里程碑的迭代式开发;
  • 多代理架构适合并行探索能带来回报的复杂研究与分析。

即便模型持续进步,在超长交互中维持连贯性的挑战,仍将是构建更有效 Agent 的核心。

结语

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

随着模型改进,我们概述的这些技术还会继续演化。我们已经看到,更聪明的模型需要的规范化工程更少,Agent 能以更高自主度运转。但即使能力不断放大,把上下文当作珍贵而有限的资源来对待,仍将是构建可靠、有效 Agent 的核心。

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

致谢

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

延伸阅读:想继续深入 Agent 与上下文管理,可以浏览站内 Agent 专题AI Coding 专题;关于上下文约束下的评测与迭代方法,参见 FDE 实践指南;若想了解这些能力在交付各阶段如何落地,可阅读 FDE 项目生命周期

本文由 FDEChina 团队翻译自原文,转载已注明出处;如需引用请以原文为准。