Agent Mentor Learn
上下文工程:把有限的注意力花在刀刃上 · 第 1 / 6 节

第 1 课:从 Prompt 工程到上下文工程

学习目标:

  • 能复述 Prompt 工程与上下文工程的定义,并说明两者为什么是「演进」而不是「取代」的关系
  • 能用「注意力预算」与「上下文腐化」两个概念,向同事解释「窗口够大就全塞进去」错在哪里
  • 能在本系列第 7 门课写的 harness 循环里,指出上下文在哪些位置只增不减 前置要求:完成本系列第 7 门课《Agent Harness 基础:循环与控制》,手边有一个能跑的 stop_reason 驱动循环 | 下一课 第 2 课 >>

先看一个你熟悉的现场:循环每转一圈,窗口都在变重

在本系列第 7 门课里,你亲手写过这样一个循环(简化示意,最大轮次、预算等四道控制阀这里先省略):

当时我们的注意力全在控制流上:stop_reason 怎么判、控制阀怎么装。现在换个角度,盯着 messages 这个数组看——它只有 push,没有任何删减。每转一圈,至少进来两样东西:模型这一轮的回复(含 tool_use 块),以及工具的返回结果。后者常常是大头:设想一次 list_files 带回几百行文件名,一次日志检索带回几十 KB 的原文,它们从此就一直躺在窗口里,每一轮推理都要被重新读一遍。

这不是你实现上的疏忽,而是 Agent 的天性:循环中的 Agent 会源源不断地产生「下一轮推理也许用得上」的数据1,而且它握着自主权,可能连续跑非常多轮2。你在本系列第 3 门课《Prompt 工程基础》里学过怎么把一条指令写清楚——但指令写得再好,也只是窗口里的一小块。真正决定第 40 轮表现的,是此刻整个窗口里都躺着什么。

两个定义:从「写好一句话」到「管好整个窗口」

把上面那个观察正式化,就得到两个定义。

Prompt 工程:为获得最优结果而书写与组织 LLM 指令的方法1。它回答的问题是:「这段指令怎么写、怎么排布,效果最好?」

上下文工程:在 LLM 推理时,为窗口挑选并维护最优 token(信息)集合的一整套策略1。它回答的问题是:「这一轮推理,窗口里应该有哪些 token、不该有哪些?」

注意视角的抬升:前者是一次性的写作问题,写完就定型;后者是循环里每一轮都要重新回答的取舍问题。Anthropic 明确把上下文工程视为 Prompt 工程的自然演进1——你在本系列第 3 门课练出的功夫一点没有作废,它变成了更大问题的一个子集:系统提示仍然要写好,但它只是你要管理的众多上下文成分之一。

社区里有更激进的说法。一份 2026 年的 Agent 工程路线图断言:「Prompt engineering is dead as a standalone skill in 2026」(Prompt 工程作为独立技能已经死了)3。注意,这是那份路线图的观点性判断,本课不把它当作共识——Anthropic 的表述审慎得多:是演进,不是取代1。不过这份路线图给上下文工程下的一句话定义倒是值得记住:「deciding what tokens are in front of the model at every step of the loop」——在循环的每一步,决定摆在模型面前的是哪些 token3。同一份路线图还点破了 harness 的分量:「Same model, different harness, completely different result」(同一个模型,不同的 harness,结果截然不同)3——这句你在本系列第 7 门课的实验里应该已经有体感了。

注意力预算:每个新 token 都在扣费

为什么非管不可?窗口不是越大越随便用吗?这就要说到第一个物理事实。

LLM 在解析大量上下文时,动用的是一笔「注意力预算」(attention budget)1。关键在于这笔预算是有限的:每引入一个新 token,都会把它扣掉一点1

打个比方:窗口容量是仓库的面积,注意力预算是你派去仓库找货的人手。仓库扩建十倍,人手并没有跟着变多——货堆得越满,翻出你真正要的那件就越费劲。往窗口里多塞一份「以防万一」的资料,不是免费的备份,而是从预算里实打实扣掉一笔,去支付「读它、排除它」的成本。

这个视角一换,很多习惯就要重新审视。「反正窗口放得下,把整个 API 文档贴进去吧」——放得下是仓库的事,读得好是预算的事,两者不是一回事。

上下文腐化:一道缓坡,不是悬崖

预算被持续消耗的宏观后果,有个形象的名字:上下文腐化(context rot)——随着窗口里 token 数量增加,模型从这段上下文中准确召回信息的能力会下降1

两个容易讲错的细节,这里先钉死:

第一,它是渐变,不是断崖。 这种退化表现为一道性能坡(performance gradient),而不是「过了某个 token 数就突然失灵」的硬悬崖1。所以你不会收到任何报错——Agent 只是慢慢变钝。落到日常观感上(这是工程经验里的典型样子,不是来源的原文枚举):早先确认过的约定开始被遗忘,查过的文件又查一遍,改过的 bug 又被改回去。没有报警的退化,比报错更难排查。

第二,它是普遍规律,不是个别模型的毛病。 有的模型退化得平缓些,有的陡些,但这个特征在所有模型上都会出现1。换更强的模型可以推迟问题,不能取消问题。

把这两条合起来,就是本课的第一块基石:上下文必须被当作一种边际收益递减的有限资源来对待1。塞进窗口的第一千个 token 和第十万个 token,占的位置一样大,贡献的价值却差得远。「塞得越多越保险」这个直觉恰好把方向搞反了——每多塞一份「保险」,都在稀释模型对真正要紧信息的注意力。

