LLM 应用的长上下文压缩与记忆蒸馏工程 2026
把短期 KV cache、中期增量摘要、长期事实图谱三层抽象为统一蒸馏流水线,辅以显式遗忘曲线与压缩监控,避免对话 50 轮后 AI 失忆。
约 26 分钟阅读7,782 字8 次阅读博主

把短期 KV cache、中期增量摘要、长期事实图谱三层抽象为统一蒸馏流水线,辅以显式遗忘曲线与压缩监控,避免对话 50 轮后 AI 失忆。

过去两年,几乎所有面向终端用户的 LLM 应用都在同一条路上摔过跤:随着对话轮次增长,prompt 体积迅速膨胀,TTFT 退化、token 单价上涨、模型推理注意力涣散导致的"金鱼记忆"——用户第 3 轮抱怨的内容,第 30 轮 LLM 完全忘记;用户提到的关键参数(如"我公司在上海"),在对话拉长到 100 轮后变成"请问您公司在哪个城市"。这不是模型的 bug,而是工程约束的必然。Transformer 自注意力机制的计算复杂度是 O(n²),128k 上下文窗口下,prefill 阶段单次 KV cache 占用的显存就足以让一张 H100 进入 OOM;更糟糕的是,长上下文里真正与当前 query 相关的 token 通常不到 5%,剩下 95% 是"历史包袱",徒增噪声。
截至 2026 年 9 月,主流生产级 LLM 应用已经形成共识:长上下文不是免费午餐,必须通过显式的压缩与蒸馏机制把 prompt 控制在工程可承受的窗口内,同时保留跨轮次的语义连续性。这件事在论文里被称为 "context engineering" 或 "memory management",在工程上更准确的名字是长上下文压缩与记忆蒸馏工程——它涉及分层摘要、增量遗忘、语义压缩率控制、记忆重建一致性、回填冲突解决等一系列尚未标准化的设计决策。
本文试图回答一个具体问题:在 2026 年的工程实践里,一套生产可用的长上下文压缩系统应当由哪些组件构成?组件之间如何协作?哪些是必选、哪些是可选、哪些是常见的反模式? 我们不讨论具体模型的 context window 数值——它们每季度都在变——而是讨论窗口之外那 95% 的工程决策空间。
把长上下文压缩问题抽象成三个正交维度,可以避免一上来就陷入"用什么摘要算法"的细枝末节:
第一层:记忆层级(memory hierarchy)——区分短期上下文(最近 N 轮)、中期摘要(按主题或时间窗口聚合的压缩段)、长期记忆(用户级别的事实、偏好、关系网络)。三者对应不同的存储介质、查询延迟、保留时长和压缩粒度。短期走 KV cache 与对话窗口,中期走嵌入式向量库与增量摘要索引,长期走结构化 KV(如"用户基本信息表"或"偏好图谱")。
第二层:压缩算子(compression operator)——把上下文从体积 V 压到体积 V' 时使用的变换。常见算子包括截断(truncation)、抽取式摘要(extractive summarization)、生成式摘要(abstractive summarization)、语义去重(semantic deduplication)、结构化抽取(structured extraction,把段落变成 JSON 字段)、对话状态机压缩(把多轮对话压成对话状态图)。
第三层:遗忘曲线(forgetting curve)——记忆随时间的衰减函数。Ebbinghaus 经典遗忘曲线在 LLM 应用里仍然适用,但要做工程化改造:衰减的载体不是"记忆强度"而是"记忆保真度"——一条 N 天前的用户偏好,今天的 prompt 里应该以多高的完整度出现?
这三个维度互相正交:层级决定"放在哪",算子决定"怎么压",遗忘曲线决定"留多久"。任何具体方案都是这三个维度上的一个点。
短期记忆的工程目标很直接:让最近 N 轮的对话以最低延迟、零信息损失的方式保持在 prompt 里。最朴素的实现是滚动窗口(sliding window),把最近 K 轮对话原封不动塞进 prompt。K 怎么定?没有标准答案,取决于模型窗口、token 单价、用户耐心。生产数据通常显示 K=10-20 是一个甜区——再大,单次推理成本急剧上升;再小,多轮对话的连贯性立刻崩。
比滑动窗口更精细的做法是 KV cache 复用。把第 N 轮对话计算出的 KV cache 缓存到显存,第 N+1 轮只增量计算新 turn 的 KV,然后拼接。这样 prefill 阶段从 O(n²) 退化到 O(1)(相对历史长度),TTFT 可以从秒级降到百毫秒级。主流推理框架(vLLM、TensorRT-LLM、SGLang)都支持 paged attention 和 prefix caching,关键约束是cache key 的设计——必须用稳定的内容指纹(如 turn 内容的 SHA256)作为 key,避免任何 prompt 微小变化(如一个空格)导致缓存全部失效。
短期记忆的另一个工程细节是截断策略。当 prompt 即将超长时,从哪个 turn 开始截?朴素的"截最旧"几乎一定是错的——用户可能在第 2 轮提到了关键事实,但第 5 轮以后全是闲聊。最优策略是基于摘要回填的截断:把最早几轮压缩成一段摘要留在 prompt 头部,剩余轮次保留原文。这正是引出第二层——中期记忆。
生产实现细节:KV cache 复用的工程难点不在算法,而在 GPU 显存调度。paged attention 把 KV cache 切成固定大小的 page(如 16 token 一页),动态分配显存页,避免传统连续显存分配导致的内部碎片(internal fragmentation)。但 page 切得太小会增大 page table 开销,切得太大会浪费显存——生产经验值是 16-64 token 一页,具体数值取决于模型 head dim 和并行度。Prefix caching 的命中率高度依赖 prompt 模板稳定性:系统 prompt 应当完全静态、tool schema 应当避免运行时变化、用户消息格式应当固定(哪怕用户改了标点也要规范化到同一格式)。命中率每提升 10%,生产环境的 TTFT P50 可以下降 30%-40%,这是免费午餐里最大的一道菜。
token-level 滚动窗口:除了 turn-level 滑动窗口,还有一类更细粒度的方案是 token-level 截断——按 token 数而非 turn 数滑动。这种方案在多模态对话(图片、文件附件让 turn 长度方差极大)场景下尤其有用,避免一个长 turn 独占整个窗口、压缩掉所有历史 turn。生产实现通常把 turn-level 与 token-level 复合使用:先按 turn 切,再按 token 上限截。
中期记忆的核心是摘要,但摘要不是简单的"全文压缩"。生产系统的摘要应当是分层、增量、可重建的。
分层意味着不同时间粒度的摘要并存:一个会话级别的粗摘要(100-300 字)、几个段落级别的细摘要(每个 30-80 字)、关键事实的结构化抽取(如"用户姓名"、"项目名称"、"截止日期")。三层摘要用不同的 prompt、不同的模型(粗摘要可用便宜模型,细摘要必须用强模型)、不同的存储介质(粗摘要放会话元数据,细摘要放进向量库,结构化事实放进 KV 表)。
增量意味着摘要不是每次重算,而是基于上一次摘要 + 新增对话的 diff 做增量更新。这避免了"对话 100 轮时摘要一次要 30 秒"的灾难。增量摘要的工程难点是冲突解决——用户在第 10 轮说"项目用 React",第 50 轮说"项目改用 Vue",摘要应当保留最新值并打上"已更新"标记,而不是简单追加两条矛盾陈述。
可重建意味着摘要必须可追溯——任何一条摘要断言都能反向指向它来源的对话 turn 区间。当用户质疑"你为什么记得这件事"时,系统应当能给出原始 turn 引用。这是 LLM 应用建立用户信任的关键工程能力。
长期记忆的工程目标是跨会话保留用户关键信息,让用户在下一次打开应用时无需重复"我叫 X,我公司在 Y,我喜欢 Z"。最常见的实现是用户级事实图谱(user fact graph):把用户的姓名、公司、偏好、历史项目、关键人脉抽象成结构化条目,每次对话结束时由后台批处理任务把新事实合并进图谱。
事实图谱的设计有几个关键决策:粒度(一条事实是"用户在阿里"还是"用户在阿里巴巴-钉钉事业部-2024 年 9 月至今"?前者泛化好但歧义多,后者精确但维护成本高)、冲突解决(新事实 vs 旧事实如何取舍)、衰减策略(5 年前的项目背景是否还要保留?)。
遗忘曲线在这里第一次成为显式的工程参数。Ebbinghaus 经典曲线 R = e^(-t/S)(R 是记忆保真度,t 是距今时间,S 是记忆强度)仍然是合理起点,但生产系统要做两件事:(1) 重要记忆的强度提升——用户明确说"请记住这个"的事实,S 应当显著拉长;(2) 衰减触发召回——当某条记忆的 R 跌破阈值(如 0.3)时,主动从长期存储里召回并摘要到当前会话,而不是默默丢失。
具体压缩算法的选择直接决定记忆保真度与工程成本的平衡。我们对生产常见的六类算子做横评:
截断算子最便宜(O(n) 计算,O(1) 存储),信息损失最大——只适合短期滑动窗口,不适合中期摘要。抽取式摘要(TextRank、LexRank、LLM-based extractive)成本中等(O(n log n) 或一次 LLM 调用),保真度高但摘要长度难精确控制——产出可能是原始长度的 30%-70%,对 prompt 体积控制贡献有限。
生成式摘要(LLM abstractive)成本最高(一次甚至多次 LLM 调用),但摘要长度可精确控制(直接指定"压缩到 200 字以内"),且可以做到语义融合——把分散在 10 轮里关于同一话题的讨论合成一段连贯叙述。生产上推荐用"小模型粗筛 + 大模型精炼"的两阶段:先用 7B 模型生成粗摘要(成本低),再用 70B 模型对粗摘要做润色与压缩(质量高)。
语义去重算子专门解决"用户重复表达同一件事"造成的 prompt 膨胀——把语义相似度高于阈值的段落合并,保留最完整的一条。这是中期记忆的高 ROI 优化,但工程实现上要小心:阈值过低会误合并,阈值过高则错过真实重复。
结构化抽取算子把非结构化对话转成 JSON 字段(如 {"用户": "张三", "项目": "X", "截止": "2026-10-01"}),用结构化数据替代自然语言描述。优点是体积可以极小(一条 JSON 可能就 50 字节 vs 一段描述 200 字节),查询精确(SQL-like 过滤),且天然支持增量更新(只 update 改变的字段)。缺点是抽取 schema 设计需要领域知识,且对"开放式闲聊"无能为力。
对话状态机压缩是把多轮对话抽象成状态机——每个状态是一个 topic,对话是状态之间的转移与状态内的论据积累。这是六类算子里最难工程化但最强大的,适合长流程任务(如客服工单的逐步诊断)。
把上面四节拼起来,给出一个生产可用的统一架构。它包含五个组件,串成一条数据流:
组件 1:短期缓冲(short-term buffer)——最近 K 轮对话原文 + KV cache 复用,TTFT 优化关键。组件 2:增量摘要器(incremental summarizer)——每 N 轮触发一次(或每次新 turn 后异步),基于上一版摘要 + 新增 turn 做 diff 更新。组件 3:事实抽取器(fact extractor)——后台批处理,把摘要里的显式事实合并进用户图谱。组件 4:召回路由器(recall router)——每次新 turn 进来时,决定哪些记忆应当被拉入当前 prompt——基于 query 与记忆条目的语义相似度、衰减后的 R 值、用户偏好权重。组件 5:压缩监控器(compression monitor)——追踪摘要长度、召回命中率、用户对记忆准确性的反馈(隐式如"我没说过这个"),用于动态调整压缩比与召回阈值。
这五件套不是全部可选——其中短期缓冲、增量摘要器、召回路由器是三件套必备,事实抽取器适合有人设/偏好记忆需求的应用,压缩监控器在生产规模(DAU > 10 万)后才有 ROI。
最关键的工程纪律是压缩比必须显式控制。许多团队的失败不是没做压缩,而是压缩比失控——对话 50 轮后 prompt 仍然是 50k tokens(说明压缩失效),或压缩到 500 tokens 但丢掉了所有关键事实(说明压缩过度)。生产上推荐自适应目标压缩比——根据当前对话长度、用户 session 长度、模型窗口动态调整,例如"前 20 轮目标 8000 tokens,20-50 轮目标 4000 tokens,50 轮以上目标 2000 tokens"。
异步流水线设计:五个组件最好解耦运行——短期缓冲与主对话流程同步(每 turn 必跑),增量摘要器异步(每 5-10 turn 跑一次或定时跑),事实抽取器离线批处理(每天一次合并当天所有用户的事实更新),召回路由器同步但用轻量模型(向量相似度查询通常 < 50ms),压缩监控器离线(每天统计指标)。这种异步设计让主对话流程的延迟预算只承担短期缓冲 + 召回路由器两项,把重活(摘要、抽取)推到后台。生产经验值:主流程同步部分的目标 P95 延迟 < 200ms(不含 LLM 推理),异步部分的执行时长允许到秒级甚至分钟级。
成本-质量权衡曲线:压缩系统的核心 trade-off 是 token 成本 vs 信息保真度。压缩比 1:10(10 倍压缩)下,单条对话的 prompt 成本降为原来的 1/10,但召回准确率可能下降 30%-50%;压缩比 1:3 下成本只降 67%,但召回准确率能保持 90%+。生产上推荐双轨设计——关键用户(付费版)走低压缩比(保质量),免费用户走高压缩比(保成本)。压缩比可以通过 A/B 测试持续优化,把"召回准确率"作为北极星指标,用 LLM-as-Judge 自动评估,不需要人工标注。
几个值得展开的反模式:
反模式 1:摘要递归——对话 100 轮时,把"前 50 轮的摘要"+"后 50 轮原文"喂给 LLM 做新摘要,多轮递归后摘要信息损失指数级放大。正确做法是只对原文做摘要,不做摘要的摘要。
反模式 2:全量重算——每次新 turn 都重新压缩整个对话历史,计算成本爆炸且摘要之间高度相似浪费 token。正确做法是diff 式增量更新。
反模式 3:遗忘曲线不区分记忆类型——把"用户在哪个城市"和"用户上周讨论了一个 bug"用同一条衰减曲线,导致城市这种事实记忆很快丢失,而 bug 细节这种高信息密度记忆又被过度保留。正确做法是按记忆类型分层衰减——事实型记忆用慢衰减,事件型记忆用快衰减。
反模式 4:压缩监控缺位——上线后从不知道压缩质量如何,直到用户在公开渠道抱怨"你又忘了"。正确做法是持续追踪摘要-原文一致性指标(让 LLM 评估:摘要是否覆盖原文关键事实)、用户反馈指标(点赞/点踩摘要准确度)、对话连贯性指标(多轮对话中信息保真度)。
几个开放问题截至 2026 年 9 月仍未有公认解法:当用户主动要求"请忘记我之前说的 X"时,记忆删除如何级联到所有下游摘要与事实图谱(GDPR 合规的工程难题);多模态记忆(用户发送的图片、语音、文件如何压缩并保留跨模态引用);跨设备记忆同步的冲突解决(用户在手机和电脑两端分别修改了同一偏好);对抗性记忆投毒——用户故意输入误导性信息污染长期记忆。
最后给一份落地清单,按推荐顺序排列:
绝对不要做的事:摘要递归、全量重算、忽视压缩监控、单条衰减曲线覆盖所有记忆类型。每一条都是真实生产事故的根因。
一个判断标准:上线 3 个月后,如果用户从不在公开渠道抱怨"AI 忘了我说过的话",说明压缩系统基本合格。如果用户反复需要重新自我介绍,说明中期/长期记忆组件需要立即投入资源重构。
未来一年的演进方向:截至 2026 年 9 月,长上下文压缩工程仍处于快速演进阶段。三个方向值得重点关注。第一个方向是结构化记忆与神经记忆的融合——纯文本摘要的语义保真度上限已被反复验证,未来主流方案可能是"结构化 JSON 字段 + 自然语言注释"的混合表示,前者保精确事实,后者保上下文叙事。第二个方向是用户主导的记忆治理——目前记忆几乎全由系统自动管理,但用户的"被遗忘权"与"显式偏好"应当有更友好的 UI,让用户能查看、修改、删除自己的长期记忆;这块涉及隐私合规与用户信任的双重约束,工程上需要一套完整的 CRUD + 审计链路。第三个方向是跨会话的全局记忆而非单会话记忆——目前大多数 LLM 应用的记忆仍是 session 级别,未来应当演进到跨 session 甚至跨应用的全局记忆("用户在与本应用聊天时讨论了项目 X,明天打开另一个应用时应当自动加载 X 的上下文"),这需要跨应用的身份层 + 记忆层协议,标准化空间巨大。综合来看,长上下文压缩是 LLM 应用从"能聊天"走向"能陪伴"的关键工程能力,它不是单一算法的胜利,而是分层蒸馏 + 增量摘要 + 显式遗忘 + 异步流水线 + 持续监控的系统工程。
长上下文压缩的核心是分层蒸馏——短期 KV cache 复用保 latency、中期增量摘要保语义连续性、长期事实图谱保用户连续性,辅以显式遗忘曲线与压缩监控,缺一不可。
Conversation
0 条