跳转至

第 27 章:上下文工程(Context Engineering)— 在有限注意力里做取舍

2026 年,Agent 领域最贵的一课是:模型能力再强,喂给它的上下文不对也白搭。

Anthropic Applied AI 团队给出的定义被广泛引用:上下文工程是在有限注意力预算下,找到最小的高信号 token 集合,以最大化期望行为的艺术与科学。

本章回答三个问题:上下文为什么会失效、你的 token 到底花在哪、以及怎么动手把这三项预算砍下来。


27.1 它和 Prompt Engineering 有什么区别?

一句话区分:

Prompt Engineering Context Engineering
关注点 怎么说 给它看什么
典型动作 调措辞、加 few-shot、改语气 筛选信息、压缩历史、裁剪工具集
作用时机 单次调用 贯穿整个 Agent 生命周期
失效表现 模型理解错意图 模型压根没"看见"关键信息
类比 写好一句提问 决定让谁进会议室

🏛️ 一个比喻:Prompt Engineering 是打磨你在这场会议上的发言稿;Context Engineering 是决定会议室里坐哪十个人、桌上摆哪几份文件。

发言稿再漂亮,如果关键决策者不在场、桌上堆着三百份无关打印件,这场会也开不出结果。

为什么它在 2026 年才成为独立学科

三个条件同时成熟:

  1. 上下文窗口不再是瓶颈 —— 从 4K 到 200K 甚至 1M,装得下了
  2. 但模型"读不完" —— 窗口变大不等于注意力变强,长上下文里模型对中间信息的召回显著下降
  3. 而且每一轮都要付钱 —— Agent 是多轮循环,上下文预算是每轮复利消耗的

⚠️ 这就是为什么把"上下文更长"当成解决方案是错的。上下文不是仓库,是注意力。


27.2 根因:Context Rot(上下文腐烂)

机理

Transformer 的核心是注意力机制,它的计算复杂度是 O(n²) —— 序列中每两个 token 之间都要建立一次关联。

上下文长度    注意力能建立的成对关系
─────────────────────────────────
   1,000  →   ~1,000,000 对
  10,000  →  ~100,000,000 对
 100,000  →  ~10,000,000,000 对

上下文越长,同样的"注意力总量"被摊得越薄。 每个 token 能分到的关注度下降,模型对信息的捕获能力被稀释——这就是 Context Rot。

┌────────────────────────────────────────────────────────┐
│                                                        │
│  信息密度  ▲                                           │
│            │  ███                                      │
│            │  ███                                      │
│            │  ███        ▓▓▓                           │
│            │  ███        ▓▓▓        ░░░                │
│            │  ███        ▓▓▓        ░░░      ···       │
│            └──────────────────────────────────────────▶│
│               2K        20K        100K      上下文长度 │
│                                                        │
│   每一份新信息带来的边际收益在衰减,                  │
│   而每一份旧信息的持有成本在累积。                    │
└────────────────────────────────────────────────────────┘

三个可观察的症状

症状 表现 常被误诊为
中段迷失 长文档中间的细节被忽略 "模型理解力不够"
指令漂移 越往后越偏离最初的约束 "系统提示写得不好"
成本失控 同样的任务越跑越贵 "这个模型太贵了"

27.3 你的 token 花在哪?一次典型轮次的解剖

这是本章最有冲击力的一张表。一次典型的 Agent 轮次,输入 token 的构成:

组成 占比
历史对话 + 历史工具输出 46%
检索到的文档 24%
工具定义 / Schema 18%
系统提示 9%
用户真正问的那个问题 3%
┌─────────────────────────────────────────────────────────────┐
│ ████████████████████████████  46%  历史对话与工具输出        │
│ ███████████████              24%  检索到的文档               │
│ ███████████                  18%  工具定义                   │
│ █████                         9%  系统提示                   │
│ ██                            3%  ← 用户真正的问题           │
└─────────────────────────────────────────────────────────────┘

两条结论:

  1. 用户那个真正重要的问题,只占 3%。 剩下 97% 是"为了让模型能回答这 3% 而付出的背景"。
  2. 历史输出是最大的单项开销(46%),而且它是累积的——第 100 轮时,你在为第 1 到 99 轮的全部冗余付钱。

💡 优化上下文的第一步不是"写得更好",是"扔得更多"。


