跳转到内容

04 — 上下文压缩:Token 阈值与前缀缓存优化

上下文压缩:Token 阈值与前缀缓存优化

学习目标

理解 CodeWhale 的上下文压缩策略:纯 Token 触发机制、前缀缓存经济学驱动的自动地板设计,以及手动与自动压缩的协同。

前置知识

下文假设你已理解上述概念,直接聚焦 CodeWhale 的具体实现。

项目实践

压缩配置结构

CompactionConfig {
enabled: bool, // 是否启用(默认 true)
token_threshold: usize, // Token 阈值(触发压缩)
model: String, // 压缩使用的模型
cache_summary: bool, // 是否缓存摘要
auto_floor_tokens: usize, // 自动压缩地板(最低 Token 数)
}

纯 Token 触发(v0.8.11 改进)

在 v0.8.11 之前,压缩由两个条件触发:Token 数 消息数。v0.8.11 移除了消息计数触发器,原因是:

“消息计数触发器的唯一目的是在长会话小消息场景触发压缩,而这恰恰是重写 V4 前缀缓存最不划算的场景。”

改进后的触发逻辑

  1. 检查总 Token 数是否 ≥ auto_floor_tokens(默认 500K)
  2. 若通过地板检查,检查是否 ≥ token_threshold
  3. 两者都通过才触发压缩

前缀缓存经济学:500K 自动地板

这是 CodeWhale 最独特的压缩设计。

为什么是 500K?

压缩会重写稳定的前缀——这会破坏 KV 前缀缓存。在低 Token 数时:

  • 前缀缓存命中率高,大部分 tokens 以缓存命中价格计费
  • 压缩导致缓存 miss,全量重新填充以 miss 价格计费
  • 压缩回收的少量 Token 预算不足以抵消 miss 的成本

高于 500K 时情况反转:

  • 缓存已受压,命中率下降
  • 前缀已漂移(动态内容累积导致缓存边界后移)
  • 回收预算变得重要

手动 vs 自动压缩

维度自动压缩手动 /compact
触发条件Token 数 ≥ threshold 且 ≥ floor用户显式请求
绕过地板
使用模型配置中的 compaction.model当前活跃模型
适用场景长会话自动维护用户主动管理上下文

每模型阈值

不同模型的上下文窗口不同,压缩阈值也不同:

模型上下文窗口自动压缩阈值(80%)
deepseek-v4-pro1M800K
deepseek-v4-flash1M800K
未知模型回退 128K102.4K(80%)

60% 时 TUI 会建议 /compact,但自动替换压缩在 80% 时才触发——这是一个”建议早、行动晚”的策略。

问题与规避

陷阱:自动压缩在不该触发时触发

当会话包含大量工具输出(低信息密度)时,Token 数可能很快达到阈值,但实际有用的上下文并不多。

规避:CodeWhale 的 500K 地板防止了低 Token 数场景下的误触发。此外,压缩策略可以选择保留关键消息(系统提示、最近交互)而丢弃中间工具输出。

陷阱:压缩导致前缀缓存全量失效

压缩重写前缀——如果 Constitution 等稳定内容被包含在压缩后的摘要中,下次 turn 需要全量冷读。

规避:CodeWhale 的压缩策略区分”稳定前缀”(Constitution,不应被压缩)和”可变内容”(对话历史,可以压缩)。压缩只替换可变部分。

陷阱:未知模型的阈值过高

如果连接到一个 32K 窗口的模型,默认的 800K 阈值永远不会触发。

规避:CodeWhale 使用 context_window_for_model() 函数动态获取模型窗口大小,未知模型回退到 128K 的 80%(102.4K)。对于更小的模型,配置需要手动调整。

设计取舍

为什么从消息计数改为纯 Token

消息计数是 128K 时代的启发式——当时窗口小,消息数量是合理的代理。1M 窗口时代:

  • 小消息长会话(如 1000 条短消息)可能只有 50K tokens
  • 压缩这些会话会破坏健康的前缀缓存,回收的预算微乎其微
  • Token 数是更准确的缓存压力信号

自动压缩默认关闭(v0.8.11)

虽然 CompactionConfig 的默认 enabled: true,但引擎级的 auto_compact 设置在 v0.8.11 被翻转为 OFF。原因是:

  • 自动替换压缩重写前缀,用户可能不希望自动发生
  • 手动 /compact 给用户更精细的控制
  • 60% 的建议仍然有效,用户可以自主决定时机

参考来源

  • crates/tui/src/compaction.rs — 压缩配置与触发逻辑
  • v0.8.11 CHANGELOG 条目 #665 — 自动压缩默认关闭