压缩策略与分层机制
六种压缩策略的实验结果如何?
- 任务: 识别并追踪 OpenAI 联合创始人的职业状态,需多步骤信息聚合,搜索返回内容从数千到十几万字符不等;
- 环境: Kimi K3(思考模型,原生上下文约 100 万 token),刻意把预算限制到 128K 窗口以触发压缩;
- 压缩率口径: “压缩后体积 / 原文体积”,数值越小表示压得越狠;
| 策略 | 做法 | 结果 |
|---|---|---|
| 无压缩 | 完整保留所有工具结果 | 7 次调用累计约 367,000 字符(均值约 52,000);第 5 次迭代超过约 165,000 token,上下文溢出,任务失败 |
| 个体摘要 | 每个搜索结果独立生成 2-3 段摘要 | 压缩率 10.9%;完成任务但需 12 次迭代、276,608 token;信息碎片化,多页重复描述同一事件 |
| 组合摘要 | 所有结果合并后生成一份综合摘要 | 压缩率 4.3%;10 次迭代、93,449 token;输入超长时须截断,可能丢失末尾信息 |
| 上下文感知 | 把当前查询意图与已积累信息纳入压缩决策 | 7 次迭代、40,157 token,整体压缩率约 3.0%;单次把约 150K 字符压到 2K 仍保留姓名与职位变动 |
| 带引用的上下文感知 | 在智能压缩上增加信息溯源 | 每条事实附来源 URL——内容有损压缩,源链接是无损索引,可随时回溯 |
| 自适应窗口化 | 只在接近容量限制时才启动压缩 | 总 token 174,601;前几次迭代保留完整原始信息,初期信息收集灵活性最大 |
- 非任务感知的共同缺陷: 缺乏语义理解,无法区分信息相关性;
- 上下文感知的核心创新: 压缩提示中指定
Given the search query: {query}与Current context: {context},引导模型生成有针对性的摘要; - 自适应窗口化的三个机制: 阈值触发(prompt token 超过窗口 80% 才激活)、批量压缩(一次压缩全部未标记的工具结果,如超过 102,400 token 即压全部 10 条)、防重复保护(加
[COMPRESSED]标记); - 综合结论: 越贴合任务意图的压缩越省 token 且保质;越早压缩越保真但总量越大;
生产级的分层压缩包含哪五个层次?
| 层次 | 做法 | 要点 |
|---|---|---|
| 工具结果预算控制 | 大体积输出存磁盘,模型只看摘要预览 | 替换决策一旦做出即冻结,保证缓存一致 |
| 噪声直接删除 | 低价值内容(如搜索结果中只被用了几行的内容)直接移除 | 对噪声做摘要只是浪费 token |
| API 层微压缩 | 通过 API 的上下文编辑能力指示服务端从前缀移除指定工具结果,本地消息不变 | 零本地实现成本;移除点之后缓存仍失效,适合即将溢出时使用 |
| 归档式摘要 | 逐轮做结构化摘要,保留每轮独立记录 | 像 git log 而非 git squash,保留对话逻辑脉络 |
| 全量压缩 | LLM 驱动的完整压缩,最后手段 | 先压缩会话记忆,不行再做全量;配备连续失败熔断器 |
- 设计依据: 不同类型的信息有不同的保质期,压缩策略应与信息的预期生命周期匹配;
- 熔断器的必要性: 生产数据表明大量会话会被困在反复压缩失败的循环中,熔断器避免在这些会话上持续烧钱;
- 参照: 以 Claude Code 的上下文管理系统为参照;
压缩策略的设计原则有哪些?
- 信息价值的非均匀分布: 关键决策点(人员名单)高于支撑性证据(新闻细节),更高出冗余噪声(网页导航栏、页脚广告);
- 语义完整性: “Sutskever 于 2024 年 5 月离开 OpenAI”不能压成“Sutskever 离开”——时间与公司名是不可丢失的关键信息;
- 任务相关性: 同样内容在“查找创始人名单”和“了解个人背景”两个任务下应产生不同压缩结果;
- 压缩即理解: 有效压缩需要深层语义理解,负责压缩的模块本身要接近主模型的能力,形成“模型调用模型”的递归架构;
- 可审查性: 显式压缩的结果可审查、可跨会话复用;
- 投资回报: 每次压缩是一次额外 LLM 调用,但相比节省的 token 与提升的成功率回报极高——实验显示上下文感知压缩将 token 使用量减少 75% 以上;
- 易失信息: 最容易丢失的是早期的架构决策、约束背后的理由和失败的路径;
- 应对: Agent 需要定期把进展记录到文档中,而不是把所有信息零散地留在执行历史里;模型没有文档化习惯时,要用 prompt 和 skill 提醒它;
压缩策略如何按任务类型自适应?
- 检索类任务: 保留广度;
- 分析类任务: 保留深度;
- 创作类任务: 保留灵感触发点;
- 要求: 理想的 Agent 应能按任务类型主动选择压缩策略;
- 长期方向: 本篇的压缩服务于当前任务;当多次任务的轨迹需要离线整理为持久经验时,进入第九章讨论的持续进化问题;
- 落地提醒: 如果所用模型没有文档化习惯,就要通过 prompt 和 skill 来提醒它定期记录进展;
子 Agent 上下文隔离解决什么问题?
- 对比对象: 压缩是在信息已进入上下文之后做减法,隔离是让大体积中间信息根本不进入主上下文;
- 定义: 主 Agent 把“在代码库中大范围搜索”这类会产生海量中间内容的任务,委派给独立的子 Agent;
- 流程: 子 Agent 在自己的上下文中完成探索,只把几百 token 的结论性摘要回传给主 Agent;
- 实例任务: “在代码库中找到处理支付回调的函数”;
- 主 Agent 亲自搜索: 可能把十几个文件中的数万 token 原始代码纳入主上下文,绝大部分在找到目标后沦为永久占据窗口的噪声;
- 委派做法: 主上下文只增加两条消息——一条任务描述,一条结论(“函数位于 src/payment/callbacks.py 的 handle_callback,另有两处调用点”);
- 代价差异: 中间过程的数万 token 随子 Agent 的上下文一起被丢弃;
为什么说隔离优于压缩?
- 压缩的代价: 有损的、需要额外 LLM 调用的事后补救;
- 隔离的优势: 让噪声从一开始就与主上下文绝缘,主 Agent 的 KV Cache 前缀完全不受影响;
- 实现代价: 子 Agent 看不到主 Agent 的完整上下文,任务描述必须自包含、目标明确;
- 呼应主题: 上下文的质量决定能力上限,对子 Agent 同样成立;
- 生产实现: Claude Code 的 Task 工具、各类深度研究(Deep Research)系统的检索子 Agent;
- 展开: 子 Agent 作为协作工具的完整设计见第四章;多 Agent 系统的上下文架构见第十章;