27.4 第一刀:收缩工具集(投入产出比最高)

如果你的 Agent 只能用一件事优化上下文,砍工具集。

一个真实量级

优化前 优化后 变化
工具数量 46 个 15 个(相关的) −67%
工具定义 token ~6,900 ~2,250 −67%

关键点:这笔钱不是一次性的,是每一轮都要付的。

为什么会这样

工具定义(JSON Schema + description)必须在每轮请求里完整发送,否则模型不知道有这些工具。一个工具的 schema 平均是 100~200 token,46 个就是几千 token 常驻。

更糟的是工具太多会让模型选错——选项越多,语义越接近的工具越容易混淆。

46 个工具                          15 个工具
┌────────────────────┐            ┌────────────────────┐
│ search_files       │            │ search_files       │
│ search_web         │            │ read_file          │
│ search_code        │  ← 混淆    │ edit_file          │
│ search_docs        │            │ run_command        │
│ grep_files         │            └────────────────────┘
│ find_in_files      │              职责清晰,选择明确
│ locate_symbol      │              每轮省 ~4,650 token
│ ... 还有 39 个      │
└────────────────────┘

四条实操建议

  1. 按任务动态加载工具 —— 不要一次性注册全部工具,按任务类型分组
  2. 合并语义重叠的工具 —— search_files / grep_files / find_in_files 往往是同一个东西的三份描述
  3. description 要短但要排他 —— 写清"什么时候不该用它",比重复描述功能更有效
  4. 优先用 skill 而非工具承载多样性 —— 这正是第 26 章 Skills 的价值:把 N 个领域的知识用 ~100 token/个常驻,而不是 N 个工具定义常驻

🔗 这是本章与上一章的连接点:Skills 的渐进式披露,本质上就是一种上下文工程技术——把 46 个工具常驻的负担,换成 15 个工具 + 若干 100-token 的目录条目。


27.5 Anthropic 的三板斧

面对长任务(跨几十轮、数十万 token),官方推荐三个手段:

27.5.1 Compaction(压缩)

做法:逼近上下文窗口上限时,让模型对历史做一次总结,用总结替换原始历史。

压缩前: [轮1原始][轮2原始]...[轮50原始]           ← 100% context
                    ↓ 总结
压缩后: [决策摘要][轮49][轮50]                     ← 15% context

总结时必须保留的三类信息:

保留 丢弃
架构决策及其理由 重复的工具调用输出
尚未解决的 bug 已经作废的尝试过程
关键实现细节(接口签名、配置项) 大段的原始文件内容(需要时重新读)

⚠️ 最常见的错误:把"尽可能完整地总结"当成目标。压缩的目标是保住后续行动需要的信息,不是写会议纪要。

27.5.2 Structured Note-taking(结构化笔记)

做法:让 Agent 把关键状态写到上下文之外的持久化存储(文件、数据库),需要时再读回来。

上下文内                          上下文外(持久化)
┌─────────────────┐              ┌──────────────────────┐
│ 当前轮次的对话   │   写 →       │ notes/task-state.md  │
│                 │    ← 读      │ notes/decisions.md   │
│                 │              │ notes/progress.json  │
└─────────────────┘              └──────────────────────┘

为什么它比 Compaction 更进一步:Compaction 是有损且有次数限制的(每次总结都会再丢一点信息),而笔记是无损且跨越 session 重置的。

典型用法:给 Agent 一个固定的笔记文件路径,在系统提示里要求它"每完成一个里程碑就更新进度"。

27.5.3 Sub-Agent 架构

做法:让子 Agent 在干净的上下文里深挖,只向主 Agent 回传 1,000~2,000 token 的浓缩摘要。

主 Agent(上下文保持精简)
    ├── 子 Agent A:阅读 50 个文件 → 回传 1.5K token 结论
    ├── 子 Agent B:跑 100 次搜索   → 回传 1.5K token 结论
    └── 子 Agent C:调试一个模块    → 回传 1.5K token 结论

主 Agent 的上下文增长:4.5K token
如果自己干,上下文增长:可能 200K+ token 且塞不下

官方数据:Anthropic 报告其多 Agent 研究系统在研究类评测上,比单 Agent Opus 4 高出 90.2%。

💡 为什么不只是因为"人多力量大":真正的收益在上下文隔离。每个子 Agent 都能在自己的窗口里放满高信号信息,而不会被其他任务的噪音污染。

