上下文工程(Context Engineering)
业界共识已从「Prompt 工程」升级到「上下文工程」——决定 Agent 成败的,往往不是某句提示词,而是喂进上下文窗口的全部信息如何组织。Karpathy 的说法:上下文窗口是 LLM 的 RAM,上下文工程就是「为下一步计算精心装填 RAM 的艺术」。
从 Prompt 工程到上下文工程
- Prompt 工程:怎么写好一段指令,面向单轮、静态场景。
- 上下文工程:在每一步推理时,如何动态地把正确的信息、以正确的格式、在正确的时机放进窗口——面向多步、有状态、调工具的 Agent。
一句话:Prompt 工程是「写好提示词」,上下文工程是「管好整个上下文窗口」。Agent 跑几十轮后,system prompt 只占上下文的零头,真正决定行为的是积累的工具结果、历史与记忆。
上下文里都有什么?
| 成分 | 说明 | 典型占比问题 |
|---|---|---|
| System Prompt | 角色、规则、工具说明 | 写太长挤占工作空间 |
| 对话/任务历史 | 多轮交互记录 | 随轮数线性膨胀 |
| 工具定义与结果 | schema + 历次返回 | 最大的膨胀源(一次网页抓取可达数万 token) |
| 检索内容(RAG) | 知识库召回材料 | 召回过多引入噪声 |
| 记忆 | 长期记忆召回(见 记忆系统) | 条数要节制 |
| 任务状态 | 计划、中间结论、待办 | 易被新内容冲淡 |
核心矛盾:窗口有限、越长越贵越慢、还会退化,但 Agent 需要的信息越来越多。
四大操作:Write / Select / Compress / Isolate
1. 写入(Write):把信息留在窗口外
- Scratchpad/笔记文件:把计划、中间结论写到外部文件,需要时再读回——Claude Code 等编码 Agent 用 markdown 待办清单驱动长任务就是此模式。
- 长期记忆:跨会话信息入库,见 记忆系统。
2. 选择(Select):只放该放的
- 按需检索:RAG 用到再查;Tool RAG 按任务筛工具子集;few-shot 示例动态挑选。
- 即时检索 vs 预加载:新一代编码 Agent 倾向「给模型 grep/读文件工具让它自己按需查」,而不是预先把可能用到的全塞进去——把 Select 的决策权交给模型。
3. 压缩(Compress):把长的变短
- 摘要:长历史/大段工具结果压成摘要(注意有损——关键约束要单独保留)。
- 裁剪:删掉确定无用的旧轮次;工具返回设最大长度,超长截断 + 落盘留全文。
- Compaction:上下文逼近上限时整体压缩重启(保留目标、关键决策、当前状态),长任务 Agent 的标配机制。
4. 隔离(Isolate):拆分上下文
- 多 Agent 分治:每个子 Agent 维护自己的小上下文,只把结论汇报主线(见 多 Agent)。
- 沙箱执行:把大量中间数据留在代码执行环境里,只回传摘要结果。
上下文退化:为什么「多 ≠ 好」
长上下文、多轮 Agent 的四种「上下文病」:
| 失败模式 | 表现 | 对策 |
|---|---|---|
| Poisoning 污染 | 一次幻觉/坏结果进入上下文后被反复引用、滚雪球 | 校验节点、引用溯源、必要时重置 |
| Distraction 分心 | 无关内容淹没关键信息,模型重复历史而非推理 | 压缩、裁剪、控制召回量 |
| Confusion 混淆 | 工具/信息堆太多,选错用错 | Tool RAG、分组、减数量 |
| Clash 冲突 | 上下文内信息互相矛盾 | 记忆更新去矛盾、晚到信息标时效 |
再加上位置效应(lost in the middle:中部信息利用率最低)与 context rot(有效注意力随长度衰减),实践结论:关键信息放头尾、上下文保持「最小充分」。详见 长上下文专题。
KV Cache 友好:被忽视的工程维度
上下文组织方式直接影响推理成本:前缀稳定才能命中前缀缓存。
- system prompt 与工具定义放最前且保持字节级稳定(别嵌时间戳);
- 历史只追加、不回头修改(append-only);
- 动态内容(检索结果、当前任务)放后部。
做好这几条,多轮 Agent 的 prefill 成本可大幅下降(缓存命中的 token 价格通常仅为正常的十分之一左右),见 推理优化。
实践 Checklist
- system prompt 找「最小充分集」:规则太多模型反而抓不住重点;
- 工具返回设计精简结构化,超长截断落盘;
- 长任务用外部笔记驱动 + 接近上限时 compaction;
- 检索召回宁缺毋滥,控制 top-k;
- 关键约束/目标重申在上下文尾部(近因效应);
- 前缀稳定保 KV Cache 命中;
- 观测每轮上下文构成(哪些成分占了多少 token),有数据才能优化。
高频追问
Q:上下文工程和 Prompt 工程的区别? Prompt 工程优化「一段静态指令」;上下文工程管理「多步动态系统中整个窗口的内容组成」——包括历史、工具结果、记忆、检索的写入/选择/压缩/隔离。Agent 时代后者是主要矛盾。
Q:四大操作分别解决什么? Write 解决「窗口装不下 → 外存」;Select 解决「信息太多 → 只放相关」;Compress 解决「必须保留但太长 → 变短」;Isolate 解决「单上下文承载太多职责 → 拆分」。
Q:为什么上下文不是越多越好? 成本延迟线性涨;lost-in-the-middle 让中部信息利用率低;无关内容引发分心/混淆;错误信息引发污染/冲突。有效上下文 ≠ 名义窗口大小,「精准」胜过「堆量」。
Q:什么是 context poisoning?怎么防? 错误信息(幻觉或坏工具结果)进入上下文后被后续步骤当事实引用、不断放大。防:关键节点加校验/反思、工具结果核查、引用溯源、发现污染及时清理或重置上下文。
Q:长任务 Agent 上下文快满了怎么办? Compaction:总结当前目标、已完成步骤、关键决策与未尽事项,用摘要替换原始历史重启;配合外部笔记文件(计划与状态持久化在窗口外),实现「上下文无限续航」。
Q:上下文组织怎么影响推理成本? 前缀缓存只对「与上次完全相同的前缀」生效:稳定的 system prompt/工具定义放前、动态内容放后、历史 append-only,能让多轮对话大部分 prefill 命中缓存,成本下降一个量级。