概述
Compaction 是 OpenClaw 在会话接近模型上下文窗口限制时,将旧消息摘要化以便对话继续的机制。摘要持久化写入 session transcript,完整历史始终保留在磁盘。
触发时机
自动触发(两种情况)
1. Overflow 恢复:模型返回 context overflow 错误时,立即压缩并重试。
识别的错误签名:
request_too_largecontext length exceededinput exceeds the maximum number of tokensinput token count exceeds the maximum number of input tokensinput is too long for the modelollama error: context length exceeded
2. 阈值维护:一次成功 turn 结束后,当:
contextTokens > contextWindow - reserveTokens
contextWindow:模型上下文窗口大小reserveTokens:为提示词和下一次模型输出预留的 headroom(默认 floor 20000 tokens)
3. 文件大小守卫(可选):当 maxActiveTranscriptBytes 设置且 active transcript 文件达到该大小时,在下一次 turn 开始前触发本地压缩(需同时开启 truncateAfterCompaction)。
4. 中途预检(可选,默认关闭):midTurnPrecheck.enabled: true 时,在工具结果追加后、下一次模型调用前估算 prompt 压力,若不够则中止当前提交并触发压缩重试。
手动触发
/compact
/compact Focus on the API design decisions
手动压缩若设置了 keepRecentTokens,会保留最近 tail;否则作为硬检查点,从新摘要重新开始。
压缩流程
触发压缩
│
├─ [可选] Memory Flush(静默 turn,写记忆文件)
│
├─ 分割 transcript 为压缩块
│ └─ 保持 tool call + toolResult 配对(不拆散)
│
├─ LLM 摘要旧对话(或调用自定义 provider)
│
├─ 写入 compaction 条目到 transcript(含 firstKeptEntryId + tokensBefore)
│
└─ [若 truncateAfterCompaction] 创建新的 successor transcript
└─ 旧 transcript 归档为 checkpoint
压缩后,后续 turn 看到的是:
- 压缩摘要
firstKeptEntryId之后的消息(保持完整)
Memory Flush(压缩前记忆写入)
压缩前,OpenClaw 会运行一个静默 turn,提醒 Agent 把重要上下文写入记忆文件,防止上下文丢失。
工作机制:
- 监控 session 上下文用量
- 达到”软阈值”(低于 Pi 压缩阈值)时,向 Agent 发送静默”立即写记忆”指令
- 使用
NO_REPLYtoken 抑制输出,用户不可见 - 每个压缩周期只运行一次(通过
sessions.json中memoryFlushAt追踪)
跳过条件:
- CLI backend(非嵌入式 Pi session)
- workspace 为只读(
workspaceAccess: "ro"或"none")
配置项(agents.defaults.compaction.memoryFlush):
| 配置项 | 默认值 | 说明 |
|---|---|---|
enabled | true | 是否开启 |
model | 继承会话模型 | 指定 flush turn 使用的模型(精确,不继承 fallback chain) |
softThresholdTokens | 4000 | 触发 flush 的软阈值(距压缩阈值的 headroom) |
prompt | 内置 | flush turn 的用户消息 |
systemPrompt | 内置 | flush turn 的额外系统提示 |
Successor Transcript(后继 transcript)
开启 truncateAfterCompaction: true 后,压缩不再原地重写 transcript,而是:
- 从压缩摘要 + 保留状态 + 未摘要 tail 创建新的 active successor transcript
- 旧 transcript 保留为归档 checkpoint
额外效果:successor transcript 会去除短重试窗口内的重复长用户 turn,防止 channel 重试风暴被带入下一个 active transcript。
注意:
maxActiveTranscriptBytes文件大小守卫需要truncateAfterCompaction: true才能生效。
标识符保留策略
压缩摘要默认保留不透明标识符(identifierPolicy: "strict")。
| 值 | 行为 |
|---|---|
"strict"(默认) | 保留所有 ID、哈希、配置键等 |
"off" | 不做特殊处理 |
"custom" | 配合 identifierInstructions 自定义 |
可插拔压缩 Provider
插件可通过 registerCompactionProvider() 注册自定义压缩 provider:
{
"agents": {
"defaults": {
"compaction": {
"provider": "my-provider"
}
}
}
}- 设置
provider会自动强制mode: "safeguard" - Provider 失败或返回空结果时,自动回退到内置 LLM 摘要
- Abort/timeout 信号会重新抛出(不吞掉),尊重调用方取消
Safeguard 模式默认开启摘要质量审计(qualityGuard.enabled: true),可设为 false 跳过。
完整配置参考
{
agents: {
defaults: {
compaction: {
// 压缩模型(不设则用会话模型)
model: "openrouter/anthropic/claude-sonnet-4-6",
// 标识符保留策略
identifierPolicy: "strict",
// 压缩前 memory flush
memoryFlush: {
enabled: true,
model: "ollama/qwen3:8b", // 可选:用本地模型做 flush
softThresholdTokens: 4000
},
// 后继 transcript(防止文件无限增长)
truncateAfterCompaction: true,
// 文件大小守卫(需 truncateAfterCompaction: true)
maxActiveTranscriptBytes: "20mb",
// 中途预检(默认关闭)
midTurnPrecheck: { enabled: false },
// 保留最近 N tokens(手动 /compact 时生效)
keepRecentTokens: 20000,
// reserveTokens 安全 floor(默认 20000)
reserveTokensFloor: 20000,
// 压缩时通知用户
notifyUser: false,
// 自定义 provider(设置后强制 safeguard 模式)
provider: "my-provider"
}
}
}
}Compaction vs Pruning
| Compaction | Session Pruning | |
|---|---|---|
| 做什么 | 摘要旧对话 | 裁剪旧工具结果 |
| 是否持久化 | 是(写入 transcript) | 否(仅内存,per-request) |
| 范围 | 整个对话 | 仅工具结果 |
| 触发时机 | 接近 context limit | 每次 LLM 调用前 |
| 互补关系 | 两者互补:Pruning 减少工具输出膨胀,延缓 Compaction 触发 |
可观测性
# CLI 状态
openclaw status # 显示 Compactions: <count>
openclaw sessions --json # 查看 compactionCount 字段
# 日志(verbose 模式)
# 🧹 Auto-compaction complete
# embedded run auto-compaction start / complete
# 会话内
/status # 上下文用量、压缩次数sessions.json 中的相关字段:
compactionCount:该 session key 的自动压缩次数memoryFlushAt:最近一次 memory flush 的时间戳memoryFlushCompactionCount:最近一次 flush 时的压缩计数
常见问题
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 压缩太频繁 | 模型 context window 小 / 工具输出大 | 启用 session pruning |
| 压缩后上下文感觉陈旧 | 摘要丢失细节 | /compact Focus on <topic> 或启用 memory flush |
| 需要全新开始 | — | /new 开启新 session(不压缩) |
reserveTokens 过高 | 导致比必要更早触发压缩 | 调低 reserveTokensFloor 或检查模型 context window |
| Silent turn 泄漏 | NO_REPLY token 未正确抑制 | 确认构建版本包含流式抑制修复 |
相关页面
- session-pruning — 工具结果裁剪(轻量级补充,与 Compaction 互补)
- memory — Memory 持久化与 flush 机制
- context — 上下文构建机制
- context-engine — 可插拔上下文引擎
- session — 会话管理与生命周期