![信息流拼合拼图](https://blog.kbmp.club/upload/context.jpg) 「提示词工程」这个词流行了两年,近来越来越多人改说「上下文工程」。这不是换说法,是关注点真的变了。 ## 为什么说法变了 提示词工程的隐含假设是:**有一个魔法咒语,写对了模型就变强。** 于是大家收集各种「你是一个资深 XX」的模板。 上下文工程的出发点是:**模型每次能看到的输入总量是有限的,你的活是把这个有限的空间分配给最该放进去的东西。** 前者是修辞问题,后者是资源调度问题。做应用做到一定规模,一定会碰到后者。 ## 上下文是预算,不是仓库 一次调用能塞进去的东西包括: - 系统提示词(角色、规则、输出格式) - 工具定义(可用函数及其参数 schema) - 检索回来的外部资料 - 历史对话 - 用户当前的输入 这些**共用同一个窗口上限**。塞满会截断,而截断往往发生在你最需要的位置。 更要命的是:每多一个 token,成本上升(见《大模型 API 的账怎么算》),延迟也会变长。**窗口越大不代表越该塞满——塞进去的东西如果无关,反而会干扰模型判断。** 这叫「大海捞针」问题:相关信息埋在一大堆无关内容中间,模型的注意力会被稀释,表现反而变差。 ## 四条实践 **1. 把稳定的放前面,变化的放最后** 系统提示词、工具定义这些内容要固定不变,放在最前——顺带还能命中前缀缓存省钱。用户输入、检索结果这些每次都变,放最后。 **2. 工具定义要精简** 给智能体接十个工具,每个工具的详细 schema 加起来可能吃掉几千 token。如果其中七个这次根本用不上,那就是纯浪费。 按需加载工具定义,或者分层:常用工具常驻,冷门工具在需要时再注入。 **3. 历史要压缩,不是要保留** 多轮对话越往后越臃肿。定期把早期对话压缩成一段摘要: ``` [历史摘要] 用户正在配置一台新服务器的 SSH, 已完成:创建 deploy 用户、配置密钥、禁用密码登录。 当前目标:配置 fail2ban。 ``` 信息密度高得多,占用少得多。 **4. 检索结果要裁剪** 召回 10 条文档直接全塞进去是常见做法,但其中可能只有 2 条真正相关。先做重排(见《RAG 入门》),只取前几条;每条再截断到必要长度。 ## 输出也是上下文的一部分 这一点常被忽略:**模型自己生成的东西也会占窗口。** 让模型「边想边说」地输出长篇推理,会把窗口填满,导致后面轮次可用空间骤减。 实践中可以: - 限制单次输出长度; - 要求结构化输出(JSON 而非散文); - 长任务拆成多个短调用,每个调用只处理一小块。 ## 一个判断标准 怎么知道上下文设计得好不好?看这个指标: **把窗口里的每一段拿出来问一句——如果删掉它,模型这次还能完成任务吗?** 答「能」的,就该删。做几轮这样的减法,通常能砍掉一半以上的 token,效果还更好。 ## 小结 从提示词工程到上下文工程,本质是从「怎么措辞」转向「怎么分配有限资源」。 具体做法其实就是四件事:稳定内容前置、工具按需加载、历史定期压缩、检索结果裁剪。都不复杂,但做与不做的差距,在长对话和复杂任务上会非常明显。 --- **延伸阅读**:本站另有《大模型 API 的账怎么算:token、上下文与缓存》和《RAG 入门:从切分到召回的一条完整链路》,可与本文对照。