OpenClaw源码解析(十五):记忆系统总览:长期记忆、会话记忆与检索层边界
核心文件:
– src/agents/memory-search.ts
– src/memory/search-manager.ts
– src/memory/manager.ts
– src/memory/qmd-manager.ts
– src/agents/tools/memory-tool.ts
– src/auto-reply/reply/memory-flush.ts
记忆系统源文件位置
-
真正的“记忆内容源文件”,这些才是 source of truth,都是 Markdown。
-
workspace/MEMORY.md
整理过的长期记忆
-
workspace/memory/YYYY-MM-DD.md
每日格式的记忆,这是一份Agent自己总结好的内容,不是原对话历史
-
workspace/memory/YYYY-MM-DD-<slug>.md
由 session-memory hook 在 /new 或 /reset 时主动生成的会话沉淀文件
-
builtin backend 的索引库
这是 OpenClaw 自己的内建索引数据库,不是记忆原文, 默认是main.sqlite。
-
memory/<agentId>.sqlite
-
QMD backend 的状态与索引,如果启用了 QMD,QMD 会自己维护一套目录。
-
stateDir/agents/<agentId>/qmd/xdg-config/ -
stateDir/agents/<agentId>/qmd/xdg-cache/qmd/index.sqlite
另外如果开启 session 导出,还会有:
-
stateDir/agents/<agentId>/qmd/sessions/
-
session transcript 原始会话日志 (注意:需要显示开启sessions,才会搜索这部分内容)
这不是长期记忆 Markdown,但它是 session-memory hook、sessions source、QMD session export 的上游来源。
-
stateDir/agents/<agentId>/sessions/\*.jsonl
先给一个总判断
OpenClaw 里的“记忆”不是单一模块,而是三层相邻但不同的东西:
1. 当前工作记忆
也就是上一篇文章讲的:
-
session transcript -
system prompt -
prompt-local 内容 -
当前 turn 的 tool / assistant 状态
它解决的是:
这一次模型调用要带什么上下文。
2. 长期可检索记忆
也就是这一章的主角:
-
MEMORY.md -
memory/*.md -
可选额外 markdown 路径 -
可选 session transcripts 索引
它解决的是:
过往知识如何持久保存,并在以后按需检索召回。
3. 记忆落盘与预压缩机制
比如:
-
/new / /reset 时通过 hook 把旧会话摘要保存为 memory 文件 -
近 compaction 阶段的 memory flush
它解决的是:
当前会话里哪些内容值得转化成长期记忆,什么时机存储最合适。
所以更准确的心智模型应该是:
context engine 负责当前工作记忆memory system 负责长期可检索记忆memory flush / session-memory hook 负责把部分当前经验沉淀成长期记忆
未来多篇文章分别讲什么
本篇介绍
总览页,解决:
-
短期记忆和长期记忆在 OpenClaw 里的边界 -
记忆数据到底来自哪里 -
builtin backend 和 QMD backend 各自处在什么位置
记忆系统运行时全景
-
一条关于“过去的事”的问题进入对话后,系统从哪里开始走到 memory search -
manager 在什么时机创建、预热、同步、关闭 -
search tool 如何把结果送回当前 turn
存储与索引层
-
有哪些记忆文件 -
session transcript 如何变成可索引文本 -
builtin sqlite schema 长什么样 -
FTS、vector、embedding cache 怎么配合 -
QMD backend 的集合、导出、更新机制
记忆是如何被检索的
-
query 是怎么被处理的 -
hybrid 检索、MMR、temporal decay 怎么工作 -
memorysearch / memoryget 工具如何设计 -
citation、snippet、注入长度是怎么控制的
记忆沉淀与刷新机制
-
/new / /reset 的 session-memory hook 怎么把会话存入 memory -
pre-compaction memory flush 是什么 -
session memory experimental source 是什么 -
“什么时候新增/更新/恢复记忆”在当前实现里分别对应哪些路径
先回答几个总问题
1. OpenClaw 里有哪些“记忆文件”
长期记忆源至少包括:
-
<workspace>/MEMORY.md -
<workspace>/memory/**/*.md -
extraPaths 指向的额外 markdown 文件/目录
可选记忆源还包括:
-
agent 的 session transcript 文件
但 session transcripts 并不默认算长期记忆数据源,只有在开启实验配置后才会进入 memory search。
2. 长期记忆和短期记忆分别是什么机制
短期记忆:
-
session transcript + context engine + prompt 装配链
长期记忆:
-
markdown 文件 / session exports -
embedding + keyword/fts 索引 -
memorysearch / memoryget 按需召回
3. 使用什么数据库
builtin backend 使用:
-
node:sqlite -
主库是每一个agent 一个 .sqlite -
其中有普通表、FTS5 虚表、可选 sqlite-vec 虚表
QMD backend 使用:
-
QMD 自己维护的 sqlite index -
位置在 agent state 下的 QMD XDG cache
4. 为什么这样选
builtin sqlite 这条线的工程动机很明显:
-
单机本地、低依赖 -
部署简单 -
可以同时承载元数据、FTS、embedding cache -
配合 sqlite-vec 可以在本地做向量检索
QMD 这条线则更像:
-
把记忆索引/召回交给专门外部工具 -
保留 builtin 作为 fallback -
更适合已经接受额外依赖和外部索引生命周期的用户
所以当前不是“只能二选一”,而是:
builtin = 默认内建实现QMD = 外部高级后端search-manager 负责按配置路由,并在需要时回退到 builtin
记忆系统主流程图
先给一张全景图,后面几篇就是把它拆开。
用户问到过去的事情 / 偏好 / 决策 / todo-> system prompt 要求先 memory_search-> memory_search tool 执行-> getMemorySearchManager(...)-> backend-config 决定 builtin 还是 qmd-> 创建/复用 manager-> manager 视情况 warmSession / onSearch sync-> 搜索 memory sources-> memory files-> 可选 sessions-> 返回 snippets + path/line/citation-> 模型如果需要再调用 memory_get-> 把精确片段带回当前 turn 继续推理
另一条从“当前经验沉淀成长期记忆”的路径是:
当前会话接近 compaction 或用户 /new /reset-> memory flush / session-memory hook-> 会话内容转成 markdown 记忆文件-> 后续 memory sync/index-> 以后可被 memory_search 检索
最重要的几个结论
-
OpenClaw 的 memory 不是“自动把所有历史塞回 prompt”,而是检索层。 -
builtin backend 不是简单实现,而是 sqlite + FTS + 可选 sqlite-vec + embedding cache 的完整本地索引器。 -
session transcript 可以是短期工作记忆,也可以在实验/导出路径下成为长期记忆来源,但这两者不是同一件事。 -
/new / /reset 的 session-memory hook 和 pre-compaction memory flush,承担的是“记忆沉淀”职责,不是检索职责。 -
当前记忆系统已经具备多 backend、provider fallback、FTS-only 降级、session source、citation 控制、检索重排等成熟特征。
夜雨聆风