Context Engineering(上下文工程)
上下文工程(Context Engineering) 是通过精心筛选、组织和注入信息,为 LLM 在每个推理步骤构建高质量上下文窗口的工程方法论。它是 Loop Engineering(循环工程)的第二阶段,在Prompt Engineering(提示工程)之上建立,并作为子层被Harness Engineering(驾驭工程)包含。
Anthropic Applied AI Team 定义:「在 LLM 推理期间管理最优 token 集合的策略集,包括所有可能进入 prompts 的信息」。核心原则:找到在每步最大化期望结果的最小高信号 token 集。Anthropic 将模型的有限上下文容量称为注意力预算(attention budget)——这个比喻揭示了上下文工程的本质:在每步裁决什么信息值得花费这份有限预算。
为什么需要上下文工程
提示工程解决"如何有效地问 AI 一个问题",但长视野 Agent 任务带来了新的核心问题:"模型在每步应该看到什么?"
三个基础约束使上下文管理无法靠扩大窗口解决:
二次注意力成本:Transformer 自注意力对 n 个 token 计算 n² 对权重,上下文加倍代价翻四倍,使窗口成为稀缺资源。
U 型注意力曲线:文档放在上下文中间比放在开头/末尾,准确率低 30% 以上(Liu et al., 2024)。信息在上下文中的位置与信息存在本身同等重要——检索到正确内容但放置不当,收益接近零。
Context Rot(上下文腐烂):所有前沿模型随输入增长而退化,且退化在窗口远未满时即已开始。这是任何跨多步积累工具结果的 Agent 的正常运行条件,不是边缘情况。
上下文窗口的 7 类竞争内容
Agent 的上下文窗口不是一张空白画布——它被 7 类内容争抢,上下文工程的本质是裁决"谁进、谁出、谁排多前"。
| 类别 | 说明 | 典型体积 |
|---|---|---|
| 系统提示(System Prompt) | Agent 身份、行为规则、控制流逻辑、不同任务类型的指令——在 Agent 语境下不止是"保持友善",它可以定义整套架构 | 固定预算,每次调用都要占 |
| 工具定义(Tool Definitions) | 每个工具的 schema(名称、描述、参数类型),工作前就要全量注入 | 40+ 工具 ≈ 10,000 token |
| 工具调用结果(Tool Call Results) | 每次工具调用的输出追加进上下文——一次网页检索 5,000–10,000 token,一次文件读取类似 | 随调用次数线性累积 |
| 检索知识(Retrieved Knowledge / RAG) | 向量数据库、搜索结果、API 响应——任何为辅助决策而检索的文档 | 按需,可控 |
| 对话历史(Conversation History) | 完整的消息记录——用户消息、Agent 响应、推理过程、已有决策 | 随轮次线性增长 |
| 记忆(Memory) | 本次会话的短期记忆、跨会话的长期记忆(偏好、历史结果、学习到的模式) | 取决于检索策略 |
| Agent 状态(Agent State) | 当前计划、todo 列表、进度标记、草稿——追踪多步任务进度的元信息 | 可控,取决于设计 |
所有 7 类在争夺同一个有限窗口。上下文工程就是裁决谁赢。
三层时间架构
生产实践催生了对应操作系统内存层次的三层架构:
短期:活跃上下文窗口管理
系统 prompt 校准:系统 prompt 建立 Agent 的行为包络,消耗每次调用的固定预算。核心挑战是找到合适"海拔":过于具体引入脆弱的、需要维护的逻辑;过于模糊使模型缺乏有效指导。实践模式:XML 标签或 Markdown 标题清晰分隔背景/指令/工具指南/输出格式,从最小 prompt 开始,通过观察失败模式逐步增加有针对性的指令。
Token 高效工具设计:每个工具 schema(名称、描述、参数类型)在每次调用时都注入上下文。大型工具集可在 Agent 读取用户请求前消耗数万 token。原则:更少但更好的工具——如果人类工程师无法判断在给定情况下哪个工具适用,模型也无法做到。
面向 Agent 的工具设计把这条原则落到工具集合和工具输出两端:少量高层工具可以减少工具选择分支;concise / detailed 响应格式、分页、过滤和可解释截断可以减少每次工具调用回填的 token。工具定义和工具结果都属于上下文预算的一部分,不能只优化 prompt 而忽略工具响应。
渐进披露(Progressive Disclosure / Just-in-Time Retrieval):不预先加载所有潜在相关信息,而是维护轻量标识符(文件路径、查询字符串、链接),在任务展开时按需加载。Anthropic 也称之为 Just-in-Time(即时)检索,并类比人类认知——“我们通常不记忆整个信息语料库,而是知道去哪里找”。Claude Code 的混合策略:CLAUDE.md 在会话启动时加载提供项目上下文(稳定的全局规则),glob 和 grep 让 Agent 在任务进行中按需加载特定文件内容(避免大前缀的代价)。
Agent Skills 是渐进披露的一个更标准化实现:Agent 启动时只看每个 Skill 的 name 和 description,任务命中后才读取 SKILL.md 正文,再按需要打开 references/、assets/ 或运行 scripts/。这把“能力发现”与“能力细节”分离,适合大量低频组织流程和领域知识;如果全部放进系统 prompt,会同时增加上下文成本和 Context Confusion(上下文混乱)风险。
KV-cache 感知设计:Prompt Caching(提示缓存)是生产 Agent 部署中最具成本效益的优化,但其收益完全取决于上下文结构。Manus 团队将 KV-cache 命中率识别为"生产 AI Agent 最重要的指标"——命中 token 成本($0.30/MTok)约为未命中的 1/10($3.00/MTok)。三条设计规则:
- 保持 prompt 前缀稳定(前缀的单 token 差异使后续所有内容的缓存失效);
- 将上下文视为仅追加(修改过去的动作或观察破坏缓存复用);
- 使用确定性序列化(JSON 键排序不稳定会静默地使缓存失效)。
Codex 的做法体现的是同一类缓存友好结构:新一轮 Responses API 请求尽量以前一轮输入为精确前缀,只在末尾追加 reasoning、tool call 和 tool output,避免回头修改早期输入导致缓存失效。
中期:会话状态与跨运行持久化
中期管理解决的问题是:Agent 如何在不依赖完整对话历史的情况下跨多次运行保持状态?
结构化笔记(Structured Note-Taking):Agent 维护持久的笔记文件(NOTES.md、todo.md),在每次运行开始时读取,在上下文清除前更新。这类文件化状态就是一种Agent Memory(Agent 记忆)。Anthropic Applied AI Team 以 Claude 跨数千游戏步骤玩宝可梦为案例:在没有任何显式记忆结构指令的情况下,Agent 自发发展出已探索区域地图、战斗策略记录和对手追踪——关键洞察是笔记将工作记忆外化,不依赖对话历史传递任务状态。
文件化规划(File-Based Planning):将完整规划表示持久化到磁盘。任务状态、规格、中间结果和依赖图在每个里程碑后写入文件系统,在下次运行开始时选择性加载——完全绕过上下文窗口处理当前步骤不立即相关的内容。
数据研发 Multi-Agent 的一个具体实现是把 阶段摘要 与 Spec 文件 组合使用:每个阶段结束时,只把结论、关键字段和待关注事项压缩成固定格式的 checkpoint 摘要;不同 specialist 不传递完整对话,而是通过预定义 schema 的需求、方案、SQL 和测试文件交接,协调者只传文件路径。这样完整产物仍可追溯和审计,下一阶段的模型视图却只加载当前任务需要的文件。它同时实现了 Compress、Write 与 Isolate,任务中断后这些文件也可供持久执行恢复。
跨运行注入(Cross-Run Injection):捕获上一次运行的显著输出并在下次运行开始时注入。如 claude-mem 作为插件式记忆层:捕获会话历史、提取下次运行有用的信息、在下次会话上下文前预置。不需要向量数据库或图存储,却提供实质性的跨运行连续性。
Session log as context object(会话日志作为上下文对象):Claude Managed Agents 把完整事件历史存为 append-only session log,而不是把它等同于 Claude 的上下文窗口。harness 可用 getEvents() 按位置切片、回看某个动作前后的事件,再把选中的事件转换成当前调用需要的上下文。这保留了可恢复原始历史,同时把摘要、裁剪、重排、prompt cache 组织等不可逆上下文工程决策留给 harness。
长期:持久记忆系统
长期系统提供有索引的可检索存储,跨会话、任务和 Agent 实例持久化。中期技术依赖前向注入摘要;长期系统支持任意检索——给定查询,无论记忆何时创建都能找到最相关的内容。
OS 启发的分层记忆(MemGPT):Packer et al.(2023)引入关键抽象——将 LLM 上下文窗口视为 RAM,外部存储视为磁盘,给模型提供显式页面信息进出的函数调用。类比虚拟内存:应用程序(Agent)获得比物理限制更大的逻辑内存的幻觉。
观察-反思-检索三元组(Generative Agents):Park et al.(2023)的 Memory Stream 架构将 Agent 所有观察存储为带时间戳和重要性评分的自然语言记录。每步检索通过三个信号加权:近期性、重要性(Agent 写入时的自评)、与当前查询的相关性。第二个机制 Reflection 定期问"我最近经历中最显著的问题是什么"并存储高层次洞察。消融实验表明三个组件均不可或缺,移除任一产生可测量退化——观察-反思-检索三元组成为 Agent 记忆设计的标准模板。
混合存储生产系统(Mem0):目前最广泛部署的长期记忆层(14M+ Python 下载,41K GitHub stars)。架构:向量数据库(语义相似性搜索)+ 图数据库(关系建模)+ 键值存储(快速事实检索)。LLM 提取层处理新交互、识别事实与偏好、将记录路由到适当存储后端。在 LOCOMO 基准上比 OpenAI 原生记忆精度高 26%,同时使用 90% 更少 token。2025 年被 AWS Agent SDK 选为独家记忆提供商。
动态知识网络(A-MEM):借鉴卡片笔记法(Zettelkasten)——不把记忆存储为平面记录,而是为每条新记忆生成包含关键词、标签、概念描述和语义相关记忆动态链接集的结构化笔记。添加新记忆时,不仅存储它,还追溯更新相关已有笔记的上下文和属性,使记忆图随知识积累而演化。解决了基于检索系统的一个基础局限:存储记忆时其重要性可能尚不明显,只能在与后续信息关联时才显现。
长视野挑战:上下文漂移
100+ 轮次后,所有上述技术都能减慢但无法停止上下文漂移——Agent 行为随扩展交互而渐进偏离原始意图。每次压缩步骤引入微小不准确性并随轮次复合累积;Agent 开始重复已完成的工作,与早期决策矛盾,遗忘任务动机目标。
上下文漂移与Context Rot(上下文腐烂)不同:腐烂是单次推理步骤的属性(上下文增长 → 检索/推理质量下降),漂移是扩展轨迹的属性(压缩不准确性随轮次复合)。
上下文工程单独无法解决漂移。需要 ETCLOVG Taxonomy(ETCLOVG 分类法) O 层(可观测性:检测行为偏离的异常检测)和 G 层(治理:人工检查点和验证循环)作为必要补充。
四大策略框架
LangChain 将所有上下文工程技术归纳为四个互补的策略桶,覆盖"从哪来、留什么、怎么精简、谁来隔离"四个维度:
Deep Agents给出了这四类策略在一个 harness 中的组合实现:AGENTS.md memory 和虚拟文件系统负责 Write,Agent Skills 负责 Select,自动摘要与大结果卸载负责 Compress,临时 subagent 负责 Isolate。它们不是四选一;长任务通常需要让信息先可持久化,再按需加载、持续压缩,并把高噪声子任务隔离出去。
Write — 持久化,对抗遗忘
当 Agent 上下文填满被压缩,没有写出去的信息就永久消失。Write 策略给 Agent 一种在上下文窗口之外持久化信息的方式。
- Scratchpad(草稿本):给 Agent 一个工具,允许它在任务过程中随时记笔记。Anthropic 实现了"think"工具——一个专用的推理空间,在 tau-bench 基准上某些任务性能提升达 54%。
- 规则文件(Rules Files):持久化的程序记忆。以 CLAUDE.md 为代表,在每次会话开始时加载,让 Agent 始终记住基础规定。
- 记忆提取(Memory Extraction):Agent 将跨会话有价值的事实、用户偏好、学习到的模式保存到上下文窗口之外,下次用时检索。
Select — 按需检索,不塞全量
Agent 不应在每一步都看到全部工具定义、知识库和历史记录。Select 策略让 Agent 只拿当前步骤需要的内容。
- Agentic RAG vs 传统 RAG:传统 RAG 由系统决定检索什么,是一次性的静态流程。Agentic RAG 由 Agent 自己决定——发出查询、精化结果、判断何时够用——把检索变成迭代过程。
- RAG over tool descriptions(RAG-MCP):40+ 工具时,工具定义就能消耗 10,000 token。方案:用语义检索只给当前步骤加载相关工具。RAG-MCP 论文实测工具选择准确率从 14% 升至 43%(3×),token 用量减少约一半。
- 工具掩码(Tool Masking)vs 工具移除(Tool Removal):稳定地把全量工具定义放进前缀(可缓存),只在调用时标记哪些工具当前可用——避免因频繁增删工具而让 KV-Cache 失效。
Anthropic 称之为混合策略:前加载基础内容(CLAUDE.md),其余按需检索(just-in-time retrieval)。
Compress — 保留语义,删减 token
即便做好了 Select,上下文仍会积累。80,000 token 的工具调用历史里,大部分已无用,但还在占位、分散注意力、拉高成本。Compress 策略在三个时间点削减 token:
| 时间点 | 技术 |
|---|---|
| 信息进入上下文前 | 文档分块 + 重排;工具输出即时摘要 |
| Agent 运行中 | 滚动历史摘要(保留最近 N 条完整 + 其余压缩);硬截断 |
| Agent 行动之后 | 工具结果清除——15 步前用过的完整输出用一行摘要替换 |
Claude Code 的自动压缩在上下文达 95% 容量时触发,自动摘要完整轨迹。实践发现输出质量在 40–60% 容量时即开始退化——留大窗口不等于塞满窗口。
Isolate — 隔离上下文,防止污染
长期 Agent 运行的深层问题不只是空间,还有污染:研究阶段留下的详细文件搜索结果,在编码阶段仍坐在上下文里,成为噪音。Isolate 策略为不同阶段的工作分配独立的上下文窗口。
- 子 Agent:父 Agent 委派子任务给子 Agent,子 Agent 在干净的上下文里工作,完成后只向父 Agent 返回浓缩摘要。所有混乱的中间搜索留在子 Agent 的上下文里,不污染父 Agent。
- 状态 schema 隔离(LangGraph 方案):把 Agent 状态的不同字段分配不同类型的上下文。LLM 每步只看与当前步骤相关的字段;工具结果存放在"后台"字段,不显式浮现时模型看不到。
四种失效模式
Drew Breunig 识别了 Agent 上下文增长时的四种典型失效模式——每一个出错的 Agent 都能归入其中。
失效 1:Context Poisoning(上下文中毒)
幻觉或错误信息进入上下文,Agent 在后续每一步都引用它,坏数据在第 5 步产生,在之后每步都复合放大。
修复:在工具输出进入上下文前验证;从错误中恢复后,压缩失败尝试的历史——不要把 10 步死路调试仍然暴露在视野中。
失效 2:Context Distraction(上下文分心)
上下文太长,模型开始过度依赖近期历史,不再综合出新计划,只是重复最近做过的事。它停止了思考,开始了重复。
修复:即使还有大窗口空间,也要主动摘要和裁剪。大窗口不意味着要填满。
失效 3:Context Confusion(上下文混乱)
多余内容导致模型决策质量下降。经典例子:给模型 46 个工具时基准测试失败,改为 19 个工具后正常工作——不是 token 放不下,而是工具太多让模型无法清晰推理。
修复:使用动态工具管理(RAG-MCP),只给当前阶段加载相关工具。
失效 4:Context Clash(上下文冲突)
新信息与上下文中已有内容矛盾——系统提示说一回事,检索文档说另一回事,Agent 无法调和,产生不一致行为。
修复:建立明确的权威排序:系统提示 > 检索事实 > 对话历史。注入新信息前先验证是否与已有上下文冲突;用 XML 标签或 Markdown 标题区分来源,让模型知道信任哪个。
Frequent Intentional Compaction
Dex Horthy(HumanLayer CEO)在 AI Engineer Code Summit 上分享的工作方法:团队用此法在 7 小时内向一个大型 Rust 代码库交付了约 35,000 行代码。
核心思路:把 Agent 工作拆成阶段,每阶段产出一个压缩产物,下一阶段以新鲜上下文启动,只携带该产物。始终刻意保持在 40–60% 上下文容量以下。
Phase 1 — Research(研究)
Sub-agents 探索代码库、读文件、追数据流 [Isolate]
→ 输出:compact research.md [Write]
→ 从 60–80% 压缩到 15–20% [Compress]
Phase 2 — Planning(规划)
新上下文:research.md + 问题定义
→ Agent 产出详细实现计划
← 最重要的人工审查点(此时改错最廉价)
Phase 3 — Implementation(实现)
新上下文:plan.md
→ Agent 逐步跟随计划
→ progress.md 追踪已完成/未完成 [Write]结果:每阶段的 Agent 都是干净、聚焦的——无污染、无上下文腐烂、无"第 20 步变马虎"。
主流平台实现对比
不同平台在面对相同的上下文约束时选择了不同的设计哲学:
Claude Code
混合检索策略:CLAUDE.md 在会话启动时预加载(提供稳定的项目上下文),glob 和 grep 让 Agent 在任务进行中按需导航代码库。上下文达到 95% 容量时自动压缩,保留架构决策和最近访问的文件。复杂子任务可委托给拥有独立上下文的子 Agent。哲学:do the simplest thing that works——让模型自己判断需要什么,给它工具去找。
Manus
专为大规模生产(百万用户)优化的效率优先设计。KV-cache 感知的上下文排序:稳定内容(系统 prompt、工具定义)放前缀,动态内容(对话历史、当前步骤)放后缀,以最大化缓存命中率。工具掩码而非工具移除——工具定义保持在可缓存前缀,只在当前不可用时标记,避免因工具列表变化而使缓存失效。每条工具输出经过压缩流水线处理后才进入 Agent 上下文。持久 todo 列表追踪状态;文件系统作为被驱逐上下文的溢出记忆。
ChatGPT Agent
视觉优先策略——Agent 通过 GUI 浏览器与世界交互,截图作为上下文快照,模型对所看到的内容进行推理。视觉 token 昂贵,Agent 对截图数量保持克制。工具使用策略不通过显式编程习得,而是通过在数千台虚拟机上的强化学习(RL)发展出来。
Google ADK
最有工程纪律的设计哲学,基于三条原则:
- 分离存储与呈现——持久状态与每次 API 调用时的上下文快照是两件事,不能混同
- 显式转换(Explicit Transformations)——上下文的每次变换都是具名、有序、可测试的处理器,而非隐式的字符串拼接
- 默认范围化(Scope Context by Default)——每次模型调用只看到必要的最小信息集
工程纪律高于提示技巧。
通用 Agent Turn 流水线
所有主流 Agent 平台(Claude Code、Manus、ChatGPT Agent、Google ADK)在每个 agent turn 内部都收敛到同一个五步循环:
Collect → 收集用户输入、对话历史、工具结果、检索文档、Agent 状态
Select → 在剩余 token 预算内筛选当前步骤相关内容
Compress → 摘要、截断、重构,使内容适合上下文
Arrange → 稳定内容(可缓存)放前,动态内容放后
Assemble → 组装最终上下文 → 发 API 调用 → 获得输出 → 循环这是一切生产 Agent 背后运行的循环,四大策略分别作用于这五步的不同位置。
API 层压缩
Responses API(响应 API) 的 compact 端点把上下文压缩从客户端提示词技巧提升为 API 能力:当 Codex CLI 的自动压缩阈值被超过时,旧输入会被替换为一组更短的项目,其中可以包含特殊的 compaction item 和加密内容,用来保留模型对原对话的隐含状态。
这类机制不会消除上下文漂移,因为压缩仍可能丢失任务相关细节;但它降低了长 turn 因工具输出和历史消息累积而直接耗尽 context window 的概率。
与相邻概念的关系
| 范式 | 解决的问题 |
|---|---|
| Prompt Engineering(提示工程) | 如何有效地问 AI(单次调用优化) |
| 上下文工程 | 模型每步应看到什么(多步信息管理) |
| Harness Engineering(驾驭工程) | 整个 Agent 系统如何可靠运行(基础设施全栈) |
| Loop Engineering(循环工程) | 如何让系统自己驱动、验证、持续运行 |
上下文工程是Harness Engineering(驾驭工程) C 层的核心内容,也是Loop Engineering(循环工程)中"知识管理体系"的底层支撑。
- Context Rot(上下文腐烂) — 上下文工程需要对抗的核心退化机制
- Prompt Caching(提示缓存) — 短期上下文结构影响推理成本的关键机制
- Agent Memory(Agent 记忆) — 跨运行状态持久化的实践形态
- ETCLOVG Taxonomy(ETCLOVG 分类法) — C 层在七层 harness 框架中的定位
- AI Agent(智能体) — 上下文工程服务的执行主体
- Claude Code — 最直接实践上下文工程的 Agent 编码工具,CLAUDE.md + subagent + /compact 是三个典型机制