模块二 · 上下文工程
上下文预算:压缩、缓存与结构化状态
把上下文窗口当成"预算"而不是"容量",是长会话系统能跑住的前提。这一节给出优先级顺序、四种压缩手段,以及不能压缩的部分。
读完这一节,你能做到
- 用预算思维管理上下文,而不是"窗口还有空位就塞"。
- 按优先级裁剪:什么该留、什么该压、什么该扔。
- 用前缀缓存、摘要、结构化状态三种手段降本。
- 说清哪些内容绝对不能压缩。
一、窗口是预算,不是容量
窗口 20 万 token 不代表"每次塞 20 万"。三个原因:
- 贵:输入按量计费,塞满是常态化的浪费。
- 慢:输入越长,首字越慢。
- 不准:中间段的内容容易被忽略。
正确的心态是:每一次调用都有一个预算,预算要花在能改变结果的信息上。
二、优先级:从后往前删
| 优先级 | 内容 | 处理方式 |
|---|---|---|
| 1 | 系统指令与安全约束 | 必留,放最前 |
| 2 | 最近 3-5 轮对话 | 原样保留 |
| 3 | 本轮检索片段 | 3-5 条,按相关性排序 |
| 4 | 已确认的事实与结论 | 结构化注入,不进对话 |
| 5 | 更早的对话摘要 | 压缩后保留 |
| 6 | 寒暄与过程性内容 | 直接删 |
裁剪顺序:先删 6,再压 5,再收 3,最后才动 2。系统指令和确认过的状态永远不动。
预算怎么定
不要按“窗口有 20 万就留 2 万”这样拍。更实用的是反推:
- 先定单次成本上限(月预算 ÷ 日请求量 ÷ 单价);
- 算出可用的输入 token 上限;
- 在这条线上分配:系统 10%-15%、检索 30%-40%、历史 30%-40%、状态 10%。
预算一旦定下来,任何“再加一段上下文”的提议都要先说清挤掉谁。这一步能挡掉很多“顺手多塞点”的改动。
三、四种压缩手段
1. 前缀缓存
系统提示、工具说明、固定示例这些"每次都一样"的内容放最前面,命中服务商的上下文缓存后,成本与首字延迟都会下降。
关键在于前缀必须稳定:中间改一个字符,缓存全部失效。所以动态内容(时间戳、用户名)要放后面。
2. 摘要
把较早的对话压缩成"事实与结论",而不是"聊了什么"。摘要里应该只有:已确认的信息、已达成的决定、未解决的问题。
3. 抽取式压缩
从长文档里只取相关句子,而不是整段塞进去。常见做法是先用检索找出段落,再按句打分取前几句。
4. 结构化状态
订单号、金额、用户选择这类信息,写进一个结构化的状态对象,每轮按需注入。这比让模型从十轮前“回忆”可靠得多。
一次压缩的实测对比
以一段 20 轮的客服对话为例(示意数字):
| 方案 | 输入 token | 首字延迟 | 第 18 轮问早期事实的准确率 |
|---|---|---|---|
| 全量历史 | 约 9000 | 2.4s | 准确 |
| 只保留最近 5 轮 | 约 2500 | 0.9s | 答错(事实已丢) |
| 最近 5 轮 + 结构化事实 | 约 3000 | 1.0s | 准确 |
三行对比说明一件事:单纯裁历史会丢事实,把事实抽成结构化字段才能既省又准。 这也是“摘要”与“结构化状态”的分工——摘要保上下文连贯,结构化状态保事实准确。
四、不能压缩的东西
| 内容 | 为什么不能压 |
|---|---|
| 安全与权限约束 | 压掉就是放开了边界 |
| 精确数字与条款原文 | 摘要会引入偏差,合规场景不可接受 |
| 用户明确表达的要求 | 二次表述容易失真 |
| 多步任务的前置结论 | 后面的步骤依赖它 |
判断方法:如果这段内容被改写后可能产生歧义,就不要压,改成结构化字段精确传递。
一个经验值
如果摘要后总长度只降了 20%,说明压的是边角内容,不值得为它引入失真风险。真正的浪费通常在重复的 system prompt 与未裁剪的历史上,先治理那两处,比写一个复杂的摘要器有效得多。
五、怎么验证压缩没伤到关键信息
一个 20 轮测试
构造一段 20 轮的长对话,在第 3 轮确认一个关键事实(比如"我的订单地址改成 B"),第 18 轮再问"我的收货地址是哪个"。
- 答对:压缩策略保住了关键信息。
- 答错或答成旧值:摘要里丢了事实,或者被更早的旧值污染。
再补一个成本对照
同一段对话,记录压缩前后的输入 token 与首字延迟。只压成本不看指标,容易把质量压没。
六、常见坑
- 把窗口当容量。 能塞多少就塞多少,成本和延迟一起涨。
- 摘要写成流水账。 "用户问了 X,客服答了 Y"没有信息价值,要留事实与结论。
- 前缀里放动态内容。 缓存永远命中不了。
- 把关键数字交给摘要。 金额、日期、条款,压了就失真。
- 只压不测。 没有长对话测试,压缩伤到关键信息也不知道。
- 状态靠模型记。 跨多轮的事实必须结构化,不能指望模型"记住"。
七、动手任务:自写 → AI 写 → 对比 → 取舍
四步不跳:① 自己写(限时,关掉补全)→ ② 让 AI 写同一题 → ③ 逐条比对 → ④ 说出保留谁的写法。
① 自己写
- 给一次请求列出 token 预算表:系统、历史、检索、状态各占多少,总预算是多少。
- 设计一个 20 轮测试用例:第几轮埋事实、第几轮提问、期望答案是什么。
② 让 AI 写同一题
把第 1 题交给 AI,补一句 按“必留 / 可压 / 可删”三档给建议,并指出哪些内容压了会出事。
③ 对比要盯的点
- 它是否把系统指令也列进了"可压"?
- 对精确数字与条款,它是压缩还是结构化传递?
- 有没有区分"前缀"与"动态内容"?
④ 一句话取舍
它的压缩方案会让哪一类问题答错?你能接受吗?
八、自测
- 为什么说窗口是预算而不是容量?
- 裁剪的优先级顺序是什么?
- 前缀缓存为什么要求前缀稳定?
- 摘要里应该保留什么、删掉什么?
- 哪四类内容不能压缩?
- 怎么验证压缩没有伤到关键信息?
参考答案要点:成本、延迟、中间遗忘;系统 > 最近几轮 > 检索 > 状态 > 摘要 > 寒暄;改一个字符缓存全失效;事实与结论,删寒暄;安全约束、精确数字、用户原话、前置结论;20 轮长对话埋事实测试 + 成本对照。
配套题目
★ 越多越该先背;点题目可看完整答案与深入版。
- ★★★★☆ 长会话上下文怎么控成本又不丢信息?
- ★★★★☆ 上下文窗口变大就能塞更多内容吗?
- ★★★☆☆ 哪些内容不该写进记忆?
提示:读完可以顺手做几道对应题目,检验是否真的理解