按场景看提示词工程与上下文工程:一个优化问题的两端

提示词工程和上下文工程不是两门手艺,而是同一个优化问题在不同场景下的解。用 Mei et al. 2025 综述的形式化定义 C = A(c_instr, c_know, c_tools, c_mem, c_state, c_query) 做骨架,沿"单轮闭卷 → 开卷问答 → 长对话 → 动手 agent → 多智能体"五级场景阶梯,讲清每登一级、上下文里多了哪个成分、工程问题怎么变形——以及为什么提示词工程没有死,只是降级成了子模块。

2025 年 7 月,一篇覆盖 1400+ 论文的综述(Mei et al., arXiv:2507.13334)给”上下文工程”下了第一个正式定义。有意思的是,它没有把上下文工程定义成一堆新技巧,而是定义成一个优化问题的换元:提示词工程优化的变量是一段字符串,上下文工程优化的变量是一个组装函数。变量不同,但目标函数是同一个。

网上关于”提示词工程 vs 上下文工程”的讨论,大多在争论哪个词更时髦、哪个要过时了。这篇想换个问法:如果按场景划分,什么时候你面对的是提示词问题,什么时候是上下文问题? 答案会比”新词取代旧词”有用得多。

如果你只带走一句话,就带走这个:

判断一个场景该做哪种工程,只问一个问题:模型这次回答所需要的信息,是你写作时就能全部写死的,还是运行时才知道的?写死的部分,是提示词工程;运行时才组装的部分,是上下文工程。场景越长、状态越多、来源越杂,天平就越向后者倾斜。

下面先给理论骨架(一个公式),再沿场景阶梯爬五级,最后回答两个必然会有的反问。

骨架:一个公式看清两者的关系

综述的核心动作是把”上下文”从一段扁平的文本,重新定义为一组动态组装的成分

C=A(cinstr,  cknow,  ctools,  cmem,  cstate,  cquery)C = \mathcal{A}(c_{\text{instr}},\; c_{\text{know}},\; c_{\text{tools}},\; c_{\text{mem}},\; c_{\text{state}},\; c_{\text{query}})

六个成分各管一摊:

成分是什么来自哪里
cinstrc_{\text{instr}}系统指令与规则开发者写死
cknowc_{\text{know}}外部知识检索(RAG、知识图谱)运行时取
ctoolsc_{\text{tools}}可用工具的定义与签名开发者定义,运行时选
cmemc_{\text{mem}}跨轮次/跨会话的持久信息记忆系统运行时读写
cstatec_{\text{state}}用户、世界或多智能体系统的当前状态环境运行时产生
cqueryc_{\text{query}}用户这一次的请求用户

A\mathcal{A} 是组装函数——决定取哪些、怎么过滤、怎么排布。于是两种工程的差别可以一句话说清:

  • 提示词工程CC 就是一段静态字符串,你手动(或自动)在字符串空间里搜一个好的;信息内容在写下时就固定了,基本无状态。
  • 上下文工程:你优化的不是任何一段具体文本,而是那组函数 F={A,Retrieve,Select,}\mathcal{F} = \{\mathcal{A}, \text{Retrieve}, \text{Select}, \dots\},目标是它们在整个任务分布上期望效果最好,且受一条硬约束——CLmax|C| \le L_{\max},装不下就是装不下。

注意这个定义里藏着本文的全部结构:六个成分不是同时存在的。 最简单的场景里只有 cinstr+cqueryc_{\text{instr}} + c_{\text{query}},随着场景变复杂,成分一个个被点亮,每点亮一个,就多出一个工程子问题。所谓”场景划分”,就是看你的场景点亮了哪几个。

graph LR
    A["场景一<br/>单轮闭卷<br/>instr + query"] --> B["场景二<br/>开卷问答<br/>+ know"]
    B --> C["场景三<br/>长对话/跨会话<br/>+ mem"]
    C --> D["场景四<br/>动手的 agent<br/>+ tools + state"]
    D --> E["场景五<br/>一个窗口装不下<br/>拆成多个 C"]

下面逐级爬。每一级都回答三件事:新点亮了什么成分、核心工程问题变成了什么、代表论文是谁。

场景一:单轮闭卷——提示词工程的主场

成分:cinstr+cqueryc_{\text{instr}} + c_{\text{query}}(可能加几个例子)。 翻译、摘要、改写、分类、一次性的代码片段——模型需要的知识全在参数里,你要做的只是把任务”说清楚”。

这是提示词工程的主场,而且它在这里的战绩是实打实的,有三篇里程碑:

  1. GPT-3(Brown et al., 2020) 发现了 in-context learning:不更新任何权重,只在 prompt 里放几个示例,模型就能”临时学会”任务。这是”prompt 里放什么会改变模型行为”这件事的原点(为什么不改权重也能学?我之前写过一篇从贝叶斯视角的解释)。
  2. 思维链Wei et al., 2022 在示例里写上推理步骤,Kojima et al., 2022 更狠——只加一句 “Let’s think step by step”,数学题正确率就大幅跳升。同一个模型、同一个问题,几个词的差异换来质变,这是”措辞有杠杆”最干净的证据。
  3. The Prompt Report(Schulhoff et al., 2024) 则给这门手艺画上了地图的句号:32 位研究者用系统综述方法梳理 1500+ 篇论文,整理出 58 种纯文本提示技巧的分类学。

