模式矩阵 /模式白皮书/P2

P2 · Semantic Compaction · 语义压缩

字段
双轴坐标 感知 Perception × 链式 Chain(传)
成本档 ②(摘要用便宜模型即可,按阈值触发)
课程对应 02-03
目录归属 全集 33 模式之一 · 感知模块 4 模式之一
一句话 Agent 跑久了 context 装满,得压;压的时候保留什么、丢什么、保到什么程度,决定它接下来还能不能想清楚。

它解决什么问题

上下文分诊解决的是哪些信息能进 context,语义压缩解决的是后面那个问题:信息已经进来了,Agent 跑过几十轮 context 也满了,得压一压才能继续。压什么、保什么听起来像小细节,做不好代价很大——一段 487-token 的连接池耗尽 stack trace 被压成"a database error occurred"之后,Agent 不知道加大 pool、加 retry 已经被排除过,于是反复重试已被否决的方案,时间和 token 就这么烧着。

语义压缩把这件事工程化:用三层级联(清理冗长 tool 结果 → 摘要老对话 → 进一步压缩)按 context 占用阈值递进触发,每层比前一层激进。它管的是单 session 内 context window 的容量,不追求无限压缩,而追求每一段历史都由高质量推理产出,不毒化下一段。

为什么坐标是「感知 × 链式」

核心机制

压缩按 context 占用从轻到重分层触发,错误堆栈跨整个流程受保护:

层级 动作 典型压缩比
Level 1 截断 清理冗长 tool 输出(保留指针,标注可重取) ~2×
Level 2 摘要 把老对话合并进持久 anchor,不重新生成完整摘要 ~14×
Level 3 深压 老错误压成清单但保留每条核心数字,最近几条完整保留 ~30× 以上

两个机制是工业级压缩的关键。第一,触发阈值。Claude Code 默认 95% 触发,但质量退化早在 70%-80% 就开始,等到 95% 才压意味着最后那段推理本身就是低质量推理,再被压进历史会毒化整条链。社区共识是调到 60%-70% 早压,舍掉部分窗口空间换推理质量稳定。第二,持久 anchor。重新压缩每次都丢一点(像反复放大照片的颗粒),迭代合并不会丢已记住的东西。anchor 维护四个固定字段——意图、已做改动、已做决策、下一步——其中"已排除方案"这一项最关键,Agent 反复试已否决方案的根因就是缺它。

适合的生产场景

容易出错的地方

关键指标

最小骨架

should_compact(total, budget): total / budget >= 0.60   # 60% 早压
compact(turns, target):
    切分:老的可压 | 受保护(最近 N 轮 + 所有错误堆栈,永不压)
    Level 1:清理冗长 tool 输出 → 够了就返回
    Level 2:老 turns 摘要合并进 anchor(intent/changes/decisions/excluded/next)→ 够了就返回
    Level 3:老错误压成清单但留核心数字,最近 3 条完整保留
每次压缩落一条 CompactionEvent(level / 前后 token / 保留的错误堆栈数)

anchor 的"已排除方案"字段要在摘要 prompt 里写死"已排除的方案必须保留,新决策追加而非覆盖"。摘要调用用便宜模型即可。

企业落地一例

一个企业客户报了 P1 级 API 网关故障,客服 Agent 接单,会话从下午两点开始跑 4 小时、80-120 轮,context 占用爬到 150K-200K。节律按三个时点设计:约 100K(55%)第一次压缩走 Level 1 只清理冗长 tool 输出,anchor 第一次写入已做诊断和已排除方案;约 120K(67%)第二次压缩走 Level 2,老对话 verbatim 没了,anchor 成为后续唯一历史记忆;进入 SLA 倒计时区主动触发 Level 3 并 export handoff,把 anchor 加已排除方案全部导出给二线工程师。关键纪律是 Level 3 之后不再让 Agent 推理重要决策——L3 是 Agent 该退场的信号,不是再压一次的意思。这份交接单让人工客服 5 分钟就能读完接手。

与其他模式的关系

一句话记住它

好的压缩本身就是一种认知——Agent 选择保留什么,决定它接下来能想清什么;压掉一段错误堆栈,就像 refactoring 时把测试也删了,下次回归你不会知道哪里坏了。


本页属于 ADPS 33 模式白皮书。返回 模式矩阵与白皮书目录, 或查看配套 可运行代码目录