三板斧怎么选

场景 首选 理由
单任务跨很多轮 Compaction 简单直接,无需改架构
需要跨 session 续接 Structured Note-taking 笔记能活过上下文重置
任务可并行、探索面广 Sub-Agent 上下文隔离,收益最大
生产环境长期运行 三者叠加 它们解决的是不同层次的问题

27.6 六个可立刻落地的手段

手段 做什么 省在哪
① 工具集收敛 46 → 15 个相关工具 每轮 −67% 工具定义
② 输出裁剪 工具返回前先截断/字段过滤 历史输出(46% 那块)
③ 引用代替内联 大段内容写文件,上下文里只放路径 避免重复搬运同一份内容
④ 分层检索 先读目录/索引,命中后再读全文 检索文档(24% 那块)
⑤ 结构化笔记 关键状态落盘,按需读回 跨 session 累积
⑥ 定期压缩 到阈值就总结,保留决策与未决项 长尾冗余

优先级建议:① → ② → ④ → ⑥ → ③ → ⑤ (左上角的投入产出比最高:工具集收敛几乎不需要改代码。)


27.7 度量:你的上下文健康吗?

不要凭感觉。以下四个指标建议常态化采集:

指标 健康阈值 说明
单轮输入 token 视任务定,但要有上限预算 突然飙升说明有东西泄漏
用户问题占比 越低越危险 参考值 3%,低于 1% 说明信息太多
工具定义占比 < 20% 超过就该砍工具了
上下文增长率/轮 应远低于单轮 token 接近 1.0 说明几乎没有回收机制

一个 5 分钟的体检办法:随便跑一个典型任务,dump 出最后一轮的完整输入,统计各段占比。第一次做这个的人,通常会发现某一段占了意料之外的比例。


27.8 反模式清单

❌ 反模式 为什么错 ✅ 替代方案
"上下文越长越好,全塞进去" Context Rot,中段信息会被忽略 分层按需加载
把所有工具一次性全部注册 每轮付 6,900 token 且容易选错工具 按任务动态加载,控制在 15 个
完整原始输出直接回灌 一次大输出污染后面所有轮次 输出裁剪,只回传必要字段
无限追加历史不舍得丢 成本每轮累积,迟早爆 到阈值就 Compaction
用上下文当数据库 重启即失、且占预算 笔记/文件/真正的存储
压缩时"保留全部细节" 那不叫压缩 只留决策、未决项、关键接口

27.9 一个野性佐证

GitHub 上有个项目叫 caveman,109K 星,日增 505。

它做的事极其简单:把提示词改写成"穴居人语"来压缩 token(Please analyze → Me look),压缩率 65%。

当一个玩笑项目能拿十万星,说明 token 成本已经痛到什么程度了。

上下文工程之所以在 2026 年成为独立学科,不是因为学术界突然感兴趣——是因为账太贵了。

还有一个更"正经"的佐证:x1xhlol/system-prompts-and-models-of-ai-tools(144.1K ⭐)收录了 Cursor、Devin、Claude Code、CodeBuddy 等产品的真实系统提示词,3.4 万 fork。逐份读下去你会发现,这些千锤百炼的提示词里有相当大的篇幅在做的事就是本章的主题——管理注意力:声明工具格式约束、注入顺序、放弃话术、禁止行为。读完再回头看本章的六手段,会有"英雄所见略同"的踏实感。更系统的导读见 第 28 章。


27.10 小结

记住这一点 为什么
上下文不是仓库,是注意力 n² 注意力机制决定了装得多 ≠ 看得清
用户的问题只占 3% 上下文工程的目标是砍掉剩下 97% 里的冗余
先砍工具集 投入产出比最高,一笔钱每轮都省
Compaction 保决策,笔记跨 session,Sub-Agent 做隔离 三者解决不同层次,生产环境要叠加
度量再优化 四个指标常态化,别凭感觉

回到全局:第 25 章 Harness Engineering 给了你 Agent 的五大支柱,第 26 章 Skills 解决"装什么知识",本章解决"这些知识怎么在有限注意力里真正生效"。

三者叠加的完整形态,就是 2026 年一个生产级 Agent 的样子。


📖 第 27 章 · 最后校验:2026-10-06 发现过时或有误?开 Issue 告诉我。