第 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 课:上下文的解剖:系统提示、工具与示例