上下文工程:给模型的信息也要做取舍
文章把系统指令、检索文档、工具结果、对话历史和跨会话记忆视为统一的上下文预算。实践重点是按相关性检索、裁剪工具输出与历史记录,避免大窗口被无关信息占满。
AI 深度解读
上下文窗口扩展到数十万 token 后,AI 应用的难题开始从「提示词怎么写」转向「到底让模型看到什么」。原文的核心判断是:系统指令、检索文档、工具结果、对话历史和跨会话记忆,需要放在同一份预算里设计,不能有多少就塞多少。
这对正在做 RAG 或 Agent 的程序员很实用:回答变差,未必需要换更大的模型,也可能只是上下文越堆越乱。不过,原文给出了明确的工程方向,没有提供足以验证效果的实验数据。
窗口更大,为什么回答还可能变差
长上下文让「先放进去,万一有用」变得容易。整篇文档、每次搜索的完整结果、此前所有对话,都可以顺手留下。
问题在于,能装下和能用好是两回事。
原文指出,无关信息会分散模型对任务的关注;即使正确答案已经出现在窗口中,准确率也可能下降。模型也不会给每段文字相同的权重,信息的位置和相关性都会影响使用效果。
答案在上下文里,不等于模型就能稳定地用对它。
这也是上下文工程(Context Engineering)与单条提示词优化的区别。后者关注某句话怎样表达,前者关注一次调用中模型接触的全部材料:哪些必须出现,哪些只在当前问题下有用,哪些已经应该删除。
原文声称无关上下文会造成可测量的准确率损失,但没有给出模型名称、测试集、下降幅度或实验方法。因此,可以把它作为排查方向,不能直接当作所有模型和任务上的量化结论。
五类上下文,应该分别怎么管
原文把上下文预算分成五类。它们服务的目的不同,整理方式也应该不同。
| 类型 | 放什么 | 原文强调的取舍 |
|---|---|---|
| System prompt | 角色、约束、输出格式 | 设置后在每次调用中复用 |
| 检索文档 | 为当前问题召回的 RAG 片段 | 相关性优先于数量 |
| 工具结果 | 函数调用或搜索实际返回的内容 | 往往是窗口中最嘈杂的部分 |
| 对话历史 | 此前的交互轮次 | 长 Agent 循环里要积极裁剪 |
| 记忆 | 跨会话保留的事实 | 经过筛选,不能保存所有交互 |
检索增强生成(RAG)的关键,不是把知识库搬进窗口,而是找到当前问题需要的材料。原文点出的典型错误,就是明明只需要相关片段,却粘贴完整文档。
工具结果则容易在循环中失控。Agent 每执行一次搜索或函数调用,就多出一批返回内容;如果一直追加,旧结果会逐渐挤占当前任务的空间。这里需要管理的不只是单次返回长度,还有多轮执行后累积下来的内容。
对话历史和记忆也不能混为一谈。历史记录保存发生过的交互,记忆则保存值得跨会话延续的事实。把全部聊天记录都当作记忆,只是把整理工作推迟到了下一次调用。
原文没有规定五类内容各占多少 token,也没有给出具体的裁剪算法。它强调的是先建立筛选机制,再讨论是否需要更大的容量。
我的判断
我认同这篇文章把注意力从「万能提示词」移向输入材料的组织。对已经接入检索和工具的应用来说,模型收到的内容远不止开发者写下的那段指令;只修改 System prompt,很可能碰不到真正的问题。
但「积极裁剪」有前提:你得知道哪些信息仍然影响任务。旧对话里可能留着用户约束,早期工具结果也可能是后续判断的依据。删掉它们,同样会伤害准确率。
上下文整理的目标是保留有效证据,不能只追求更短。
至于「准确率下降时通常应该整理上下文,而非换更大的模型」,我会把它看作经验建议。原文没有提供两种方案的对照数据,也没有说明成本和任务难度。它足以支持先检查输入质量,还不足以证明升级模型总是次要选项。
能拿来做什么
- 给现有 RAG 应用检查一次实际输入:当前问题只需要某个段落时,确认检索链路是否仍然把整篇文档传给模型。
- 在 Node 编写的 Agent 循环里,检查工具结果和对话历史是否只增不减,并明确哪些内容完成当前步骤后可以移出上下文。
- 排查 AI 编程助手的回答退化时,先查看模型实际收到的任务、旧对话和工具输出,判断当前约束是否被大量无关内容淹没。
- 为跨会话记忆明确保存标准,只保留需要延续的事实;比较整理前后的效果时,用同一批任务验证,不凭某一次回答判断成败。