会话管理与压缩(深入了解)
本文档解释 OpenClaw 如何端到端管理会话:
- 会话路由(入站消息如何映射到
sessionKey) - 会话存储(
sessions.json)及其跟踪的内容 - 记录持久化(
*.jsonl)及其结构 - 记录清理(运行前的提供商特定修复)
- 上下文限制(上下文窗口 vs 跟踪的 token 数)
- 压缩(手动 + 自动压缩)以及在何处挂接压缩前工作
- 静默内务处理(例如不应产生用户可见输出的记忆写入)
如果你想先了解更高层次的概述,请从以下内容开始:
事实来源:Gateway 网关
OpenClaw 围绕一个拥有会话状态的单一 Gateway 网关进程设计。
- UI(macOS 应用、web 控制 UI、TUI)应该向 Gateway 网关查询会话列表和 token 计数。
- 在远程模式下,会话文件在远程主机上;"检查你的本地 Mac 文件"不会反映 Gateway 网关正在使用的内容。
两个持久化层
OpenClaw 在两个层中持久化会话:
-
会话存储(
sessions.json)- 键/值映射:
sessionKey -> SessionEntry - 小型、可变、可安全编辑(或删除条目)
- 跟踪会话元数据(当前会话 ID、最后活动时间、开关、token 计数器等)
- 键/值映射:
-
记录(
<sessionId>.jsonl)- 具有树形结构的仅追加记录(条目有
id+parentId) - 存储实际对话 + 工具调用 + 压缩摘要
- 用于为后续回合重建模型上下文
- 具有树形结构的仅追加记录(条目有
磁盘上的位置
在 Gateway 网关主机上,每个智能体:
- 存储:
~/.openclaw/agents/<agentId>/sessions/sessions.json - 记录:
~/.openclaw/agents/<agentId>/sessions/<sessionId>.jsonl- Telegram 话题会话:
.../<sessionId>-topic-<threadId>.jsonl
- Telegram 话题会话:
OpenClaw 通过 src/config/sessions.ts 解析这些位置。
会话键(sessionKey)
sessionKey 标识你所在的哪个对话桶(路由 + 隔离)。
常见模式:
- 主要/直接聊天(每个智能体):
agent:<agentId>:<mainKey>(默认main) - 群组:
agent:<agentId>:<channel>:group:<id> - 房间/频道(Discord/Slack):
agent:<agentId>:<channel>:channel:<id>或...:room:<id> - 定时任务:
cron:<job.id> - Webhook:
hook:<uuid>(除非被覆盖)
规范规则记录在 /concepts/session。
会话 ID(sessionId)
每个 sessionKey 指向一个当前的 sessionId(继续对话的记录文件)。
经验法则:
- 重置(
/new、/reset)为该sessionKey创建一个新的sessionId。 - 每日重置(默认 Gateway 网关主机本地时间凌晨 4:00)在重置边界后的下一条消息时创建一个新的
sessionId。 - 空闲过期(
session.reset.idleMinutes或旧版session.idleMinutes)当消息在空闲窗口后到达时创建一个新的sessionId。当同时配置了每日和空闲时,以先过期者为准。
实现细节:决策发生在 src/auto-reply/reply/session.ts 的 initSessionState() 中。
会话存储模式(sessions.json)
存储的值类型是 src/config/sessions.ts 中的 SessionEntry。
关键字段(不完整):
sessionId:当 前记录 ID(文件名从此派生,除非设置了sessionFile)updatedAt:最后活动时间戳sessionFile:可选的显式记录路径覆盖chatType:direct | group | room(帮助 UI 和发送策略)provider、subject、room、space、displayName:群组/频道标签的元数据- 开关:
thinkingLevel、verboseLevel、reasoningLevel、elevatedLevelsendPolicy(每会话覆盖)
- 模型选择:
providerOverride、modelOverride、authProfileOverride
- Token 计数器(尽力而为/依赖提供商):
inputTokens、outputTokens、totalTokens、contextTokens
compactionCount:此会话键完成自动压缩的次数memoryFlushAt:最后一次压缩前记忆刷新的时间戳memoryFlushCompactionCount:最后一次刷新运行时的压缩计数
存储可以安全编辑,但 Gateway 网关是权威:它可能会在会话运行时重写或重新水合条目。
记录结构(*.jsonl)
记录由 @mariozechner/pi-coding-agent 的 SessionManager 管理。
文件是 JSONL 格式:
- 第一行:会话头(
type: "session"