会话管理
OpenClaw 将 每个代理的一个单聊会话 视为主要会话。单聊会折叠为agent:<agentId>:<mainKey>(默认是 main),而群聊/频道聊天则拥有各自的键名。session.mainKey 会被遵循。
使用 session.dmScope 控制 私信 如何分组:
main(默认):所有私信共享主会话,确保连续性。per-peer:按发送者 ID 隔离,不同渠道独立。per-channel-peer:按频道 + 发送者隔离(推荐用于多用户收件箱)。per-account-channel-peer:按账号 + 频道 + 发送者隔离(推荐用于多账号收件箱)。 使用session.identityLinks映射带有提供方前缀的对端 ID 到规范身份,这样相同的人在使用per-peer、per-channel-peer或per-account-channel-peer时可以跨频道共享私信会话。
安全私信模式(推荐用于多用户场景)
安全警告: 如果你的代理可以接收来自 多个用户 的私信,强烈建议启用安全私信模式。否则,所有用户共享相同的对话上下文,可能导致私人信息在用户间泄露。默认设置下的问题示例:
- Alice(
<SENDER_A>)给代理发送了一个私密话题信息(例如,医疗预约) - Bob(
<SENDER_B>)给代理发送消息:“我们之前在谈什么?” - 因为两条私信共享同一会话,模型可能会用 Alice 的上下文来回答 Bob。
dmScope,按用户隔离会话:
- 你允许多个发送者配对批准
- 你使用包含多个条目的私信允许列表
- 你设置了
dmPolicy: "open" - 多个电话号码或账号可向代理发送消息
- 默认是
dmScope: "main"以保证连续性(所有私信共享主会话),适用于单用户场景。 - 本地 CLI 上线时,未设置时默认写入
session.dmScope: "per-channel-peer",(已有显式配置会保留)。 - 同频道多账号收件箱建议使用
per-account-channel-peer。 - 同一人跨多个频道联系时,使用
session.identityLinks将其私信会话合并为一个规范身份。 - 你可以用
openclaw security audit验证私信设置(详见 安全)。
Gateway 是唯一数据源
所有会话状态由 网关(“master” OpenClaw) 负责。UI 客户端(macOS 应用、网页聊天等)必须向网关查询会话列表和令牌统计,不能直接读取本地文件。- 在远程模式下,你关心的会话存储位于远程网关主机而非本机。
- UI 显示的令牌数来自网关存储字段(
inputTokens、outputTokens、totalTokens、contextTokens),客户端不会解析 JSONL 转录文件来“修正”统计。
状态存储位置
- 在网关主机:
- 存储文件为:
~/.openclaw/agents/<agentId>/sessions/sessions.json(每个代理单独存储)。
- 存储文件为:
- 转录文件位于:
~/.openclaw/agents/<agentId>/sessions/<SessionId>.jsonl(Telegram 主题会话用.../<SessionId>-topic-<threadId>.jsonl的格式)。 - 存储是一个映射表:
sessionKey -> { sessionId, updatedAt, ... },删除条目是安全的,缺少时会根据需要重建。 - 群组条目可能包含
displayName、channel、subject、room、space用于 UI 显示标签。 - 会话条目包含
origin元数据(标签和路由提示),便于 UI 解释会话来源。 - OpenClaw 不会 读取传统的 Pi/Tau 会话文件夹。
维护机制
OpenClaw 会执行会话存储维护,确保sessions.json 和转录文件随时间保持合理大小。
默认值
session.maintenance.mode:warnsession.maintenance.pruneAfter:30dsession.maintenance.maxEntries:500session.maintenance.rotateBytes:10mbsession.maintenance.resetArchiveRetention: 默认为pruneAfter(30 天)session.maintenance.maxDiskBytes: 未设置(禁用)session.maintenance.highWaterBytes: 如果启用磁盘配额,默认为maxDiskBytes的 80%
运作方式
维护在写入会话存储时运行,你也可以用openclaw sessions cleanup 手动触发。
mode: "warn":报告将被清理的项,但不修改条目或转录。mode: "enforce":按顺序执行清理:- 剪除比
pruneAfter更旧的条目 - 限制条目数至
maxEntries(先删最旧的) - 归档已移除条目且不再引用的转录文件
- 根据保留策略清理旧的
*.deleted.<timestamp>和*.reset.<timestamp>归档 - 当
sessions.json超过rotateBytes时轮转 - 如果设置了
maxDiskBytes,朝highWaterBytes软限制清理(先删除最旧文件,再删除最旧会话)
- 剪除比
大型存储性能注意
高流量场景中,存储规模常很大。维护是在写入时执行,存储越大写入延迟可能越高。 主要增加成本因素:session.maintenance.maxEntries设得过高- 过长的
pruneAfter保留了太多陈旧条目 ~/.openclaw/agents/<agentId>/sessions/中积累大量转录和归档文件- 启用磁盘配额(
maxDiskBytes)却未合理设定剪枝或条目数限制
- 生产环境使用
mode: "enforce"保证增长自动受控 - 同时配置时间和条目数限制(
pruneAfter和maxEntries) - 对大规模部署,设定
maxDiskBytes和highWaterBytes以硬限制上限 - 保持
highWaterBytes明显低于maxDiskBytes(默认约 80%) - 配置调整后,用
openclaw sessions cleanup --dry-run --json预览效果 - 对于频繁活跃会话,手动清理时使用
--active-key
自定义示例
采用保守的 enforce 策略:会话剪枝
OpenClaw 默认会在调用 LLM 之前,从内存上下文中修剪 旧的工具结果。 这不会重写 JSONL 历史。详见 /concepts/session-pruning。预压缩内存刷新
当会话接近自动压缩时,OpenClaw 可运行静默内存刷新回合,提醒模型将持久笔记写入磁盘。此功能仅在工作区可写时启用。详见 内存 和 压缩。传输 → 会话键映射
- 单聊依照
session.dmScope(默认main):main:agent:<agentId>:<mainKey>(跨设备/频道连续性)。- 多个电话号码和频道可以映射到同一个代理主键,作为进入同一会话的不同传输渠道。
per-peer:agent:<agentId>:dm:<peerId>。per-channel-peer:agent:<agentId>:<channel>:dm:<peerId>。per-account-channel-peer:agent:<agentId>:<channel>:<accountId>:dm:<peerId>(accountId 默认为default)。- 如果
session.identityLinks匹配带提供方前缀的对端 ID(如telegram:123),则用规范键替换<peerId>,实现跨频道会话共享。
- 群聊隔离状态:
agent:<agentId>:<channel>:group:<id>(房间/频道用agent:<agentId>:<channel>:channel:<id>)。- Telegram 论坛主题通过附加
:topic:<threadId>区分。 - 仍支持旧版
group:<id>键名用于迁移。
- Telegram 论坛主题通过附加
- 入站上下文可能仍用
group:<id>,频道从Provider推断并规范为agent:<agentId>:<channel>:group:<id>形式。 - 其他来源:
- 定时任务:
cron:<job.id> - Webhook:
hook:<uuid>(除非由 webhook 明确设置) - 节点运行:
node-<nodeId>
- 定时任务:
生命周期
- 重置策略:会话复用直到过期,过期在下一条入站消息时评估。
- 每日重置:默认本地时间 每天凌晨 4 点(网关主机时间)。如果会话最后更新早于最近一次每日重置时间,则视为过时。
- 空闲重置(可选):
idleMinutes添加滑动空闲窗。当同时配置每日和空闲重置,以先到期者为准,强制新建会话。 - 兼容旧空闲模式:仅设置
session.idleMinutes而无session.reset/resetByType配置时,保持仅空闲超时模式。 - 各类型重置覆盖(可选):
resetByType覆盖direct、group和thread(Slack/Discord 线程,Telegram 主题,Matrix 线程由连接器提供)三种会话的重置策略。 - 频道重置覆盖(可选):
resetByChannel针对频道覆盖重置策略(适用于该频道的所有会话类型,优先于reset/resetByType)。 - 重置触发词:精确匹配
/new或/reset(以及resetTriggers中的额外命令)可开启新会话 ID 且余下消息继续处理。/new <model>可指定模型别名、provider/model或提供商名称(模糊匹配)作新会话模型。如果只发/new或/reset,OpenClaw 会发送简短“你好”确认重置。 - 手动重置:删除指定键或移除 JSONL 转录文件,下一条消息会重建它们。
- 隔离定时任务每次运行均新建会话 ID(不复用空闲会话)。
发送策略(可选)
可阻止特定会话类型的消息发送,无需列出具体 ID。/send on→ 允许该会话发送/send off→ 禁止该会话发送/send inherit→ 清除覆盖,使用配置规则
配置示例(可选重命名)
查看状态
openclaw status— 显示存储路径及近期会话。openclaw sessions --json— 导出所有条目(可用--active <分钟数>过滤)。openclaw gateway call sessions.list --params '{}'— 从运行中的网关获取会话(远程访问需--url/--token)。- 在聊天中单独发送
/status查看代理是否在线,会话上下文使用情况,当前思考/详细模式切换及 WhatsApp Web 凭证刷新时间(便于判断是否需重新关联)。 - 发送
/context list或/context detail查看系统提示和注入的工作区文件内容(及最大上下文贡献者)。 - 发送
/stop(或单独中止指令,如stop、stop action、stop run、stop openclaw)以中止当前运行,清除该会话的待办后续消息,并停止所有由该会话派生的子代理运行(回复中会显示停止计数)。 - 发送
/compact(可附加指令)作为独立消息,汇总老旧上下文并释放窗口空间。详情见 /concepts/compaction。 - 可直接打开 JSONL 转录文件回顾完整对话回合。
小贴士
- 保持主键专用于一对一聊天,群聊保留独立键。
- 自动清理时推荐删除单个键而非整份存储,以保留其他上下文。
会话来源元数据
每条会话记录以origin 字段(尽量准确)记录来源:
label:人工标签(从对话标签 + 群主题/频道解析)provider:标准化频道 ID(包含扩展)from/to:入站信封中的原始路由 IDaccountId:提供商账号 ID(多账号时)threadId:支持时的线程/主题 ID
ConversationLabel、GroupSubject、GroupChannel、GroupSpace 和 SenderName 并调用 recordSessionMetaFromInbound(或将相同上下文传递给 updateLastRoute)实现。