上下文压缩
用更紧凑的表示替换窗口内容的操作 —— 谱系、触发、保留、自定义指令调优、设计扩展、度量、跨框架参考
为什么压缩重要
长时 Agent 会把上下文窗口塞满。不做压缩时,Agent 要么在硬上限处崩溃,要么随着窗口超出模型有效工作范围而逐渐劣化(context rot)。压缩用更紧凑的表示替换窗口里的部分内容,让 Agent 能继续工作。
本章节其他所有技术 —— 缓存、即时加载、子 Agent 隔离 —— 都在减少进入窗口的量。压缩是它终究进得太多时你能做的事。
设计决策一览 (Design Decisions at a Glance)
一份压缩设计由七个决策塑形,大致按这个顺序:
- 你需要压缩吗? —— 用量画像。短任务经常不用。
- 用谱系的哪几层? → § 压缩谱系
- 触发策略 —— 固定阈值、自主、任务边界、还是混合? → § 触发策略
- 保留政策 —— 什么原样保留、什么紧凑引用、什么丢? → § 保留政策
- 自定义指令 —— 怎么把政策编成 prompt 文本? → § 自定义指令调优
- 情景专属扩展 —— 多 Agent、缓存、恢复? → § 设计扩展
- 度量 —— 怎么验证它真的起作用? → § 度量
按顺序读后续;每一节都建立在前一节之上。
压缩谱系
压缩不是一个操作,而是一条代价-保真度折衷尖锐不同的技术谱系。选能奏效的最轻那个,不够再升级。
| 技术 | 做什么 | 保真度损失 | 计算成本 |
|---|---|---|---|
| 工具结果清除 | 把已消费工具输出的内容清掉 | 若 Agent 已推进过,无损 | 零 |
| 工具结果截断 | 工具输出截到 N 字符;保留首 + 尾 | 有损 —— 中段细节丢失 | 零 |
| 轮级替换 | 把较早的轮次替换为预生成摘要 | 有损 —— 摘要抓大意 | 写入时付一次 |
| 完整对话摘要 | LLM 重读整段对话、写出新起点 | 最有损 —— 叙事端到端被压缩 | 一次完整 LLM 调用 |
哪一层适用何时
启用哪几层取决于你的 Agent 多长、工具多密:
- 短对话、工具使用适度 —— 层 1(清除)单独就够
- 长对话、工具使用中等 —— 层 1 + 2(清除 + 截断)
- 长对话、工具输出密集 —— 层 1 + 2 + 3(加轮级替换)
- 很长、反复逼近上限 —— 四层全开,完整摘要作为最后手段
从最轻开始、按需升级比永远跑完整摘要便宜。但不要等到最后一刻 —— 重型压缩需要空间才能把工作做好,触发时窗口已 98% 满意味着摘要本身没余裕。
选择性截断 vs 均一截断
把每个工具输出截到同一字符数既便宜又浪费。50 行的文件读可以原样保留;50,000 行的数据库 dump 需要激进修剪。按工具调 —— 让每个工具声明自己的截断策略(保头、保尾、保摘要)。
“先召回、后精度” 的配方
从最大化召回率开始 —— 确保压缩提示词捕获每条相关信息。然后迭代提高精确度 —— 消除冗余的工具输出和消息。 —— Effective Context Engineering for AI Agents, Anthropic, 2026
把你的压缩搭成”宁留勿缺”的形态。等看到 Agent 压缩后实际在重读什么,再修剪。反过来做 —— 一开始就紧、看到丢失才放 —— 会失败,因为你看不到丢失,直到几周后用户投诉。
触发策略
最难的问题不是”怎么压”,而是”何时压”。四种策略覆盖整个空间。
固定阈值
总 token 越过上下文窗口的固定比例(常见 60–85%)或绝对值(Anthropic API 默认 150,000、最低 50,000)时触发压缩。
- 优势:可预测、易推理、不涉及模型判断。
- 缺点:可能在糟糕的时刻触发 —— 推理中途、工具链中途、或 Agent 正要完成时。Agent 失去连续性,因为触发基于 token 数而非任务态。
自主触发
Agent 自己决定何时压。LangChain Deep Agents 和 Claude Code 都提供这种形态。Agent 通常在以下时刻触发:
-
任务切换 —— 完成一个子目标之后
-
提取之后 —— 刚从长文档或工具输出提取出结果
-
摄入之前 —— 要拉一段大新上下文之前
-
多步边界 —— 开始重构、迁移、分析之前
-
优势:压缩发生在”失去的状态最少”的时刻。Agent 自己挑出逻辑工作单元之间的缝。
-
缺点:模型判断会波动。Agent 可能压得太晚(拖到撞天花板)或压得太频(摘要的摘要会退化)。需要调优。
任务边界压缩
由 harness、而不是 Agent 或阈值声明压缩点。每个工作流阶段结束时压一次;摘要成为下一阶段的输入。流水线、多 Agent 交接、结构化工作流用这种。
- 优势:压缩是架构的一部分,不是应急响应。没有意外触发、没有判断题、阶段之间有干净缝。
- 缺点:只对有天然缝的工作流奏效。开放式 Agent 循环不具备。
不做(到上限就崩)
值得点名,因为许多早期 Agent 就是这样。无压缩、上下文塞满、模型报错或悄悄截断。唯一对策是”把对话保持短”。短命 Agent 可接受;能跑多于几轮的 Agent 不可接受。
生产默认是混合
多数生产系统组合使用:固定阈值作为安全网 + 自主或任务边界作为主力。阈值兜住主力没来得及触发的情况;主力避免固定阈值出名的”最糟时刻触发”。
保留政策
一旦你知道用哪层、何时触发,实质的设计问题是:什么存活? 这个决定对压缩后 Agent 是否连贯的影响比其他任何选择都大。
三层保留:
永远原样保留
- 用户的当前任务轮(最近的 N 轮,通常 3–10 轮)
- 当前打开的文件加它们的最新状态
- 进行中的工具调用,还没返回的
- 系统提示词和记忆索引 —— 这些本就不在压缩区内,点名是提醒你别不小心把它们压了
以紧凑引用保留
- 约束未来行为的决策 —— 保决策、丢商议
- 读过但没改的文件 —— 保路径、不保内容
- 用户意图 —— 最初的请求和关键澄清,压缩但显著
- 架构承诺 —— 技术选择、接口契约
- 未决问题 —— 发现但未修的 bug、开放问题
可以自由丢弃
- 已被读取且综合进决策的工具输出
- 导致已提交决策的中间推理
- 被抛弃的探索分支
- 例行应答 —— “好,我查一下……”
- 被取代的决策 —— 被更新版本覆盖的旧计划
线划在哪里
“永远原样保留”和”紧凑引用”之间的边界是压缩 bug 最多的地方。一个安全的经验法则:
- 用户会明显察觉丢失的东西 → 原样层
- Agent 需要记得但必要时能重建的东西 → 紧凑引用
- 其他一切 → 可丢弃
自定义指令调优
你的保留政策是”什么”存活。自定义指令是”怎么” —— 把政策编码成给摘要 LLM 的实际 prompt 文本。默认压缩 prompt 为通用对话而优化,经常把你的用例搞错:丢掉架构决策、保留例行工具交换、忘掉用户陈述的偏好。
每个正经压缩系统都暴露替换或增补默认 prompt 的途径:
- Anthropic API ——
instructions参数完全替换默认 prompt - Claude Code ——
/compact "focus on the recent database migration"追加用户指引 - LangChain Deep Agents —— middleware 层配置摘要 prompt
- OpenAI Agents SDK —— session 配置里的自定义摘要器函数
怎么写好自定义指令
把上一节的每个保留层翻译成 prompt 文本:
- 原样层 —— 明确列出:“保留用户原始请求原文。最近 N 轮不变。保留当前文件编辑态。”
- 紧凑引用层 —— 描述压缩形式:“每个架构决策压成一句话。未决问题每条列一行。即便内容被压了也保留文件路径。”
- 丢弃层 —— 说明要丢什么:“省略例行应答、被抛弃的探索分支、以及已被综合进已提交决策的工具输出。”
prompt 要保持短而规定性。嵌套规则多的长摘要 prompt 会让较小的摘要模型困惑;干净的”保留什么 / 丢什么”清单比段落式指引表现更好。
用 Replay 验证
在生产里信任一条自定义压缩 prompt 之前,用 replay 测:拿一个已知良好的长任务、在不同点强制压缩、从压缩态继续执行、检查继续的工作是否匹配未压缩的基线。这里的失败就是你的 prompt 丢了不该丢的东西的信号。
这也是 § 度量 里正式化的回路 —— 在这里提一下,是因为它是你对自定义指令、保留政策、触发策略做的每一次改动的验证步骤。
设计扩展
基础设计(谱系 + 触发 + 保留 + 自定义指令)处理单 Agent、不带缓存、无长时恢复需求的 setup。下面三个扩展只在你的情境匹配时适用 —— 不是每个 Agent 都需要。
多 Agent 协调
适用场景:多个 Agent 共享上下文(共同对话、共享状态)或它们的压缩决策互相影响。
每个 Agent 有自己的上下文窗口。压缩设计要决定:每个 Agent 独立压、还是有个协调者?
分散式压缩(常见默认) —— 每个 Agent 独立压。简单、不用协调者。Agent 上下文基本独立时工作良好(主 Agent 委托给子、子回传压缩摘要)。
- 劣势:Agent 共享大量上下文时,每个都重复压一次,且可能压成略有差异的摘要,造成漂移。
集中式压缩(AutoGen 的模式) —— 一个协调者压缩共享对话、广播给所有 Agent。AutoGen 的 CompressibleGroupManager 是公开的例子。
- 优势:单一真相源。所有 Agent 对”说过什么、意思如何”达成一致。
- 劣势:需要协调者角色、在高负载下成为瓶颈。
指导:独立 Agent → 分散式。共享对话(协作编辑、共享线程)→ 集中式。父子配干净交接 → 分散式(父只看子的摘要)。
Prompt 缓存集成
适用场景:你在用 prompt 缓存(你大概率在用 —— 缓存命中通常便宜 10×)。
压缩和缓存有一个微妙的互动。缓存只在稳定前缀上命中。每次压缩事件替换内容,可能废掉缓存前缀。
三种要遵守的模式:
- 保护缓存头部。最稳定的内容(工具、系统提示词、耐用示例)活在压缩区之前。压缩替换头部之后的历史、不是头部本身。
- 缓存摘要本身。Anthropic API 让你在 compaction block 上放
cache_control—— 摘要文本写时被缓存,下次调用便宜地读。 - 别把压缩输出写在缓存区之前。若实现把压缩输出前置为”新上下文”,每次压缩都废掉缓存。压缩必须写在缓存前缀之后。
可恢复性与再压缩
适用场景:你的 Agent 跑得足够长需要考虑失败恢复,或一段对话可能被压缩多次。
压缩是有损的。若执行在压缩之后、任务完成之前失败,你能恢复吗?
三种机制:
- 压缩前日志 —— 压缩触发前把完整压缩前状态记录到持久存储。失败时加载、尝试不同策略。
- 压缩 Checkpoint —— 压缩输出包含对压缩前状态的引用。恢复时载入摘要、保留引用以便必要时再展开。
- 并行恢复通道 —— 独立的、始终追加的 artifact(记忆、笔记、auto-memory)独立于压缩区地捕获关键决策。Claude Code 的 Auto Memory 就是这种。
为再压缩而设计:某一刻,压缩过的摘要本身需要被再压缩(摘要的摘要)。每一次都丢保真度。预期到这点:
- 给任何一次对话的压缩次数设上限;超过 N 就开新会话带显式交接
- 保留一个”核心身份”区永不被再摘要 —— 用户意图、架构决策
- 对更早、多次压缩过的摘要在质量指标里加权更轻
度量
压缩风险高:在长时状态上做的有损操作。它比多数上下文工程主题都更奖励仔细测量。
要跟踪的五个信号:
| 信号 | 告诉你什么 |
|---|---|
| 压缩比 | 输入 token / 摘要 token。过高 = 过度压缩。过低 = 白干。 |
| 触发精度 | 压缩中确实需要的比例。低 = 触发太早。 |
| 压缩后回归 | 任务中途强制压缩、重放。只在压缩后失败的任务指出压缩器该保留的东西。 |
| 摘要的摘要退化 | 第 N 次再压缩时保真度怎么掉。陡的话就限制再压缩次数。 |
| 压缩成本摊销 | 摘要调用成本 ÷ 到下次压缩的轮数。决定这一层压缩是否值得其计算。 |
合成回归套件
最有价值的单一测试:保留 10-20 个历史成功的长任务。在固定和变化点强制压缩。重放。标出任何回归。
每次改压缩逻辑都跑一遍(自定义指令、触发策略、保留政策)。它抓住的问题比任何其他度量手段都多。
跨框架参考
主要框架如何暴露压缩的概览。对照业界实践做校准用,不是规定。
| 框架 | 触发方式 | 保留 | 自定义 | 多 Agent | 恢复 |
|---|---|---|---|---|---|
| Anthropic API | 固定阈值(可配) | 自动或手动 pause_after | instructions 参数 | 按会话 | compaction block + cache_control |
| Claude Code | Auto + /compact 命令 | 最近轮次 + auto memory | /compact "focus on ..." | 按会话 | Auto Memory 并行通道 |
| LangChain Deep | 自主(模型决定) | 最近 10% + middleware 规则 | 摘要 middleware | 按 Agent | 历史的虚拟文件系统 |
| OpenAI Agents | 丢弃或摘要 | 最后 N 轮原样 | 自定义摘要器函数 | 按会话 | Session 存储 |
| CrewAI | respect_context_window | summarize_messages() 分块 | 有限 | 按 Agent | 共享 memory class |
| AutoGen | 按 manager | 共享对话压缩 | Group manager 配置 | 集中式(独一份) | 委托给协调者 |
每个框架代表的设计赌注
没有框架是”最好” —— 它们反映不同的设计选择:
- AutoGen 赌协调式多 Agent —— Agent 共享上下文多时值
- LangChain 赌 Agent 判断 —— 负载可变的自主 Agent 值
- OpenAI 赌简洁 —— 两个选项(丢 / 摘),清晰心智模型
- Anthropic 赌可配置的服务端原语 —— 基础设施,不是策略
- CrewAI 赌”一个设置解决”的简洁 —— 观点化默认、无选择瘫痪
- Claude Code 赌开发者 in-the-loop ——
/compact+ 用户指令、少自主
如果你带着压缩考虑选框架,先点名哪种赌注匹配你的 Agent 形态。其他都跟着来。
相关阅读
- ← 总览 —— 回到章节枢纽。
- 上下文管理 —— 运行时纪律的其余部分:注意力预算、即时上下文、子 Agent 隔离、checkpoint。压缩是这些技术触到极限时启动的操作。
- 记忆设计 —— 结构化笔记和记忆和压缩互补:窗口之外持久的内容不需要被压缩,只需要被召回。
- 从案例到范式 → 第二部分 —— “方法在哪里触顶”点明了Agent 需要”压缩入设计”而非应急处理的时刻。
来源
- Compaction —— Anthropic, Claude API 文档(beta
compact-2026-01-12) - Automatic context compaction —— Anthropic, Claude Cookbook
- Autonomous Context Compression —— LangChain, 2026
- Context Engineering for Deep Agents —— LangChain Docs
- Context Engineering — Short-Term Memory Management with Sessions —— OpenAI Agents SDK Cookbook
- Memory — CrewAI Concepts
- Memory and RAG — AutoGen
- Effective Context Engineering for AI Agents —— Anthropic, 2026