ccgo 实现了多种 context 压缩策略,防止对话历史超出模型 context window。
触发阈值计算
internal/compact/auto_compact.go 定义关键常量:
| 常量 | 值 | 说明 |
|---|---|---|
AUTOCOMPACT_BUFFER_TOKENS | 13,000 | 自动压缩缓冲区 |
WARNING_THRESHOLD_BUFFER_TOKENS | 20,000 | 警告阈值缓冲 |
ERROR_THRESHOLD_BUFFER_TOKENS | 20,000 | 错误阈值缓冲 |
MANUAL_COMPACT_BUFFER_TOKENS | 3,000 | 手动压缩阻塞缓冲 |
MAX_OUTPUT_TOKENS_FOR_SUMMARY | 20,000 | 压缩摘要预留输出 token |
MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES | 3 | 熔断阈值 |
有效 context 窗口 = 模型 context window(200k)- 保留输出 token(min(32k, 20k))= 180,000 token
自动压缩触发点 = 有效窗口 - 13,000 buffer = 167,000 token
TokenWarningState
每次对话轮次会计算 5 个告警状态:
type TokenWarningState struct {
PercentLeft int // 剩余百分比
IsAboveWarningThreshold bool // 是否超过警告线
IsAboveErrorThreshold bool // 是否超过错误线
IsAboveAutoCompactThreshold bool // 是否触发自动压缩
IsAtBlockingLimit bool // 是否到达阻塞限制
}压缩策略分类
| 策略 | 文件 | 说明 |
|---|---|---|
auto_compact | auto_compact.go | 触发判断 + 编排逻辑 |
full_compact | full_compact.go | 全量摘要压缩 |
micro_compact | micro_compact.go | 轻量摘要(保留更多细节) |
snip_compact | snip_compact.go | 裁剪旧消息(不摘要) |
session_memory_compact | session_memory_compact.go | 利用 session memory 压缩 |
自动压缩流程
AutoCompactIfNeeded() 的执行顺序(对标 TypeScript autoCompact.ts):
1. 检查 DISABLE_COMPACT / DISABLE_AUTO_COMPACT 环境变量
2. 熔断器检查(>=3 次连续失败则跳过)
3. ShouldAutoCompact():递归保护 + threshold 检查
4. 优先尝试 session memory compact(保留结构化记忆)
5. 回退到 full compact
6. 失败则增加 ConsecutiveFailures 计数
环境变量覆盖
| 变量 | 说明 |
|---|---|
DISABLE_COMPACT | 禁用所有压缩 |
DISABLE_AUTO_COMPACT | 仅禁用自动压缩 |
CLAUDE_CODE_AUTO_COMPACT_WINDOW | 覆盖 context 窗口大小 |
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE | 按百分比覆盖自动压缩触发点 |
CLAUDE_CODE_BLOCKING_LIMIT_OVERRIDE | 覆盖阻塞限制 |
递归保护
当 querySource 为 "session_memory" 或 "compact" 时,ShouldAutoCompact() 直接返回 false,防止压缩操作自身触发压缩。
相关页面
- query-engine — 压缩在查询循环中的触发点
- session — session memory 与压缩的关系