摘抄自 https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
随着AI领域发展,Building with LLMs (和LLM交互、基于 LLM 开发应用/系统等)已经不是简单的“提示词工程”能够覆盖全面的了。重点转向更宏观的问题——“怎样的上下文配置最有可能引发模型预期的行为?”
上下文指的是从大型语言模型中抽取样本时所包含的 token 集合。
当前面临的工程问题是,在大型语言模型的固有限制条件下,优化这些 token 的效用,从而始终实现预期的结果。
有效利用大型语言模型通常需要结合上下文来思考——也就是说,要考虑到大型语言模型在任意时刻所处的全局状态,以及该状态可能引发的种种行为。
本篇文章:探讨新兴的上下文工程艺术,并提出一种精炼的思维模型,用于构建可控且高效的 Agent。
提示词工程
除了日常聊天之外,大多数应用场景都需要针对一次性分类或文本生成任务优化提示。
指的是为获得最佳结果而编写和组织 LLMs 指令的方法,核心在于如何编写有效的提示(遣词造句,寻找恰当的词汇和短语),尤其是系统提示。
上下文工程
因素:开发具备多轮推理能力和更长时间处理能力的 Agent,在循环中 Agent 会生成越来越多可能与下一次推理相关的数据,这些信息需要不断循环优化。 需要有策略来管理整个上下文状态——包括系统指令、工具、模型上下文协议、外部数据、消息历史记录等。
上下文工程则指的是一系列用于在 LLMs 推理过程中 筛选和维护最优信息集的策略,从不断变化的信息海洋中筛选出适合纳入有限上下文窗口的内容。
上下文工程为什么重要?
上下文遗忘
根据 https://research.trychroma.com/context-rot 的研究:即使上下文窗口未满,在长上下文窗口中填充更多 token,通常会降低模型答案的可靠性。
这与我们以为的 “大型语言模型通常被假定能均匀处理上下文信息——也就是说,模型对第10,000个 token 的处理能力和对第100个 token 的处理能力应该相同” 认知不同
因此,上下文应被视为一种具有递减边际收益的有限资源。
原因:注意力稀缺
LLMs 基于Transformer架构,该架构使得每个 token 能够关注整个上下文中的其他所有 token。这样一来,当有n个 token 时,就会产生n²种成对关系。 随着上下文长度的增加,模型捕捉这些成对关系的能力会减弱,从而在上下文规模和注意力焦点之间产生天然矛盾。此外,模型的注意力模式是依据训练数据分布形成的,其中较短序列通常比较长序列更为常见。这意味着模型在处理全局上下文依赖关系时经验不足,相关专用参数也较少。
这些现实情况意味着,精心设计的上下文工程对于构建功能强大的智能体至关重要。
高效上下文的构成要素
System Prompt
错误示例:
- 极端具体(僵化,过度约束,反而限制了模型的发挥):在提示中硬编码复杂的、脆弱的逻辑规则,以精确控制智能体的行为。这种方式会导致系统脆弱性增加,且随着时间推移维护成本也会上升。
- 极端模糊(笼统,缺乏指导,AI过于自由发挥导致失控):工程师提供的指导过于模糊笼统,既无法为大型语言模型提供明确的期望输出信号,又错误地假设智能体已理解相关背景信息。
最佳的状态是找到平衡点:既足够具体以有效引导智能体行为,同时又具有足够的灵活性,让模型能够根据经验规律自主决策。
正确规范:
- 拆分为不同章节
a. 例如<background_information>、<instructions>、## Tool guidance、## Output description等 - 内容简洁
a. 但并不一定意味着字数少;你仍需向智能体提供足够的信息,以确保其能按照预期行为行事 - 工具集简洁
a. 避免:工具集功能过于冗杂,导致难以决定该使用哪个工具。如果人类工程师都无法明确判断在特定情况下应使用哪个工具,那么人工智能代理自然也无法做得更好。 - 提供示例(少样本提示)
a. 避免:在提示中罗列大量边缘案例,试图涵盖 LLMs 在特定任务中应遵循的所有规则
b. 推荐:精心挑选一组多样且具有代表性的示例,以便有效展现模型的预期行为。对 LLMs 而言,示例就如同千言万语的“图片”般重要。
(运行时动态地)检索上下文和 agentic search
Agentic: 在 AI 领域通常翻译为 “智能体化” 或 “代理化”。它描述的是 AI 系统从 “被动响应” 向 “主动规划与执行” 的转变。
Agentic AI 像一位有自主性的助手,你给它一个目标(Goal),它会主动拆解任务、规划步骤、调用工具(如搜索、写代码、操作软件),直到完成任务。
Agents:LLMs 在循环中自主使用各种工具的过程。
本段核心讲的是对上下文的动态管理策略
embedding-based pre-inference time retrieval
事先预处理所有相关数据,为 Agents 提供重要的上下文信息供其推理使用。
强调一次性、所有信息
“just in time” context strategies
维护轻量级的标识符(文件路径、存储的查询、网页链接等),并在运行时通过工具动态加载这些数据以供使用。
这种方式与人类的认知方式类似:我们通常不会记住全部的信息内容,而是依靠文件系统、收件箱和书签等外部组织和索引系统来按需检索相关信息。
好处:
- 存储效率
- 渐进式披露:引用的元数据,有助于人类和 Agents 理解如何以及何时使用这些信息,实现自主导航和检索数据。
- 每次交互都会提供有助于下一次决策的背景信息:例如文件大小可反映其复杂性;命名规则能暗示其用途;时间戳则可作为相关性的参考指标等。
- 只在 working memory 中保留必要的信息,并利用 note-taking strategies 来长期保存额外信息。这种自我管理的 context window 使 Agents 能够专注于相关内容,而不会被大量可能无关的信息所淹没。
权衡:
- 相对慢
- 需要经过深思熟虑的工程设计,以确保 LLMs 拥有有效的工具和启发式方法来应对复杂的信息环境。
- 如果没有适当的指导,模型可能会因误用工具、陷入死胡同或未能识别关键信息而浪费计算资源。
混合策略:
先预先获取部分数据以提高效率,然后根据需要自主进行进一步探索。
以 Claude Code 为例:CLAUDE.md文件会被直接放入上下文中,而像glob和grep这样的工具则能让它实时导航环境并检索文件,从而有效避免了索引失效和复杂语法树带来的问题。
长周期任务下的上下文工程
本段核心讲的是如何解决超长任务场景下 context window 大小限制问题。
等待更大的的上下文窗口
不可靠。
在可预见的未来,各种大小的上下文窗口都可能受到上下文污染和信息相关性问题的影响。
压缩 Compaction
有助于保持需要大量来回交流的任务的对话流畅性
指将接近上下文窗口限制的对话内容进行总结,然后以该总结作为新的上下文窗口来继续对话。
压缩的艺术:
判断哪些内容需要保留,哪些需要舍弃,因为过度激进的压缩方式可能会导致那些细微但至关重要的上下文信息的丢失,而这些信息的重要性往往要等到后来才会显现。
示例(Claude Code):
保留了架构决策、未解决的漏洞以及实现细节,同时舍弃了冗余的工具输出或消息。
Structured note-taking
在具有明确里程碑的迭代开发中非常有用
结构化的 note,或称 agentic memory。
让 Agent 在上下文窗口之外定期记录笔记并将其保存在记忆中的技巧。这些笔记会在后续时间被重新纳入上下文窗口中。
示例: Claude Code 创建的 todo-list,或者我们自己的 agent 维护的 NOTES.md 等。
这种简单模式能让代理在处理复杂任务时追踪进度,保留关键上下文和依赖关系,否则这些信息会在数十次工具调用中丢失。
sub-agent 架构
适用于需要并行探索的复杂研究与分析任务
与其让一个 Agent 尝试维护整个项目的状态,不如让专门的 SubAgent 来处理具有明确上下文范围的特定任务。
主 Agent 负责协调高层次的计划,而 SubAgent 则执行复杂的技术工作或使用工具来查找相关信息,不论消耗多少 token,最终只返回其工作的简洁摘要给主 Agent。
总结
上下文工程代表了我们利用 LLMs 进行构建的方式的根本性转变。
随着模型能力的提升,挑战不再仅仅是设计完美的提示语,而是要精心筛选在每一步中输入模型有限注意力范围内的信息。
核心原则:找到最能最大化实现预期结果可能性的最小规模高价值 token 集合。