提示词之后:上下文工程如何接管 LLM 应用质量

从系统提示词、用户提示词、会话上下文、检索上下文、Token 窗口、幻觉抑制和提示词模板库出发,结合 arXiv 论文解释为什么 LLM 应用的核心工程对象正在从 prompt 变成 context。

提示词之后:上下文工程如何接管 LLM 应用质量

那张图里的关键词很像一条学习目录:

提示词工程
系统提示词
用户提示词
上下文工程
会话上下文
检索上下文
Token 窗口
模型幻觉抑制
提示词模板库

如果把它当成一组零散概念,很容易学成技巧清单:系统提示词要强一点,用户提示词要清楚一点,RAG 要加引用,长上下文要省 token,幻觉就让模型“不要编”。

但这些词真正连起来以后,指向的是一个更底层的变化:

LLM 应用的核心工程对象,正在从 prompt 变成 context。

提示词工程解决的是“这一段话怎么写”。上下文工程解决的是“模型这一次调用前,应该看到什么、按什么优先级看到、哪些信息必须信、哪些信息只能参考、哪些信息要被压缩、哪些信息要被检索、哪些信息应该被丢弃,以及输出后如何验证”。

换句话说,prompt 是界面;context 是运行时。

我用 Scrapling 抓了 arXiv 搜索页和摘要页,重点看了 prompt engineering、context engineering、RAG、long context、hallucination、prompt template repository 几条论文线。一个很清晰的结论是:今天的“提示词工程”已经装不下这些问题了。更准确的框架应该是“上下文工程”。

1. Prompt 不是输入,context 才是输入

很多人说“给模型一个 prompt”。这句话在聊天产品里能成立,但在真实应用里太粗。

一次 LLM 调用的输入通常不是一段话,而是一整包上下文:

flowchart TD
  A[系统提示词] --> H[上下文包]
  B[用户提示词] --> H
  C[会话历史] --> H
  D[检索材料] --> H
  E[工具返回] --> H
  F[模板与示例] --> H
  G[输出约束与评分标准] --> H
  H --> I[Token 预算与排序]
  I --> J[模型调用]
  J --> K[验证与幻觉抑制]

系统提示词、用户提示词、历史消息、检索片段、工具结果、模板、示例、输出格式、评分标准都会进入同一个 Token 窗口。模型并不会天然知道哪一段更可信,哪一段更新,哪一段只是旧对话里的临时假设。

所以,上下文工程的第一条原则是:

不要把“写 prompt”当成全部输入设计。
真正要设计的是一次模型调用的完整上下文包。

这也是 The Prompt Report 和更早的 Pre-train, Prompt, and Predict 给我们的启发。前者整理了大量 prompting 技术和术语,后者把 prompt-based learning 放进“模板、语言模型、预测目标”的统一框架里。它们都说明 prompt 不是玄学咒语,而是一种把任务转换成模型可处理文本分布的接口。

但接口不是系统。接口之外,还需要上下文的装配、裁剪、排序、授权、引用和验证。

2. 系统提示词:不是人设,而是权限层

系统提示词经常被写成这样:

你是一个资深专家,请认真回答。

这类写法不是完全没用,但太弱。系统提示词最重要的作用不是“设定人设”,而是定义应用层的权限和边界:

你服务的目标是什么?
你必须遵守哪些不可变规则?
你可以调用哪些工具?
你不能泄露什么?
当用户请求和系统规则冲突时,谁优先?
当检索材料和用户指令冲突时,谁优先?
当上下文里出现恶意指令时,怎么处理?

The Instruction Hierarchy 直接切中了这个问题:很多 prompt injection 和 jailbreak 的根因,是模型把系统提示、用户输入、第三方文本放在了过于相近的优先级里。论文提出用明确的指令层级训练模型,让它在冲突时优先服从高权限指令,并忽略低权限的恶意覆盖。

这对应用设计的启发很具体:

系统提示词不应该写成“更大声的用户提示词”。
它应该写成上下文包里的最高权限协议。

一个更工程化的系统提示词至少应该包含四类内容:

作用例子
任务边界定义这个应用负责什么只回答某个产品、某个仓库、某类流程的问题
权限规则定义冲突时谁优先系统规则 > 开发者规则 > 用户请求 > 检索文本
工具契约定义工具怎么用何时检索、何时查数据库、何时拒绝
输出标准定义可验收结果必须引用来源、必须标注不确定性、不能编造 ID

系统提示词越接近“协议”,越能承载工程责任。越接近“角色扮演”,越容易在复杂上下文里失效。

