考察点
这道题出自 2026 年 Agent 高频面经("记忆太多放不下上下文窗口怎么办?""Session 太长,会不会挤爆 LLM 的 Context?"),一面必问级。面试官想看你有没有处理过真实长会话——只答"做摘要"会立刻被追问摘要丢信息怎么办。答好这题要给出分层的手段谱系、触发时机、保真兜底三条线。
参考答案
先算账:什么时候会爆
以 200k token 窗口为例,系统指令加几十个工具 schema 吃掉 30k,检索和记忆吃掉 20k,留给对话历史的大约 120k。一次工具调用返回几千 token 很常见,一个跑三十轮工具调用的编程 Agent,历史轻松超过 150k。不处理就会报错截断,或者更糟——静默丢掉头部的系统指令。
四层手段,从粗到细
| 手段 | 做法 | 代价 |
|---|---|---|
| 滑动截断 | 只保留最近 N 轮原文,更早的直接丢 | 最早的目标、约束会丢,只适合闲聊类 |
| 滚动摘要 | 旧历史由 LLM 增量摘要成"前情提要" | 细节有损,摘要本身要 token 和调用成本 |
| 结构化提取 | 从旧历史抽出事实清单(实体、决定、TODO)替代叙述 | 提取质量依赖 prompt,适合任务型 Agent |
| 结果外置 | 工具大返回落盘,历史里只留结论一句话加引用 ID | 模型要额外一次"读取"才能看到原文 |
生产上是组合用:最近 5-10 轮原文保留,更早的走滚动摘要,摘要之上再维护一份结构化事实清单(当前目标、已做决策、未决问题),工具结果一律外置。压缩后历史的 token 占用通常能压到原来的 10%-20%。
触发时机:别等爆了再压
在窗口用量达到阈值(我的经验是 70%-80%)时就触发压缩,而不是写满报错才处理。理由有二:一是要给本轮输出和下一轮输入留出余量;二是压缩本身要消耗上下文(做摘要得把旧历史再喂给模型一次),真等到 100% 连做摘要的余地都没了。Claude Code 的 auto-compact 就是这个思路。
增量摘要的做法:维护一份滚动摘要 S,每轮新增对话超过一定量(比如 10k token)时,把"S + 新增原文"喂给 LLM 生成新摘要,只把新增部分摘要后合并,不全量重算——全量重算在长会话里成本是平方级。
保真兜底:原文永不真删
压缩最大的风险是关键信息被摘要吞掉——某个具体报错码、用户中途改过的需求。两条防线:第一,摘要 prompt 里硬性要求保留实体、数字、路径、决策和未决问题,这几类是任务型 Agent 的命脉;第二,所有被压缩的原文完整落盘(文件或 KV),历史里留引用,给模型一个"翻旧账"工具,发现摘要里没有就按引用读回原文。这样摘要只损失"即时可用性",不损失"可恢复性"。
一个反模式
有人为了省成本把压缩模型换成小模型。要慎重:摘要是信息瓶颈,小模型漏掉一个关键约束,后面十轮推理全白跑。压缩环节值得用和主模型同级的模型,省 token 不该省在这里。
可能的追问
- 摘要越滚越长怎么办?——摘要本身设上限,超限后对摘要做二次压缩;同时结构化事实清单是天然有界的,决定和 TODO 收敛后条目会删除。
- 多轮压缩后模型"忘了"最初的目标怎么办?——会话目标单独字段存,每轮原样注入系统区,不参与摘要流程。
- 压缩时机除了阈值还有什么?——话题切换点也可以触发,检测到新会话意图时把上一话题整体归档,比机械按 token 切更符合信息边界。