第三篇值得多看一眼,因为它同时暴露了提示词工程的天花板。58 种技巧听起来繁荣,但它们全部在优化同一个东西——那段字符串怎么写。综述里对提示词工程的判词是”Brittleness increases with length and complexity”(脆弱性随长度和复杂度增长):字符串越长、任务越复杂,改一处措辞牵动全局,你没有模块边界可以隔离问题,出了错只能”人眼盯着改”。

在场景一里这个天花板碰不到,因为信息量小、任务一次性。提示词工程不是被证伪了,而是它的主场就这么大。

场景二:开卷问答——cknowc_{\text{know}} 点亮,问题从”怎么说”变成”取什么、放哪里”

新增成分:cknowc_{\text{know}} 一旦答案不在模型参数里——公司内部文档、昨天的新闻、私有代码库——再精妙的措辞也无济于事。RAG(Lewis et al., 2020)给出的方案是运行时检索:从外部库里取相关片段,塞进上下文再生成。

注意这一步发生了什么质变:上下文里第一次出现了”写作时不知道内容”的部分。 你没法为一段”不知道会检索回什么”的文本做措辞优化——你能优化的只剩下函数:怎么切块、怎么检索、取几条、怎么排序、放在什么位置。工程对象从字符串滑向了 F\mathcal{F}

“放在什么位置”甚至单独催生了一条研究线。Lost in the Middle(Liu et al., 2023)把同一份含答案的文档放在 20 篇文档的不同位置,发现所有被测模型都呈 U 形曲线:开头和结尾附近的信息用得好,放在中间的信息经常被忽略,最差时甚至不如完全不给文档的闭卷作答。也就是说,检索器明明找对了,只因为放的位置不对,效果全丢。这个现象在 2025 年 Chroma 对 18 个前沿模型的测试里依然全员存在(我在《上下文不是平的》里专门拆过它的注意力机制成因)。

这一级带走一个判据:当”上下文里放什么”开始比”指令怎么措辞”更影响效果时,你就已经跨进上下文工程了——哪怕你还没听说过这个词。RAG 系统里各组件(Embedding、Retriever、Reranker、GraphRAG……)各管什么,我在另一篇里有完整的地图,这里不重复。

场景三:长对话与跨会话——cmemc_{\text{mem}} 点亮,问题变成”记什么、忘什么”

新增成分:cmemc_{\text{mem}} 对话一长,新矛盾出现了:历史是线性增长的,窗口是有限的(CLmax|C| \le L_{\max} 那条硬约束开始咬人)。而且历史不像检索库那样”在外面等着被查”——它是这个会话自己产生的,你得决定它的去留。

这一级的代表作是 MemGPT(Packer et al., 2023),它的洞察是一个漂亮的类比:这不就是操作系统的虚拟内存问题吗? 物理内存(上下文窗口)有限,但可以用磁盘(外部存储)做换页——把窗口内当作”主上下文”,窗口外当作”外部上下文”,让模型自己通过函数调用决定什么该换出去、什么该调回来。模型第一次成为自己记忆的管理者。

注意工程问题又变形了。场景二问”取什么”,这一级还要问”忘什么”

  • 压缩(compaction):把远处的对话摘要成一段,细节丢掉,结论留下;
  • 分层:近期原文保留、中期摘要、远期落库待检索——像 CPU 缓存的层级;
  • 结构化记忆:把”用户偏好 pnpm”这类事实抽出来单独存,而不是让它淹没在第 37 轮对话里。

遗忘在这里不是缺陷而是能力——上下文里留着的每一段低价值历史,都在挤占后面真正重要信息的位置(这一点我在《遗忘是能力》里展开过)。

场景四:动手干活的 agent——ctools+cstatec_{\text{tools}} + c_{\text{state}} 点亮,上下文变成每步重排的流

新增成分:ctoolsc_{\text{tools}}cstatec_{\text{state}} 让模型修一个 bug、订一张票、跑一次数据分析——它需要工具,而工具会带回环境反馈:命令输出、文件内容、报错信息。上下文不再是”一次组装、一次生成”,而是一个循环:每一步行动都往窗口里注入新状态,下一步的决策依赖对这些状态的取舍。

这一级最好的一手材料是 Anthropic 的 Effective Context Engineering for AI Agents(2025-09),它贡献了两个概念:

  • 注意力预算(attention budget):模型和人一样工作记忆有限,每多一个 token 都在消耗这个预算;
  • Context rot:随着窗口越塞越满,模型对窗口内信息的准确回忆能力全员、可测量地下降——窗口是 200K 不代表 200K 都好用。