3. 用户提示词:不是命令,而是任务实例

用户提示词在权限上低于系统提示词,但它是任务的触发点。

一个好用户提示词不是越长越好,而是应该把这几个要素说清楚:

目标:要完成什么?
材料:基于哪些输入?
约束:不能做什么,必须满足什么?
输出:希望得到什么形态?
成功标准:怎样算完成?

比如“帮我写一篇 RAG 博客”是弱提示。它缺少读者、范围、材料来源、深度、证据标准和输出位置。

更好的任务提示是:

面向已经用过 ChatGPT、但没系统理解 LLM 应用架构的开发者,
写一篇解释 prompt engineering 到 context engineering 转变的中文博客。
必须覆盖系统提示词、用户提示词、会话上下文、检索上下文、Token 窗口、幻觉抑制、提示词模板库。
用 arXiv 论文做证据,不写成论文列表,而是讲清楚它们之间的工程关系。

这不是“话术更漂亮”,而是把任务实例补全了。

Chain-of-Thought Prompting 的价值也可以从这个角度理解。CoT 不只是让模型“多想几步”,而是在 prompt 里加入中间推理轨迹这个任务结构,让模型在复杂推理中不只看到问题和答案,还看到从问题到答案的路径样例。

提示词工程的上限,往往来自你能不能把任务结构显式化。

4. 上下文工程:把输入从一句话变成一个系统

“上下文工程”这个词在 2026 年的 arXiv 上已经明显升温。截至 2026-07-16,直接搜索 "context engineering" 能看到一批非常新的论文。

其中 Context Engineering: A Practitioner Methodology for Structured Human-AI Collaboration 把上下文工程定义成组装、声明和排序完整信息负载的方法,并提出 Authority、Exemplar、Constraint、Rubric、Metadata 五类上下文角色。它的实验是观察性、单操作者数据,不能当成强因果证明,但方向很有参考价值:质量问题经常不是 prompt 不够妙,而是上下文不完整、顺序不清、验收标准没进输入。

Less Context, Better Agents 则从长程工具型 agent 的角度说明:完整保留历史不一定最好。论文报告的企业费用场景里,保留最近工具交互并加入摘要,反而比全量历史更可靠、更省 token。这正好反驳了一个常见误区:

上下文工程不是“尽量多塞”。
上下文工程是“让当前任务看到足够且正确的信息”。

Context by Distinct Information 更进一步,把问题从 token 数量转到“distinct information”。它的核心启发是:如果上下文流里有大量重复信息,按 token 计费和保留并不是最合理的记忆单位;真正该保留的是任务还没吸收过的差异信息。

所以我会这样定义上下文工程:

上下文工程 = 为每次模型调用选择、组织、压缩、排序、授权、引用和验证信息的工程 discipline。

它至少包括六个动作:

动作问题典型实现
选择哪些信息该进来?检索、规则过滤、工具路由
排序信息放在哪里?高权限在前,关键证据靠近任务
压缩历史太长怎么办?摘要、结构化状态、记忆槽
隔离哪些内容不能互相污染?引用块、权限标签、沙箱工具输出
更新新事实如何覆盖旧事实?会话状态、版本号、时间戳
验证输出是否被证据支持?引用检查、反问验证、自检、多采样

这已经不是“prompt 怎么写”的问题,而是 LLM 应用架构问题。

5. 会话上下文:聊天记录不是记忆

会话上下文看起来最简单:把历史对话带上不就行了?

问题就在这里。

聊天记录只是发生过的文本,不等于干净的工作记忆。里面可能有:

已经作废的需求
用户随口说的假设
模型自己犯过的错
工具返回的过期结果
中途尝试过但失败的方案
临时格式要求
和当前问题无关的闲聊

如果全量塞回 Token 窗口,模型会获得更多文字,但不一定获得更好的状态。它可能被旧假设牵走,被失败路径污染,或者把之前的错误当成事实。

MemGPT 的价值就在于它不把上下文窗口当成无限记忆,而是借鉴操作系统里的分层内存,把有限窗口、长期记忆、外部存储和控制流组织起来。它把“记住更多”变成“什么时候把什么搬进工作区”的问题。

会话上下文应该从聊天记录升级成结构化状态:

用户长期偏好
当前任务目标
已确认事实
未解决问题
已经否定的方案
最近工具结果
下一步计划

这样模型看到的不是一堆历史,而是当前任务的状态快照。

一个实用原则:

历史消息用于追溯,结构化状态用于决策。
不要让模型在一大段聊天记录里自己考古。

6. 检索上下文:RAG 不是外挂资料,而是非参数记忆

