大模型应用如何做上下文压缩?
简化版
上下文压缩不是把文本一律缩短,而是在 Token 预算内保留对当前任务有决定作用的信息。工程上先删除重复和无关内容,再对历史做结构化状态提取、对检索文档做相关片段抽取、对已完成阶段做带引用摘要;数字、否定条件、权限和未解决约束应高保真保留。压缩后必须用任务成功率、事实保持率和引用可回溯性验证,不能只看压缩比。
详细版
压缩可分为无损与有损:无损手段包括去重、删除模板、裁剪未使用工具、规范化 JSON;有损手段包括抽取、摘要、聚类合并和外置原文。优先做无损,再按内容类型选择有损策略。
raw context
-> permission/version filter
-> deduplicate and remove irrelevant blocks
-> extract hard constraints and entities
-> summarize completed history with citations
-> pack by utility per token
不能把系统规则、精确金额、日期、否定条件和当前任务状态交给自由摘要反复改写。大文档原文存为 artifact,摘要带来源范围和哈希,需要时按引用展开。压缩器本身也会产生幻觉与遗漏,因此要用问答回归、字段对照、冲突检测和不同预算档位的质量曲线做验证。
完整版教学
一、压缩目标是任务效用,不是最短文本
一段 5000 token 的上下文压到 500 token,压缩率 90%,但若删掉唯一限制“不得向外发送”,结果就是失败。压缩要优化的是单位 token 对当前决策的价值,并受硬约束保持率限制。
不同任务需要不同信息。写摘要关心主题与结论,执行转账关心精确账户和金额,代码修复关心错误栈和相关文件;不存在通用的“最佳摘要”。
记忆钩子:先问哪些信息一旦丢失会改变答案或动作,再谈能压掉多少。
二、先做无损清理
很多上下文浪费来自相邻检索块重叠、重复工具 Schema、HTML 导航、空白和序列化冗余。去重与清洗不改变语义,风险最低,应放在模型摘要之前。
| 手段 | 是否有损 | 典型对象 |
|---|---|---|
| 精确/近似去重 | 基本无损 | 重叠 chunk、重复消息 |
| 模板与标记清洗 | 基本无损 | HTML 导航、日志前缀 |
| 字段投影 | 取决于 Schema | 工具返回、表格 |
| 抽取与摘要 | 有损 | 长历史、文档正文 |
若十个检索块每块 800 token,相邻重叠 200 token,简单消除九处重叠就能省约 1800 token,不需要承担生成式摘要风险。
三、把硬状态从自然语言中提取出来
多轮对话里的目标、实体、金额、日期、禁止事项和待确认项应写进结构化状态。这样旧消息被摘要时,关键约束不必依赖模型每次重新理解。
{
"goal": "生成内部报告",
"deadline": "2026-09-18",
"constraints": ["不得对外发送", "预算<=500"],
"unresolved": ["确认数据时间范围"]
}
模型可提出字段更新,但类型、权限和冲突由控制器验证。用户修改预算时形成新版本,避免旧摘要与新值同时进入上下文。
四、对话压缩采用“近期原文 + 历史摘要”
近期几轮保留原文,以免丢掉语气、指代和刚出现的约束;较早阶段按完成的子任务摘要,记录决定、原因、产物引用和未解决问题。固定保留最近 N 轮不够,因为一轮长度差异可能有百倍。
摘要不应不断摘要上一次摘要,否则误差逐轮累积。可以周期性从原始事件重建,并在摘要上记录覆盖消息 ID 范围。精确字段留在状态对象,摘要负责叙事关系。
当用户追问早期细节时,通过消息或 artifact ID 展开原文,而不是让摘要编造。
五、文档压缩优先抽取当前问题相关片段
RAG 场景中,全文摘要可能删除一个对当前问题关键、对全文却不显眼的例外条款。应先根据问题定位相关章节,再在局部范围压缩,并保留标题、版本、页码和原文引用。
假设文档 40K token,检索定位三段共 4K;对这 4K 压到 2K,比先把全文摘要成 2K 更可能保留问题相关细节。多跳问题还要确保不同文档的证据组共同保留。
冲突来源不要被摘要成单一结论,应显式列出差异和各自时间,让下游决定采用哪个版本。
六、用信息价值做预算装箱
候选片段可以按相关度、权威性、新颖度、时效和长度打分,近似计算每 token 效用。硬约束设置无限高优先级,普通背景按边际价值装入。
utility_per_token = (relevance × authority × freshness × novelty) / tokens
公式是启发式,不应盲目相乘。短但错误的片段不能因分数高被选中,权限和来源过滤必须先于排序。
装箱还要为输出留预算;输入刚好填满窗口会导致答案截断。
七、摘要必须保留来源和不确定性
生成式摘要可能把“可能”“不得”和“仅在……时”删掉,这些词往往决定业务含义。提示应要求保留数字、否定、条件、例外和未知项,并禁止补充原文没有的事实。
每条关键摘要附来源区间,例如 [doc7:p12#L20-L35]。验证器可以检查引用片段是否蕴含摘要;低支持度条目直接回退原文或转人工。
原始内容外置而不是删除。摘要是索引和工作副本,不是唯一真相。
八、评测质量—压缩率曲线
准备带关键事实、诱饵、冲突和多跳证据的数据集,在 25%、50%、75% 等预算下比较答案正确率、字段保持率、约束违反率和引用准确率。
例如从 8K 压到 4K,准确率由 90% 降至 89%;压到 2K 后降至 78%。拐点说明 4K 左右是当前策略的合理预算,不能只因 2K 更便宜就上线。
线上记录压缩前后 token、采用的策略版本、被丢弃块 ID 和失败样例,模型或检索变更后做回归。
九、常见误区与追问
- 误区:摘要越短,压缩效果越好。 目标是保持任务质量,而不是追求最高压缩率。
- 误区:所有内容都交给同一个摘要 Prompt。 对话、状态、代码和证据需要不同策略。
- 误区:反复总结旧摘要很省成本。 误差会累积,应保留原始事件并周期重建。
- 误区:长文先整体摘要再检索最好。 整体摘要可能删掉问题相关的局部例外。
- 误区:压缩后原文可以删除。 关键结论要能回溯与纠错。
- 追问:哪些内容不应自由摘要? 权限、安全规则、精确数值、否定条件和当前任务状态。
- 追问:怎样检测摘要幻觉? 做引用蕴含检查、关键字段对照和固定问答回归。
- 追问:什么时候触发压缩? 达到预算水位、子任务结束或上下文用途切换时。
十、加强记忆
上下文压缩记住“先清理、再抽状态、后摘要、留引用、看曲线”:先去重和清洗无损冗余,把目标、数字和约束提为结构化状态,再对完成历史与相关文档做有来源的局部摘要;原文作为 artifact 保留。最终以任务正确率、约束保持和引用准确率选择预算拐点,而不是拿压缩比当成功标准。