跳到主要内容
OpenClaw Session 机制详解:重置、压缩、剪枝与记忆管理 | 极客日志
编程语言 Node.js AI
OpenClaw Session 机制详解:重置、压缩、剪枝与记忆管理 OpenClaw Session 机制详解重置、压缩、剪枝与记忆管理。文章通过真实踩坑案例,解析 OpenClaw 中 Session 生命周期、重置触发条件、上下文压缩策略及剪枝优化方案。重点说明 Memory Flush 与 Memory Search 如何跨会话持久化记忆,避免 AI 失忆。提供配置示例与实战协同建议,帮助用户掌握会话控制工具命令,实现高效稳定的 AI 助手部署。
孤勇者 发布于 2026/4/5 更新于 2026/4/25 4 浏览凌晨 4 点,我的 AI 悄悄把记忆清空了——OpenClaw Session 避坑指南
摘要 :用 OpenClaw 搭了个 AI 助手,聊得好的,第二天一早它就"失忆"了?本文从一个真实踩坑出发,系统拆解 OpenClaw 的 Session 机制——重置(Reset)、压缩(Compaction)、剪枝(Pruning)、记忆(Memory)、会话控制(Session Tool)——帮你彻底搞懂"对话为什么会消失"以及"怎么让 AI 记住你"。
🤯 踩坑现场
事情是这样的:
我用 OpenClaw 部署了一个私人 AI 助手,接了飞书和 Web 两个渠道。白天跟它聊了一整天的项目方案,讨论了架构设计、技术选型、排期计划……信息量巨大,我很满意。
第二天早上 9 点,我发了句"继续昨天的讨论"。
它回我:
'你好!请问有什么可以帮你的?'
整个对话历史,没了。干干净净。
我当时的表情:🫠
后来我翻了文档才明白——OpenClaw 默认在凌晨 4 点重置 Session 。不是 bug,是 feature。但如果你不了解这套机制,就会像我一样,被"设计如此"四个字暴击。
这篇文章,就是我把 OpenClaw 的 Session 体系从头到尾啃完 之后的总结。希望能帮你少走弯路。
📚 本文结构
章节 内容 解决什么问题 第 1 章 Session 基础 消息怎么找到"对的对话"? 第 2 章 Session 生命周期 什么时候开始、什么时候结束? 第 3 章 Compaction(压缩) 上下文满了怎么办? 第 4 章 Pruning(剪枝) 怎么省钱? 第 5 章 Memory(记忆) 怎么跨 Session 记住东西? 第 6 章 Session Tool 运行时怎么控制会话? 第 7 章 实战协同 五个机制怎么配合工作?
第 1 章 · Session 基础——消息怎么找到"对的对话"
核心概念:两层标识
理解 Session,先搞清楚两个东西:
┌─────────────────────────────────────────────┐
│ Session Key (路由键) │
│ → "这条消息属于哪个对话桶?" │
│ │
│ 例:agent:main:main │
│ agent:main:feishu:group :oc_xxx │
│ cron:job-123 │
│ │
│ ┌─────────────────────────────────────┐ │
│ │ Session ID(对话记录) │
│ │ → "当前这轮对话的实际文件" │
│ │ │
│ │ │
│ │ abc123.jsonl(今天的对话) │
│ │ def456.jsonl(昨天的,已归档) │
│ │ └─────────────────────────────────────┘ │
└─────────────────────────────────────────────┘
Session Key 是固定的 ,决定消息路由到哪个"桶"
Session ID 会变 ,每次重置就换一个新的 JSONL 文件
重置 ≠ 删除 ——旧 JSONL 文件还在磁盘上,只是模型不再读取
Session Key 的生成规则 来源 Key 格式 示例 私聊(默认) agent:<agentId>:<mainKey>agent:main:main群组 agent:<agentId>:<channel>:group:<id>agent:main:feishu:group:oc_xxx频道/房间 agent:<agentId>:<channel>:channel:<id>agent:main:discord:channel:123定时任务 cron:<job.id>cron:daily-reportWebhook hook:<uuid>hook:abc-def-123
私聊的 dmScope 模式 这个配置决定了不同渠道的私聊是否共享同一个 Session :
dmScope 行为 适用场景 main(默认)所有私聊共享一个 session 个人助手 per-peer按发送者隔离 多用户场景 per-channel-peer按渠道 + 发送者隔离 多渠道多用户 per-account-channel-peer按账户 + 渠道 + 发送者 多账户收件箱
💡 如果你用的是默认 main 模式,飞书私聊和 webchat 私聊会共享同一个 session 。
存储位置 ~/.openclaw/agents/<agentId>/sessions/
├── sessions.json ← Session 元数据(Key → ID 映射)
├── abc123.jsonl ← 当前对话记录
├── def456.jsonl ← 旧对话记录(重置后留下的)
└── ghi789-topic-42.jsonl ← Telegram 话题会话
第 2 章 · Session 生命周期——什么时候开始、什么时候结束
生命周期全景图 消息到达 │
▼
┌──────────────┐ 是 ┌──────────────┐
│ Session 过期? │───────→│ 创建新 Session │
│ │ │ ID + JSONL │
└──────┬───────┘ └──────┬───────┘
│ 否 │
▼ ▼
┌──────────────┐ ┌──────────────┐
│ 继续使用当前 │ │ 开始新对话 │
│ Session │ │(旧上下文丢失)│
└──────┬───────┘ └──────────────┘
│ ▼
[对话进行中] │
▼
┌──────────────┐ 是 ┌──────────────┐
│ 上下文快满了? │───────→│ Memory Flush │
│ │ │(静默写日志) │
└──────┬───────┘ └──────┬───────┘
│ 否 │
▼ ▼
[继续对话] ┌──────────────┐ │
│ Auto-Compact │ ▼
│(压缩旧内容) │
┌──────────────┐ └──────────────┘
│ 上下文溢出? │ │
│───→ 强制 Compact → 重试 └──────────────┘
三种重置触发方式
① 每日重置(默认启用) { "session" : { "reset" : { "mode" : "daily" , "atHour" : 4 } } }
⚠️ 重点来了 :不是到凌晨 4 点就立刻清空,而是下一条消息到来时才检查 。
23:00 聊天 ──→ 凌晨 4:00(重置边界)──→ 早上 9:00 发消息 ──→ 💥 新 Session!
↑ 这时候才真正重置
这就是我踩坑的根本原因 ——昨晚聊的内容,在今早第一条消息时被判定为"过期",直接创建了新 Session。
② 空闲重置(可选) { "session" : { "reset" : { "mode" : "daily" , "atHour" : 4 , "idleMinutes" : 120 } } }
③ 手动重置 发送 /new 或 /reset 立即创建新 Session:
/new claude-sonnet → 重置并切换模型
单独发 /new → 重置并发一条问候确认
按类型/渠道覆盖 { "session" : { "resetByType" : { "dm" : { "mode" : "idle" , "idleMinutes" : 480 } , "group" : { "mode" : "idle" , "idleMinutes" : 120 } , "thread" : { "mode" : "daily" , "atHour" : 4 } } , "resetByChannel" : { "discord" : { "mode" : "idle" , "idleMinutes" : 10080 } } } }
优先级 :resetByChannel > resetByType > reset(全局默认)
第 3 章 · Compaction(压缩)——上下文满了怎么办
为什么需要压缩? 每个模型有上下文窗口限制(比如 200k tokens)。聊久了,历史消息会撑满窗口。
压缩 vs 重置 压缩(Compaction) 重置(Reset) 触发 上下文快满时自动触发 到时间/手动触发 效果 旧内容变摘要,对话继续 创建全新 session,从零开始 连续性 ✅ 保留(摘要形式) ❌ 完全断开 持久化 ✅ 摘要写入 JSONL 旧 JSONL 保留但不再使用
自动压缩触发条件
溢出恢复 :模型返回上下文溢出错误 → 压缩 → 重试
阈值维护 :成功回复后检查 contextTokens > contextWindow - reserveTokens
配置 { "compaction" : { "enabled" : true , "reserveTokens" : 16384 , "keepRecentTokens" : 20000 } }
压缩后模型看到什么? ┌─────────────────────────────────┐
│ [压缩摘要] │
│ "之前讨论了 A 、B 、C 三个话题..." │
├─────────────────────────────────┤
│ [保留的最近消息] │
│ 用户:xxx │
│ 助手:xxx │
│ 用户:xxx │
│ 助手:xxx │
└─────────────────────────────────┘
💡 手动压缩:发送 /compact 即可触发,还可以附带指令,比如 /compact 重点保留关于项目架构的讨论
第 4 章 · Session Pruning(剪枝)——省钱的隐形优化
剪枝 vs 压缩 剪枝(Pruning) 压缩(Compaction) 作用对象 仅工具调用结果 整个对话历史 持久化 ❌ 不修改 JSONL ✅ 写入 JSONL 触发时机 每次 LLM 调用前 上下文快满时 目的 省钱(减少缓存重写) 腾空间
为什么需要剪枝? Anthropic 的提示缓存有 TTL(生存时间)。如果会话空闲超过 TTL,下次请求会重新缓存整个提示 ,很贵。剪枝在 TTL 过期后裁掉旧的工具结果,减少重新缓存的大小。
两个级别 工具结果(很大) │
▼
┌──────────────┐
│ 软修剪 │ 保留头尾,中间用 ... 替代 │
(Soft Trim) │
└──────┬───────┘
│ 如果还是太大 ▼
┌──────────────┐
│ 硬清除 │ 整个替换为占位符 │
(Hard Clear) │
"[Old tool result content cleared] " └──────────────┘
什么不会被剪枝?
❌ 用户消息——永不修改
❌ 助手消息——永不修改
❌ 包含图片的工具结果——跳过
❌ 最近 N 条助手消息之后的工具结果——受保护
配置 { "agent" : { "contextPruning" : { "mode" : "cache-ttl" , "ttl" : "5m" , "keepLastAssistants" : 3 , "softTrim" : { "maxChars" : 4000 , "headChars" : 1500 , "tailChars" : 1500 } , "hardClear" : { "enabled" : true , "placeholder" : "[Old tool result content cleared]" } } } }
💡 智能默认值 :如果你用的是 Anthropic 的 key,OpenClaw 会自动启用 cache-ttl 模式,不需要手动配。
第 5 章 · Memory(记忆)——跨 Session 的持久化方案
核心问题 Session 会重置、会压缩,模型的"记忆"是短暂的。Memory 系统就是解决"AI 失忆"的终极方案。
三层记忆架构 ┌─────────────────────────────────────────────┐
│ 第 1 层:Session 上下文(最短暂) │
│ · 当前对话的消息历史 │
│ · 压缩后变摘要,重置后完全丢失 │
└─────────────────────────────────────────────┘
▼ 写入文件
┌─────────────────────────────────────────────┐
│ 第 2 层:Workspace 文件(持久) │
│ · MEMORY.md — 长期记忆 │
│ · memory /YYYY-MM-DD.md — 每日日志 │
│ · AGENTS.md, SOUL.md 等 — 注入系统提示 │
└─────────────────────────────────────────────┘
▼ 语义搜索
┌─────────────────────────────────────────────┐
│ 第 3 层:Memory Search(语义检索) │
│ · 基于 Embedding 的向量搜索 │
│ · 搜索 MEMORY.md + memory /*.md │
│ · 每次新 session 启动时可自动召回相关记忆 │
└─────────────────────────────────────────────┘
Workspace 文件注入 OpenClaw 会自动把 workspace 中的特定文件注入到系统提示中:
workspace/
├── AGENTS.md ← 工作规范(自动注入)
├── SOUL.md ← 人格定义(自动注入)
├── USER.md ← 用户信息(自动注入)
├── TOOLS.md ← 工具笔记(自动注入)
├── MEMORY.md ← 长期记忆(自动注入)
├── HEARTBEAT.md ← 心跳任务(自动注入)
└── memory/
├── 2026-02-07. md ← 每日日志(需搜索读取)
└── 2026-02-08. md
⚠️ 注入的文件会占用上下文窗口!MEMORY.md 太大会挤压对话空间。
压缩前记忆刷新(Memory Flush)⭐ 最聪明的设计 上下文使用量 │
███████████████████░░░░░░ ← 软阈值(flush 触发)
████████████████████████░ ← 硬阈值(compaction 触发)
█████████████████████████ ← 上下文窗口上限
上下文接近压缩阈值(但还没到)
OpenClaw 静默运行一轮 ,让模型把重要内容写入 memory/YYYY-MM-DD.md
用户看不到这个过程
然后正常触发压缩
{ "agents" : { "defaults" : { "compaction" : { "memoryFlush" : { "enabled" : true , "softThresholdTokens" : 4000 } } } } }
⚠️ Memory Flush 的致命盲区 场景 会触发 Flush? 压缩前 ✅ 会 Session 重置前 ❌ 不会!
这就是"失忆"的根本原因 :凌晨 4 点重置时,没有任何机制把昨晚的对话写入持久记忆。对话就这么没了。
第 6 章 · Session Tool——运行时的会话控制
常用命令 命令 作用 /status查看当前 session 状态、token 用量 /new重置 session(可选指定模型:/new claude-sonnet) /compact手动压缩(可附带指令) /context list查看系统提示中注入了什么 /context detail详细查看上下文组成 /stop中止当前运行 + 清除队列 /send on/off控制消息发送策略
Send Policy(发送策略) { "session" : { "sendPolicy" : { "rules" : [ { "action" : "deny" , "match" : { "channel" : "discord" , "chatType" : "group" } } , { "action" : "deny" , "match" : { "keyPrefix" : "cron:" } } ] , "default" : "allow" } } }
第 7 章 · 实战:五个机制如何协同工作
一条消息的完整旅程 用户发送消息 │
▼
[1] Session 路由 │
根据来源生成 Session Key │
检查是否过期(每日/空闲/手动重置) │
过期 → 创建新 Session ID ▼
[2] 加载上下文 │
读取 JSONL 对话记录 │
注入 workspace 文件(MEMORY.md 等) │
如果有压缩摘要,从摘要开始 ▼
[3] Session Pruning(剪枝) │
检查缓存 TTL 是否过期 │
过期 → 裁剪旧工具结果(省钱) ▼
[4] 发送给模型 → 生成回复 ▼
[5] 回复后检查 │
接近阈值 → Memory Flush(静默写日志) │
超过阈值 → Auto-Compaction(压缩) ▼
[6] 投递回复 │
检查 Send Policy → 通过则发送 ▼
[7] 写入 JSONL + 更新 sessions.json ▼
✅ 完成
记忆保持可靠性排行 可靠性 ▲
手动写入文件 ────┤ ★★★★★ 最可靠,但需要主动操作
Memory Flush ───────┤ ★★★★ 压缩前自动触发,重置前不触发
Memory Search ──────┤ ★★★ 新 session 可召回,依赖搜索质量
Compaction 摘要 ────┤ ★★ 保留大意,丢失细节
纯靠 Session ───────┤ ★ 重置就没了
└──────────→ 自动化程度
🏆 推荐配置组合 { "session" : { "reset" : { "mode" : "daily" , "atHour" : 4 , "idleMinutes" : 480 } } , "agents" : { "defaults" : { "compaction" : { "memoryFlush" : { "enabled" : true , "softThresholdTokens" : 4000 } } , "memorySearch" : { "enabled" : true } } } }
📋 全文速查表 概念 一句话 持久化? 自动? Session Reset 创建新对话,旧上下文断开 旧 JSONL 保留 ✅ 每日/空闲 Compaction 旧对话压缩成摘要 ✅ 写入 JSONL ✅ 上下文满时 Pruning 裁剪旧工具结果省钱 ❌ 仅内存中 ✅ 每次调用前 Memory Flush 压缩前静默写日志 ✅ 写入文件 ✅ 接近阈值时 Memory Search 语义搜索历史记忆 N/A(读取) 半自动 Workspace 注入 文件内容注入系统提示 ✅ 文件本身 ✅ 每次加载
写在最后 OpenClaw 的 Session 体系设计得其实很精巧——重置保证干净、压缩保证连续、剪枝保证省钱、记忆保证持久 。但如果你不了解这套机制,就会在某个早晨被"你好,请问有什么可以帮你?"当头一棒。
相关免费在线工具 RSA密钥对生成器 生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
Mermaid 预览与可视化编辑 基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
随机西班牙地址生成器 随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online