检索上下文通常被叫作 RAG。它的本质不是“把搜索结果贴进 prompt”,而是给模型接一块可更新、可追溯、可替换的外部记忆。

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks 是 RAG 这条线的关键论文。它把参数记忆和非参数记忆结合起来:模型参数里有通用语言能力,外部索引里有可检索知识。这样既能补知识,也能提供 provenance,还能更新知识来源。

后来的 Retrieval-Augmented Generation for Large Language Models: A Survey 把 RAG 的演进拆成 Naive RAG、Advanced RAG、Modular RAG,并强调检索、生成、增强、评估各环节。它很适合用来提醒我们:RAG 不是一个步骤,而是一条链路。

一个最小 RAG 链路是:

flowchart LR
  Q[用户问题] --> R[检索查询改写]
  R --> S[召回候选文档]
  S --> T[重排与过滤]
  T --> U[上下文拼装]
  U --> V[生成答案]
  V --> W[引用与事实检查]

真正难的是中间三步:召回什么、过滤什么、怎么拼。

检索上下文有三个常见坑:

表现解决方向
召回错答案基于无关片段查询改写、hybrid search、rerank
拼接乱片段互相矛盾,模型乱选去重、按时间/权威排序、显式来源
信任错把检索文本里的恶意指令当命令权限隔离、引用块、instruction hierarchy

RAG 可以降低幻觉,但 RAG 自己也会引入错误上下文。检索错了,模型会更自信地错。

所以检索上下文的核心不是“加资料”,而是“把外部资料变成可审计证据”。

7. Token 窗口:容量、成本和注意力可靠性是三件事

Token 窗口经常被误解成一个简单指标:

窗口越长,模型越能理解长材料。

长窗口当然有价值,但它至少拆成三件事:

容量:能塞多少 token。
成本:塞进去要花多少推理时间和钱。
可靠性:模型是否真的用对了中间的信息。

Lost in the Middle 是理解 Token 窗口必读的论文。它发现模型处理长上下文时,对信息位置很敏感:关键信息放在开头或结尾往往更容易被用到,放在中间可能显著掉性能。也就是说,“放进窗口”不等于“被稳定使用”。

这对上下文拼装有直接影响:

高优先级规则不要埋在中间。
当前问题和关键证据要靠近。
长文档不要只靠原文堆叠。
冲突信息要显式标注来源和时间。

到了 agent 和推理服务层,Token 窗口还会影响 KV cache 和延迟。SmoothAgent 研究的是长程 agent 中的上下文转换:offload、reduction、isolation 等上下文工程动作可能导致 KV cache 失效和重新 prefill。它提出 lookahead context engineering,提前准备上下文转换,减少 TTFT。

这说明 Token 窗口不是前端参数,而是系统性能的一部分。

一个成熟的上下文预算策略,应该同时考虑:

哪些信息必须原文保留?
哪些信息可以摘要?
哪些信息应该检索而不是常驻?
哪些信息只保留最近 N 步?
哪些信息必须靠近输出指令?
哪些信息需要从上下文中隔离?

“窗口够大”只是起点。“窗口里有正确的信息结构”才是能力。

8. 模型幻觉抑制:不要把可靠性寄托在一句提醒上

最常见的幻觉抑制 prompt 是:

如果不知道就说不知道,不要编造。

这句话可以保留,但不能指望它解决问题。

A Survey on Hallucination in Large Language Models 把幻觉问题拆成成因、检测、基准和缓解方法。它提醒我们,幻觉不是一个单一 bug,而是模型知识边界、训练目标、解码策略、检索质量、任务开放性共同作用的结果。

从上下文工程角度看,幻觉抑制至少有五层:

做什么对应机制
输入约束限定回答范围系统提示词、领域边界
证据供给给可引用材料RAG、工具查询、数据库
输出绑定让结论绑定证据引用、逐条依据、结构化字段
生成后验证检查是否自洽或有证据SelfCheck、CoVe、二次检索
失败路径不确定时退出abstain、追问、标注未知

SelfCheckGPT 提供了一个黑盒检测思路:如果模型对同一事实多次采样后说法互相矛盾,那么这些句子更可能不可靠。它不需要外部数据库,但更适合检测不一致,不等于证明为真。

Chain-of-Verification 则把验证变成一个生成流程:先草拟答案,再生成验证问题,再独立回答验证问题,最后给出修正答案。它的启发是:

不要让模型一边生成结论,一边顺手相信自己的结论。
把回答和验证拆成两个上下文阶段。