落回 Agent:为什么这是地基,不是锦上添花

单轮问答里,上下文腐化你未必感知得到——窗口一次性用完就扔,token 量通常也到不了危险区。Agent 把这个问题从「偶尔遇到」变成「每一轮都在加剧」:循环里的数据只增不减1,Agent 又可能自主跑很多轮2。回头看开头那段代码,messages 那个只进不出的数组,就是这个过程的具象化。

工程一线的经验与此完全一致。Claude Code 的官方文档写道:上下文窗口填满得很快,而且越满性能越差4;它把上下文窗口直接称作「最重要的待管理资源」(the most important resource to manage)4。同一份文档里还有一句值得抄下来的观察:一个干净会话配一条更好的 prompt,几乎总是胜过一个积累了一堆来回修正的长会话4——「聊得久」不等于「聊得好」,积累下来的每一次纠错、每一段跑偏,都还在窗口里参与着下一轮推理。

所以给上下文工程一个准确的定位:它不是调优阶段的锦上添花,而是 Agent 可靠性的地基。本系列第 7 门课的四道控制阀管的是「循环别失控」;这门课要装的是另一套东西——「窗口别腐化」。两套机制合在一起,你的 harness 才算真正能托付长任务。

这门课的路线图

面对长时程任务,Anthropic 总结了三类手段——压缩(compaction)、结构化笔记(structured note-taking)与多 Agent 架构,目标是让 Agent 在长长的动作序列中保持连贯、保持上下文、保持目标导向1。这门课就沿着这条线展开:

  • 第 2 课先解剖窗口:系统提示、工具定义、示例各自占多少地、怎么写才不浪费。
  • 第 3 课讲即时检索:与其把资料全塞进去,不如让 Agent 拿着轻量标识符按需自己去查。
  • 第 4 课讲压缩与笔记:窗口逼近上限时怎么摘要重启,关键信息怎么记到窗口之外。
  • 第 5 课讲子代理与上下文隔离:把翻箱倒柜的脏活派给带干净窗口的子代理,只收回蒸馏后的结论。
  • 第 6 课回到你自己的 harness,把这些机制逐一装上去。

最后提醒一句分寸。这些机制每一个都是复杂度,而 Anthropic 的工程指南建议:只有当增加复杂度确实能改善结果时,才考虑引入2。所以后面每一课在讲「怎么做」之前,都会先讲清「什么时候值得做」——不是所有 Agent 都需要子代理,也不是所有任务都值得上压缩。

小结

  • 上下文工程是 Prompt 工程的自然演进:前者管「推理时窗口里维护哪组最优 token」,后者管「指令怎么书写与组织」,视角从一句话抬升到整个窗口1
  • 「Prompt 工程作为独立技能已死」是某份社区路线图的观点性断言3;本课采用更审慎的表述——演进,而非取代1
  • LLM 解析上下文靠一笔有限的注意力预算,每个新 token 都会消耗一点1——「窗口放得下」和「模型用得好」是两回事。
  • 上下文腐化是渐变的性能坡而非断崖,各模型陡缓不同但趋势普遍存在1,所以它不报错,只让 Agent 悄悄变钝。
  • 上下文是边际收益递减的有限资源1;Agent 循环里数据只增不减1,Claude Code 官方文档因此把上下文窗口称作「最重要的待管理资源」4
  • 应对长时程任务的三类手段——压缩、结构化笔记、多 Agent 架构1——分别对应第 4、第 5 课的主线,第 6 课把它们装进你的 harness;引入任何一种复杂度之前,都先确认它确实能改善结果2

>> 第 2 课:上下文的解剖:系统提示、工具与示例

Footnotes

  1. Effective context engineering for AI agents — Anthropic Engineering — https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

  2. Building Effective AI Agents — Anthropic Engineering — https://www.anthropic.com/engineering/building-effective-agents 2 3 4

  3. The 2026 Agent Engineering Roadmap — GitHub (codejunkie99/agent-roadmap-2026) — https://github.com/codejunkie99/agent-roadmap-2026 2 3 4

  4. Best practices for Claude Code — Claude Code Docs — https://code.claude.com/docs/en/best-practices 2 3 4

练习

01

下面六条做法,哪些主要属于 Prompt 工程(关心「指令本身怎么书写与组织」),哪些主要属于上下文工程(关心「每一轮推理时窗口里维护哪些 token」)?逐条归类,并为每条写一句归类理由。

Level 1:把六条做法归进两个抽屉
  1. 把系统提示里的「你是一个助手」改写成一段具体的职责与边界描述
  2. harness 每转一圈,就把三轮之前的工具返回结果替换成一行摘要
  3. 给任务指令补充一个「输入长什么样、输出长什么样」的示例
  4. 面对一份 500 页的产品文档,只把目录和文件路径给模型,需要时让它自己去查
  5. 把指令里的「尽量简洁」改成「回复不超过三句话」
  6. 会话跑到第 40 轮时,把全部历史压缩成一段摘要,用它重开一个新窗口
完成标准 · 本地勾选
02

不调用真实模型,写一段可独立运行的脚本,模拟本系列第 7 门课那个循环跑 20 轮:每轮向 messages 追加一条模拟的 assistant 消息(假定 200 字符)和一条模拟的工具结果(假定 3000 字符),逐轮打印累计字符数。然后加一个开关:只保留最近 5 轮的工具结果(更早的移出列表),重跑一遍。回答两个问题:两种模式下累计量各呈什么走势?差异说明了什么?

Level 2:给循环装一个最小观测仪
完成标准 · 本地勾选