最近我碰到一个很典型的坑。
配置里明明已经写了:
"sources": ["memory", "sessions"]按直觉看,这事应该已经成了。结果一查运行时状态,真正生效的 source 只有一个:memory。
如果你也遇到过这种情况,先别怀疑自己,也别急着怀疑索引坏了。这个坑不是表面配置的问题,而是 OpenClaw 现在对 session transcript memory 还多了一层开关。
这篇就把这个问题一次讲透。
一、这个坑最容易怎么出现
最常见的表象是下面这样:
1. 你已经在配置里加了 sessions2. memorySearch.enabled = true3. openclaw memory status也能正常返回4. embeddings、vector、FTS 看起来都正常 5. 但运行时 sources 还是只有 memory
也就是说,系统不是坏了,而是看起来像开了,实际上没真开。
这种问题最烦的地方在于,它不会立刻报一个很明显的错。你会以为 session memory 已经接进来了,结果后面去搜历史对话时,总觉得哪里不对。
二、真正的根因,不在 sources
这个坑的关键点在于:
不是唯一条件。
在当前版本里,sessions 能不能真的进入 memorySearch,还取决于另一个配置:
"agents": {
"defaults": {
"memorySearch": {
"enabled":true,
"sources": ["memory", "sessions"],
"provider": "local",
"fallback": "none",
"experimental": {
"sessionMemory":true
}
}
}
}真正容易漏掉的是这一段:
"experimental": {
"sessionMemory":true
}如果这个开关没开,运行时会把 sessions 静默过滤掉。
所以问题的本质不是“你有没有写 sessions”,而是“你有没有同时打开 experimental.sessionMemory”。
三、为什么很多人会误判
因为从人的直觉来说,sources 就是“数据源列表”。
既然我已经明确写了 sessions,系统就应该把它用起来。这种理解非常自然。
但 OpenClaw 当前的逻辑更像两层:
• sources决定你想要哪些源• experimental.sessionMemory决定sessions这个源能不能真正放行
所以你会看到一种很迷惑的状态:
• 配置看着没问题 • memory 服务也正常 • embeddings 也正常 • 但 session transcript 就是不进来
这不是 provider 坏了,也不是索引器抽风,而是功能门没有彻底打开。
四、正确修法,分三步
第一步:把 sessionMemory 打开
把配置改成下面这样:
"agents": {
"defaults": {
"memorySearch": {
"enabled":true,
"sources": ["memory", "sessions"],
"provider": "local",
"fallback": "none",
"experimental": {
"sessionMemory":true
}
}
}
}如果你想统一给所有 agent 开,直接放在 agents.defaults.memorySearch 最省事。
如果你只想给某个 agent 单独开,也可以只在那个 agent 的配置里覆写。
第二步:强制重建索引
这一步很多人会漏掉。
开关打开,不等于历史 sessions 会自动补到索引里。最稳的做法,是直接强制重建:
openclaw memory index --force如果你要指定 agent:
openclaw memory index --agent main --force如果你是多 agent 架构,建议把其他几个 agent 也各自跑一遍。
第三步:不要靠感觉,要靠状态命令验收
执行:
openclaw memory status你真正想看到的不是“命令成功”,而是下面这种结果:
Sources: memory, sessions
By source:
memory · ...
sessions · ...如果你看到的还是:
Sources: memory那说明 session memory 还是没真正生效。
五、怎么判断你到底修没修好
我建议看三层信号。
1)先看 Sources
最直接。
你要确认运行时展示的是:
• memory, sessions
而不是只有:
• memory
2)再看 By source
这一步能区分“开关已经打开”和“历史索引已经补齐”是不是两回事。
比如下面这种状态:
Sources: memory, sessions
By source:
memory · 69/69 files · 782 chunks
sessions · 0/80 files · 0 chunks这说明:
• sessions 已经启用了 • 但历史 transcript 还没有真正补进索引
只有当你看到类似:
sessions · 80/80 files · 988 chunks才算这件事彻底完成。
3)最后看 Dirty / Vector / FTS
如果是:
• Dirty: no• Vector: ready• FTS: ready
说明索引系统本身是稳的。
如果 sources 还是不对,那就继续查配置和 feature gate,不要先把锅甩给 embedding provider。
六、这个坑和 embedding provider,其实不是一回事
还有一种常见误判是:
“是不是我现在用的是 local embedding,所以 sessions 不支持?”
多数情况下,不是。
memory 和 sessions 能不能一起生效,核心不在 provider,而在配置解析阶段有没有把 sessions 放进有效 source 集合。
也就是说:
• local• openai• gemini• voyage• mistral• ollama
这些是“向量怎么做”的问题。
而 sessions 是否被启用,先是“数据源有没有真的进入运行时”的问题。
顺序要对。先把 feature gate 打开,再谈 provider 优化。
七、我更推荐的实际配置思路
方案一:本地优先
适合:
• 重视隐私 • 不想让 embedding 走外部 API • 希望成本更可控
思路:
• provider: local• sources: ["memory", "sessions"]• experimental.sessionMemory: true
优点是稳,缺点是 sessions 变多以后,索引体积和更新成本也会上去。
方案二:先只开 memory
适合:
• 你主要依赖 MEMORY.md和memory/*.md• 对历史聊天引用没有强需求 • 想先把系统跑稳
优点是简单,缺点是很多真实对话里的上下文进不了可检索层。
方案三:只给核心 agent 开 sessions
适合:
• 你是多 agent 架构 • 某些 agent 高频对话,确实需要 transcript recall • 某些 agent 只是偶尔运行,不值得增加索引负担
这是更平衡的做法。
八、这件事最值得记住的一句话
我把这次踩坑浓缩成一句话:
在 OpenClaw 里, 是声明, 才是放行。
只写前者,不开后者,sessions 就可能停留在“看起来已配置”的状态。
这也是为什么很多人明明觉得自己已经配对了,结果系统还是搜不到历史对话。
九、最短排障清单
如果你赶时间,直接按这个顺序查:
1. 有没有写: • sources: ["memory", "sessions"]
2. 有没有写: • experimental.sessionMemory: true
3. 改完后有没有执行: • openclaw memory index --force
4. 有没有用: • openclaw memory status
5. 结果里有没有看到: • Sources: memory, sessions
6. By source里sessions有没有真实文件数和 chunk 数
只要漏一步,你都可能以为自己修好了,其实没有。
结尾
OpenClaw 的记忆系统很强,但也正因为它在往更复杂的多层记忆方向走,配置项之间已经不是“写上就等于生效”的关系了。
这次这个坑,表面看是一个小开关,实质上是在提醒我们一件事:
别只看配置文件,要看运行时状态。
真正的答案,不在“我觉得应该生效”,而在:
openclaw memory status如果你也在折腾 OpenClaw 的 memory、sessions、多 agent 记忆,这篇建议先收藏。等你哪天明明写了配置却死活搜不到历史对话,大概率就是踩到这里了。
夜雨聆风