由此推出 agent 上下文管理的总纲领,原文一句话:“找到最小的高信号 token 集合,最大化你想要的结果的概率。” 落到手段上是三板斧——压缩(compaction)维持长对话、结构化笔记(note-taking)把关键状态写到窗口外持久化、子 agent 隔离复杂子任务——以及”即时检索”(just-in-time):别预加载一切,让 agent 用工具按需去取。

还有一件事在这一级变得显眼:ctoolsc_{\text{tools}} 的质量——工具叫什么名字、描述怎么写、返回结果长什么样——对行为的影响大到反直觉。SWE-agent(Yang et al., 2024) 的消融实验证明,一个设计糟糕的搜索接口比没有这个接口更糟。这部分属于 harness 的职责,我在《什么才是好的 Harness》里详细写过;模型为什么以及何时决定伸手用工具,见这篇

场景五:一个窗口装不下——拆成多个 CC

变化:不再是往一个 CC 里加成分,而是把任务拆到多个上下文里。 当任务大到任何压缩都救不了一个窗口时(全库审计、大规模迁移、宽领域调研),出路是多智能体:每个子 agent 拿一个干净的窗口做一个子问题,只把结论(而不是过程)汇回主 agent。

这其实是上下文工程的递归应用:主 agent 的上下文里,子 agent 的整个探索过程被压缩成了一段摘要——隔离本身就是最强的压缩。代价是新的工程问题:任务怎么切分、结论用什么格式汇报、子 agent 之间冲突怎么办。综述把多智能体的通信协议和编排(orchestration)列为上下文工程的四大系统实现之一,和 RAG、记忆系统、工具推理并列——也就是说,在这个框架里,多智能体系统本质上是一种上下文架构,而不只是一种并发模式。

场景阶梯总览

场景点亮的成分核心问题代表工作
一、单轮闭卷cinstr+cqueryc_{\text{instr}} + c_{\text{query}}怎么说GPT-3、CoT、Prompt Report
二、开卷问答+ cknow+\ c_{\text{know}}取什么、放哪里RAG、Lost in the Middle
三、长对话/跨会话+ cmem+\ c_{\text{mem}}记什么、忘什么MemGPT
四、动手的 agent+ ctools+cstate+\ c_{\text{tools}} + c_{\text{state}}每一步喂什么、丢什么Anthropic、SWE-agent
五、超出一个窗口拆成多个 CC怎么分、怎么汇多智能体系统

规律很清楚:每登一级,运行时才知道的信息占比就更高一点,“措辞”的杠杆就更短一点,“信息物流”的杠杆就更长一点。 综述的说法是:上下文工程把重心从提示词设计的”艺术”移向信息物流与系统优化的”科学”。

两个必然的反问

反问一:“上下文工程”是不是提示词工程的营销新包装?

在场景一里,是的——那里两者没有区别,不必赶时髦改名。但从场景二开始,两者在数学上就不是一个问题了:优化变量从一段字符串变成一组函数,无状态变成有状态,“人眼盯字符串改”变成”可以分模块评测调试”(检索器单独测召回、压缩器单独测信息保留)。变量不同、约束不同、调试方法不同——这不是换名字,是换问题。真正的营销噪音是反过来的:把场景一里写写措辞也叫”上下文工程”。

反问二:窗口越来越大、模型越来越强,上下文工程会不会是过渡性技术?

“装不下”这个约束确实在松动,但场景阶梯揭示的三个约束不随窗口消失:其一,注意力预算不随窗口等比扩张——Lost in the Middle 和 Context Rot 都表明,塞得进不等于用得好;其二,该进上下文的信息本身是运行时才存在的(今天的报错、这个用户的历史),窗口再大也得有人决定取什么——取舍逻辑可以从人写的代码移进模型自己的判断(就像 MemGPT 让模型自管记忆),但那是上下文工程换了实现方式,不是消失;其三,token 有真实的钱和延迟成本,“全塞进去”在经济上先输。窗口增长杀死的是因窗口太小而生的补丁,杀不死”决定模型看见什么”这个问题本身。

收尾:提示词工程去哪了

回到开头那个判据:写作时能写死的,是提示词工程;运行时才组装的,是上下文工程。现在可以把两者的最终关系说完整了——

提示词工程没有死,它降级成了上下文工程的子模块。C=A()C = \mathcal{A}(\dots) 里,cinstrc_{\text{instr}} 这一个成分的内部质量,依然靠提示词工程:系统指令怎么写、工具描述怎么措辞、压缩摘要的模板长什么样,全是措辞功夫。变化的是它的地位:从”全部的工程”变成”六分之一成分的内部优化”,而剩下的五个成分——取什么、记什么、忘什么、怎么排、怎么拆——才是今天 LLM 应用质量的主要变量。

所以下次再有人问”该学提示词工程还是上下文工程”,你可以把问题还给场景:你的应用停在阶梯的哪一级? 第一级,措辞就是全部;再往上,先把信息物流做对,再谈措辞。


论文与资料清单