如果有外部知识库,优先用检索证据验证;如果没有外部知识库,至少用多采样、自检问题、输出约束降低风险。

幻觉抑制不是一句 prompt,而是一条可靠性流水线。

9. 提示词模板库:模板不是收藏夹,而是可测试资产

很多团队会沉淀一个提示词模板库,里面放:

总结模板
翻译模板
代码审查模板
客服回复模板
RAG 问答模板
报告生成模板

这一步很必要,但容易做成“prompt 收藏夹”。收藏夹只能复用文本,不能保证质量。

PromptSource 是更早、更工程化的一种形态。它把 prompts 定义成从数据样本到自然语言输入/目标输出的函数,并提供模板语言、迭代界面和社区贡献规范。论文提到当时已经有大量数据集和模板,这说明 prompt 模板库从一开始就不只是“复制几段话”,而是围绕数据、输出和协作建立工具。

Large Language Models Are Human-Level Prompt Engineers 提出的 APE 则说明,prompt 本身可以被生成、搜索、评分和选择。也就是说,提示词模板可以进入优化循环,而不是永远靠人手调。

一个真正可用的提示词模板库,应该至少给每个模板配这些元数据:

字段用途
适用任务防止模板被滥用
输入变量明确哪些位置由外部填充
权限级别区分系统规则、用户任务、检索文本
示例给 few-shot 或验收样例
失败样例记录模板容易翻车的情况
评测集用固定样本回归测试
版本追踪模板变更
指标记录准确率、引用率、拒答率、成本

模板库的成熟形态不是:

这里有 100 条好用 prompt。

而是:

这里有一组经过版本管理和评测的上下文程序。

模板只是表层。变量、证据、约束、评分标准、回归集和发布流程,才是它变成工程资产的部分。

10. 把这些关键词合成一张工程图

现在再回头看那组关键词,它们不是并列关系,而是一个分层系统:

关键词在系统里的位置主要问题
提示词工程单次任务表达层怎么把任务说清楚
系统提示词权限与协议层哪些规则不可被覆盖
用户提示词任务实例层用户这次到底要什么
上下文工程输入运行时层本次调用该看到什么
会话上下文状态记忆层历史如何变成当前状态
检索上下文外部证据层知识从哪里来,能否追溯
Token 窗口资源与注意力层容量、成本、位置效应怎么权衡
模型幻觉抑制可靠性层输出如何被证据和验证约束
提示词模板库复用资产层如何版本化、评测和迭代

更简洁地说:

系统提示词管权限。
用户提示词管任务。
会话上下文管状态。
检索上下文管证据。
Token 窗口管资源。
幻觉抑制管可靠性。
模板库管复用。
上下文工程把它们装配成一次可控的模型调用。

这就是从 prompt engineering 到 context engineering 的核心跃迁。

11. 一个可落地的上下文工程检查表

如果要在项目里真正落地,我会用这张检查表:

1. 权限
   系统规则、用户输入、检索文本、工具输出是否有明确优先级?

2. 状态
   当前任务状态是否结构化,而不是只靠聊天历史?

3. 证据
   关键事实是否来自可引用来源?

4. 预算
   Token 窗口里哪些信息原文保留,哪些摘要,哪些检索?

5. 排序
   高优先级规则和关键证据是否没有被埋在上下文中间?

6. 隔离
   第三方文本里的指令是否被当成数据,而不是命令?

7. 验证
   输出是否经过引用检查、自检、二次检索或规则校验?

8. 回归
   常用模板有没有固定测试集和版本记录?

如果一个 LLM 应用经常出现“同一个 prompt 今天好用明天不好用”,问题可能不是 prompt 还不够优雅,而是上下文没有被工程化。

12. 总结

提示词工程没有过时。它仍然是 LLM 应用的入口技能。

但只会提示词工程,会很快遇到天花板:

任务一复杂,系统提示词和用户提示词会冲突。
对话一长,会话历史会污染当前状态。
资料一多,检索上下文会带来噪声和注入风险。
窗口一大,模型不一定能稳定使用中间信息。
答案一开放,幻觉不能靠一句“不要编”解决。
模板一复用,没有评测就不知道改坏了什么。

上下文工程不是否定 prompt,而是把 prompt 放回它应该在的位置:

prompt 是上下文包的一部分。
context 才是 LLM 应用的运行时。

当你开始设计系统提示词的权限、用户提示词的任务结构、会话状态的压缩、检索证据的排序、Token 窗口的预算、输出后的验证和模板库的回归测试时,你就已经不只是在“写提示词”了。

你在搭一个能让模型稳定工作的上下文系统。

参考论文