最近我在用 OpenClaw 的时候遇到一个问题:第一天和它聊了很久,第二天让它把昨天的讨论内容保存下来,结果它完全不记得之前聊了什么。一开始我以为是记忆管理(Memory)出了问题,排查了一圈才发现,根本不是记忆的事——是会话(Session)被自动重置了,上下文早就清空了。
如果你也在用 OpenClaw,遇到过类似的困扰,可以试试下面这套方法。我花了时间把会话管理的机制彻底搞清楚了,今天分享给你。
先说结论
OpenClaw 默认每天凌晨 4 点自动重置会话。如果你想第二天接着昨天的对话继续聊,最简单的方法是执行一行命令:
openclaw config set session.reset.atHour -1这样会话就不会因为时间到了而被自动清空,直到你手动发送 /new 或 /reset 才会重置。
如果你还是希望有某种超时机制(防止会话无限膨胀),可以设置一个较长的空闲超时:
openclaw config set session.reset.mode idle
openclaw config set session.reset.idleMinutes 43204320 分钟 = 3 天。3 天不聊天才会自动重置。
OpenClaw 的会话是怎么管理的
两层存储
OpenClaw 把会话数据存在两个地方:
- 1. sessions.json — 一个轻量级的索引文件,记录每个会话的元数据(会话 ID、最后活跃时间、token 用量、用户偏好等)
- 2. transcript 文件(.jsonl) — 按会话 ID 命名的 JSONL 文件,逐行追加,存储完整的对话记录(包括工具调用、压缩摘要等)
这些文件都在 ~/.openclaw/agents/<agentId>/sessions/ 目录下。
会话什么时候会被重置
OpenClaw 有三种会话重置机制,取先到者生效:
| 机制 | 配置项 | 默认值 | 说明 |
|---|---|---|---|
| 每日重置 | session.reset.atHour | 4(凌晨 4 点) | 每天到了这个时间,下次发消息会创建新会话 |
| 空闲超时 | session.reset.idleMinutes | 未设置 | 超过指定分钟没活动,下次发消息创建新会话 |
| 手动重置 | 在聊天中输入 | /new 或 /reset | 立即创建新会话 |
这里有个关键细节:重置是懒评估的。不是到了凌晨 4 点就立刻清空,而是到了 4 点之后你发的第一条消息才会触发新会话创建。在那之前,旧会话一直保留着。
另外,系统事件(心跳检测、定时任务、执行事件)永远不会触发会话重置,不用担心后台活动把你的对话冲掉。
会话路由规则
不同来源的消息会被路由到不同的会话:
| 来源 | 行为 |
|---|---|
| 私聊(DM) | 默认所有私聊共享一个会话 |
| 群聊 | 每个群一个独立会话 |
| 论坛话题 | 每个话题一个独立会话 |
| 定时任务 | 每次运行一个临时会话 |
| Webhook | 每个 hook 一个独立会话 |
如果你的机器人有多个用户同时私聊,建议开启 DM 隔离:
{
session: {
dmScope: "per-channel-peer"
}
}上下文窗口是怎么管理的
这是一个很多人关心的问题:每次对话时,模型能看到多少历史消息?
答案:不是固定条数,而是动态 token 预算
OpenClaw 不使用"保留最近 N 条消息"这种简单粗暴的方式。它基于 token 预算动态管理上下文,核心机制叫做 Compaction(压缩)。
工作原理是这样的:
- 1. 每次发消息前,OpenClaw 会估算当前上下文的总 token 数(历史对话 + 系统提示 + 新消息)
- 2. 如果估算结果接近模型的上限(比如 Claude 的 200K token),就会先执行压缩
- 3. 压缩不是简单截断,而是用模型对历史对话进行摘要总结
- 4. 摘要会保留关键信息(UUID、链接、API Key 等标识符原样保留),丢弃冗余细节
压缩的触发时机
| 触发方式 | 说明 |
|---|---|
| 发送前检查 | 每次发消息前估算 token,超限则先压缩 |
| 溢出恢复 | 模型返回"上下文太长"错误时自动压缩重试(最多 3 次) |
| 阈值维护 | 成功回复后,如果 token 用量超过 窗口大小 - 16384,后台自动压缩 |
| 超时保护 | 模型响应超时且上下文很大时,压缩后重试 |
| 手动触发 | 聊天中发送 /compact |
压缩前的记忆保存
这个设计很贴心:在自动压缩之前,OpenClaw 会先静默执行一次"记忆刷写"(Memory Flush),让 agent 把重要信息保存到持久化记忆中。这样即使上下文被压缩了,关键信息也不会丢失。
下次新会话开始时,如果启用了 Active Memory 插件(2026.4.12 新增),agent 会在回复前自动从记忆中拉取相关上下文。
关键配置参数
{
agents: {
defaults: {
// 自定义上下文窗口大小(默认跟随模型本身的窗口)
contextTokens: 200000,
compaction: {
// 预留空间,上下文用到离上限差这么多 token 时触发压缩
reserveTokens: 16384,
// 压缩时保留最近多少 token 的原始对话不参与摘要
keepRecentTokens: 20000,
// 压缩前是否自动保存记忆
memoryFlush: {
enabled: true
}
}
}
}
}会话被重置了怎么办
即使会话被重置,你也不必担心重要信息丢失。OpenClaw 有多层保护:
- 1. Memory Flush — 压缩前自动保存关键信息到持久记忆
- 2. Active Memory — 新会话开始时自动从记忆中拉取相关上下文
- 3. Compaction Checkpoint — 每次压缩保存检查点,最多 25 个,支持回滚
- 4. Transcript 归档 — 被重置的会话文件重命名为
*.reset.<时间戳>,不会立即删除
配置速查表
| 场景 | 配置 |
|---|---|
| 永不自动重置 | session.reset.atHour: -1 |
| 3 天不聊天才重置 | session.reset.mode: "idle", session.reset.idleMinutes: 4320 |
| 保持默认每天重置 | 无需配置(默认行为) |
| 多用户隔离 | session.dmScope: "per-channel-peer" |
| 增大上下文窗口 | agents.defaults.contextTokens: 200000 |
| 手动压缩当前对话 | 聊天中发送 /compact |
| 手动重置会话 | 聊天中发送 /new |
会话生命周期一览
创建会话
│
├─ 收到消息 → 追加到 transcript → 更新 token 计数
│
├─ 上下文增长 → 接近窗口上限
│ ├─ Memory Flush(静默保存重要信息到持久记忆)
│ ├─ Compaction(多阶段摘要压缩历史对话)
│ └─ 保存 Checkpoint(支持回滚)
│
├─ 触发重置(/new | 每日 | 空闲超时)
│ ├─ 旧 transcript 归档为 *.reset.<时间戳>
│ ├─ 触发 session_end 插件钩子
│ └─ 创建新会话 + 触发 session_start 插件钩子
│
└─ 定期清理
├─ 过期条目修剪(默认 30 天)
├─ 条目数量上限(默认 500)
└─ 磁盘空间预算执行一句话总结:OpenClaw 不使用固定消息条数窗口,而是基于 token 预算动态管理上下文。上下文增长到接近模型窗口上限时自动压缩(summarize)历史对话,压缩前先保存重要记忆,整个过程对用户透明。
写在最后
如果你也在用 OpenClaw 或类似的 AI Agent 工具,希望这篇文章帮你省去了翻源码翻文档的时间。会话管理看起来是个小问题,但直接影响你每天和 AI 协作的效率——别让"重新解释背景"成为你的日常。
试试文中的配置,找到最适合你的会话策略。如果你在配置过程中遇到问题,或者有更好的实践方案,欢迎在评论区聊聊。
AI 时代,一起成为 Builder。
夜雨聆风