别把全部聊天记录塞进知识库:OpenClaw 的记忆检索到底怎样才省钱、找得准?
全文约 4000 字 | 预计阅读 10 分钟
你有没有过这种时刻——
用了几个月的 OpenClaw,MEMORY.md 已经长到 40 KB,每次新会话开头都要”预热”快一分钟;结果你问它一个很具体的问题,比如”我上个月定的那个日志库选型是什么来着”,它想了半天,回你一句”不太确定你指的是哪次”。
问题不在它”记性不好”。问题在于你把稳定偏好、每日流水、长期资料全堆进了同一层,而且默认把它整本塞进上下文。
OpenClaw 的记忆系统其实设计得相当讲究:它有分层、有 hybrid 检索、有可调的命中率和成本旋钮。但绝大多数”记不住 / 太烧钱”的抱怨,根源都是同一件事——没有把记忆分层,也没有按需检索。
今天这篇,我基于 OpenClaw 官方 Docs(docs.openclaw.ai)逐篇扒了一遍,把”记忆到底存在哪、检索怎么工作、三层结构怎么切、以及你怎么测出自己环境的真实命中率和成本”讲清楚。
划重点:本文不给任何未实测的百分比。网上那些”省 40% token””命中率提升 X 倍”的数字,基本都是别人在别人的模型、别人的切分下测的,你直接抄过来没意义。我会给你一套 15 题自测框架,跑完你就有自己的数字。
一、OpenClaw 的记忆,到底存在哪?
先拆一个最常见的误解:OpenClaw 没有隐藏的记忆状态。 它只把 workspace 里的纯 Markdown 文件当记忆载体,默认路径是 ~/.openclaw/workspace。
三类文件的分工是这样的:
-
MEMORY.md:长期记忆。会话开始时会被注入到 bootstrap prompt 里。这里只放稳定事实、偏好、决策和摘要,不是原始记录。 -
memory/YYYY-MM-DD.md(可以带-slug后缀):每日工作层。默认只有在/new或/reset时,才会自动加载”今日 + 昨日”两天的日志;更早的内容平时不进上下文,靠memory_search/memory_get去检索。 -
DREAMS.md:可选。是 dreaming 系统的评审记录,主要给人看,不进 bootstrap。
如果你之前用 Codex 或 Claude Code,它们的 Markdown 记忆可以直接迁进来:在 Control UI → Settings → Import Memory 导入,结果会单独放在 memory/imports/codex/、memory/imports/claude-code/,会被 memory_search 索引,但不会合并进 MEMORY.md 的 bootstrap——也就是说它能被查到,但不会白白占你的长期上下文。
关键区别在于两种”被看到”的时机:
-
MEMORY.md是”每次会话开头就注入”——你不用查,它就在那; -
memory/YYYY-MM-DD.md是”平时不注入,需要时再检索”——这就是”按需检索”的开关。
一个很多人踩过的坑:当你往
MEMORY.md里疯狂加东西,超过 bootstrap 预算时,磁盘上的文件不会变,但注入到上下文的副本会被截断。你看到的 agent”突然变笨”,可能只是它的长期记忆被悄悄截掉了一段。
怎么验证?用这几个命令看”原始大小 vs 注入大小”的差和截断状态:
/context list # 看各层上下文占用/context detail # 看 MEMORY.md 注入副本有没有被截断openclaw doctor # 整体体检
<img src=”fig1-%E4%B8%89%E5%B1%82%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84.png” alt=”配图①:三层目录结构 + 每层”什么时候被 agent 看到”的时机图” title=”配图①:三层目录结构 + 每层”什么时候被 agent 看到”的时机图”>
三层目录:顶层
MEMORY.md每次会话自动注入;中层每日日志按需检索;底层外部 Vault 经extraPaths按全文检索。
二、memory_search 是怎么”找到东西”的?
这是整篇文章最值钱的一节。OpenClaw 的检索是 hybrid(混合) 的:你的查询会同时走三条路,再加权合并。
你的查询 query │ ┌─────────┼─────────────┐ ▼ ▼ ▼ vector BM25 文件名索引(语义相似) (关键词) (路径/basename命中权重更高) │ │ │ └─────────┼─────────────┘ ▼ 加权合并 → top results
-
vector:把 query 做 embedding,找语义相近的片段; -
BM25:传统关键词匹配,拼写、专有名词、报错信息这类”字面必须命中”的场景很关键; -
文件名索引:完整路径 / 文件名 / stem 的命中权重,比”路径里某段匹配”更高——所以文件名起得好,检索就赢一半。
你能选的 embedding provider
OpenClaw 给了相当长的列表(memorySearch.provider):
-
不用 API key 就能用: bedrock(AWS 凭证链)、github-copilot(Copilot 订阅)、local(llama.cpp GGUF)、lmstudio、ollama -
需要 API key: deepinfra(默认BAAI/bge-m3)、gemini、mistral、openai(默认,用text-embedding-3-small)、openai-compatible、voyage
注意一个很”轴”的设计:如果你显式指定了一个远端 provider,但它不可达(认证失败 / 网络问题),
memory_search会直接返回 “memory unavailable”,而不会悄悄降级成纯关键词搜索。 这是故意的——让坏配置显性暴露,而不是让你在”以为有向量搜索、其实只剩 BM25″的状态里蒙着跑。真想关掉 embedding 只用 FTS,要主动写
provider: "none"。
两把可选的”召回钥匙”
默认是关的,但中文项目很值得开:
-
Temporal decay: memorySearch.query.hybrid.temporalDecay.enabled: true,默认半衰期 30 天。只对memory/YYYY-MM-DD.md生效——MEMORY.md和memory/下非日期的文件永不衰减。意思是:老日志会随时间自然降权,不会一直挤占你的上下文。 -
MMR(diversity): mmr.enabled: true,避免 top 结果全是同一话题的近重复,让检索结果更多样。
进阶玩法还有:用 gemini-embedding-2-preview 给 extraPaths 里的图片/音频做多模态索引(默认 memory 根目录只吃 Markdown),以及把历史会话也纳入 memory_search(需要 experimental.sessionMemory 开关,且默认是 experimental)。

你的查询同时走 vector(语义)+ BM25(关键词)+ 文件名索引三路,加权融合后再排序过滤出 Top-K 结果注入上下文。
三、三层记忆结构:具体这样切
光讲原理没用,给你一份能直接抄的目录设计。 核心是把”稳定偏好 / 每日过程 / 可复用资料”分开放。
~/.openclaw/workspace/├── MEMORY.md # 长期记忆:稳定偏好、决策、当前项目摘要├── memory/│ ├── 2026-07-17.md # 今日过程、临时发现、待确认│ ├── 2026-07-16.md│ └── imports/ # 从 Codex / Claude Code 迁入的旧记忆(可选)│ ├── codex/│ └── claude-code/└── DREAMS.md # 可选:dreaming 评审记录~/notes/ # 外部 Vault(按需索引,不放在 workspace 内)├── projects/├── refs/└── sops/
层 1:MEMORY.md 只写四类
-
稳定偏好:不易变的语言/工具/风格,比如”回复默认用中文””代码用 Python 3.11″; -
长期决策:已在项目里执行的选型,比如”日志用 loguru,不用标准库 logging”; -
当前项目摘要:一两句话说清在做什么、边界在哪; -
Action-sensitive 备注:涉及审批、跨会话交接、过期时机、来源权威的短笔记——记得写清”什么时候能做、什么时候别做”。
不写:原始聊天记录、每日流水、临时调试、可再检索的资料原文、密钥/凭据。
警戒线:一旦
/context detail提示注入副本被截断,就把细节挪到memory/*.md,MEMORY.md只留摘要。别靠放大 bootstrap 预算来掩盖问题。
层 2:memory/YYYY-MM-DD.md 用四段模板
每天的过程、临时发现、待确认结论放这。一个脱敏示例:
# 2026-07-17## Context- 目标:给公众号 09 号文章准备记忆检索资料。- 边界:以官方 Docs 为权威事实来源。## Decisions- 采用三层结构,参考 memory-layer-design。- QMD 作为进阶方案,先跑通 builtin。## Findings- OpenClaw builtin 默认切分 400 tokens / overlap 80。- provider / model / chunking 改任一都会触发索引 identity 变化。## TODO / Follow-up- 明天设计 benchmark 用的 15 个测试问题。
只有今日和昨日的日志会自动加载;更早的走检索。别主动删,让 temporal decay 自然降权,或让 dreaming 把有用内容提炼回 MEMORY.md。
层 3:外部 Vault 用 extraPaths 挂进来
可跨项目复用的 SOP、参考卡、项目文档,别塞进 workspace,写到 ~/notes/ 后挂进来:
{ agents: { defaults: { memorySearch: { extraPaths: ["~/notes/sops", "~/notes/refs"] }}}}
两个坑提醒:builtin 引擎会跳过符号链接(QMD 会跟随);多模态索引只对
extraPaths里的文件生效,MEMORY.md永远只吃 Markdown。改了extraPaths也会触发重建。
一个容易忽略但很实用的默认设置:compaction(对话压缩)之前,OpenClaw 会自动做一次 memory flush(
agents.defaults.compaction.memoryFlush.enabled默认true)——它会悄悄提示 agent 把重要上下文写进记忆文件,防止长对话被压缩时丢关键信息。你甚至可以为这次 flush 单独指定一个本地模型(比如compaction.memoryFlush.model: "ollama/qwen3:8b"),不占用主模型额度。
<img src=”fig3-%E5%86%99%E5%85%A5%E5%86%B3%E7%AD%96%E6%A0%91.png” alt=”配图③:agent 写记忆前的”往哪层写”决策树” title=”配图③:agent 写记忆前的”往哪层写”决策树”>
判断逻辑:稳定偏好/长期决策/项目摘要 → 写
MEMORY.md;过程/发现/TODO → 写每日日志;可复用 SOP/参考文档 → 挂外部 Vault。敏感信息和密钥千万别进MEMORY.md。
四、三种做法对照:别抄网上的百分比
社区里最常见的三种记忆组织方式,我整理了它们的本质差异(配置对齐 benchmark 设计):
|
|
|
|
|
|---|---|---|---|
| A:整库灌入 |
MEMORY.md 或 memory/topics/*.md |
|
|
| B:每日摘要 |
MEMORY.md 短(仅偏好+项目摘要) |
|
|
| C:分层检索 |
MEMORY.md + 每日日志 + 外部 Vault 经 extraPaths 索引 |
|
|
这里必须泼盆冷水:网上你能看到的那些命中率 / 成本百分比,大部分是别人在别的模型、别的切分、别的语料下测的。直接抄,等于拿别人的体检报告当自己的药方。
如果你真要对比 A/B/C,先 pin 死这几个变量,否则结果不可比——
-
主模型(任何切换都视为新实验) -
embedding provider / model(变了就是新的 index identity) -
切分 chunking.tokens=400 / overlap=80(Docs 默认) -
tokenizer:中文项目用 trigram -
hybrid 权重、maxResults、minScore -
机器、时段(减少远端 API 抖动)
任一变量变化 = 新一轮实验,不能和旧结果混算。
五、15 题自测:怎么验证自己的配置
前面说了不给假数字,那你的真实数字从哪来?自己跑。下面是一套可直接复用的自测框架。
15 题怎么出
题目要覆盖四种类型,否则测出来的命中率会偏:
-
语义题: paraphrase 一下你的真实意图,看它能不能语义命中(例:”我上次为什么放弃 logging 换 loguru?”) -
关键词题: 必须字面命中的(报错信息、专有名词) -
时间敏感题: 答案会过期的(”上周定的那个截止日期是哪天?”) -
过期条目题: 故意放一条已经作废的偏好,看它会不会把过时结论当真理
一个反面例子:某题在 A 方案下”命中率很高”,但点开
openclaw memory search的输出,它引用的是 3 个月前一条早被推翻的结论。命中 ≠ 正确,所以记录时要同时标stale_info_shown(是否命中过期信息)。
每题记录这些字段
|
|
|
|---|---|
hit@1 |
|
hit@6 |
maxResults)是否含正确片段 |
relevant_ratio |
|
|
|
|
|
|
|
context_polluted |
|
stale_info_shown |
|
跑完后,把每个方案的结果汇总成一行:Hit@1、Hit@6、平均相关度、中位延迟、P95、平均 token 成本、上下文污染率。重点不是追求一组“通用最优数字”,而是用同一套题目和环境,找出更适合自己资料组织方式的配置。
六、你会踩的坑(改配置篇)
这部分全是”我替你排过雷”的硬经验,建议直接收藏。
-
改了 provider / model / chunking / tokenizer 就以为没事 —— 错。这些字段里任意一项变更,索引 identity 都会变, memory_search会先”暂停 + 报 warning”,别以为是自己代码坏了。手动跑一次openclaw memory index --force重建。 -
Local GGUF 首次会自动下载模型 —— 约 0.6 GB 的 embedding + 2 GB 的 QMD reranker,第一次用别被”卡住”吓到。 -
群 / 频道里看不到 QMD 结果 —— 这不是 bug,是 scope 默认 deny。只有 direct / DM 会话默认能看到 QMD 结果。 -
Intel Mac 用不了 LanceDB —— darwin-x64 没有原生构建,插件会报 unavailable。用 Apple Silicon 或 Linux。 -
登了 Codex OAuth 就以为有 vector 搜索 —— 错。Codex OAuth 只覆盖 chat/completions,不满足 embedding 请求,OpenAI 还得单独配 API key。

改完 provider / model / 切分后记得跑
openclaw memory index --force重建索引——这是最容易忘的一步。
七、进阶:什么时候才值得上 QMD 或 LanceDB?
默认引擎(builtin SQLite + hybrid + OpenAI embedding)零依赖起步,多数人够用。QMD 和 LanceDB 是”默认不够时”的选项,不是新手默认路径。
升级判据(满足再考虑):
-
需要 rerank / query expansion 来提升精排质量 → 看 QMD; -
要跨 workspace 索引、要跨会话 recall → 看 QMD 或 LanceDB; -
需要独立向量库、S3 存储、Agent 级所有权边界 → 看 LanceDB。
QMD 首次
qmd query会下载约 2 GB 模型,且 QMD 二进制必须在 gateway 的PATH下——新手最容易栽在”装了但 PATH 没生效”。LanceDB 换非内置维度模型(如智谱embedding-3= 2048)时,必须显式写embedding.dimensions,否则维度对不上直接 unavailable。
一句话:先把 builtin 跑顺、把三层结构切好、把 15 题自测跑完,再谈进阶。 顺序反了就是给自己找事。
八、收束:记忆管理是”每周 15 分钟”的功夫
回到开头那个场景——MEMORY.md 长到 40 KB、预热一分钟、问具体事还答不上来。
根因从来不是”记得太多”,而是把不同性质的东西放进同一层,并且默认整本注入。
你真正要做的就三件事:
-
先画三层目录: MEMORY.md(稳定偏好/决策/摘要)+ 每日日志(过程/TODO)+ 外部 Vault(可复用 SOP); -
跑一次 15 题自测:别抄别人的百分比,用本文框架跑出你自己的命中率和成本; -
每周清一次 MEMORY.md:截个/context detail,把细节挪到日志,只留摘要。
记忆不是”塞满就好”,是”在需要的时候,刚好能找到对的那一条”。
附录:OpenClaw 记忆管理 Checklist(建议收藏)
-
MEMORY.md只写四类内容(稳定偏好 / 长期决策 / 项目摘要 / action-sensitive 备注) -
每日 memory/YYYY-MM-DD.md用四段模板(Context / Decisions / Findings / TODO) -
中文项目把 store.fts.tokenizer设成trigram -
打开 mmr和temporalDecay -
用 extraPaths挂外部 Vault(别把整个聊天目录塞进去) -
改 provider / model / 切分后跑 openclaw memory index --force -
每周体检 MEMORY.md(截屏/context detail看是否截断) -
保留一份 15 题自测 CSV,环境变了就重跑
最后说一句
从”我的 agent 每次都要重新认识我”,到”它三个月后还记得我那个日志选型写在哪”——中间差的不是更大的模型,而是一套分层的记忆纪律。这套跑通的那一刻,你才会真正觉得:它不是聊天工具,是个有记忆的工作伙伴。
下一篇我会写 QMD 实战:怎么把 rerank 真正用起来、2 GB 模型下载后怎么预热、以及群聊里让结果可见的 scope 怎么配。关注「桦说AI」,下周见。
📍 你想聊聊吗? 你现在的 MEMORY.md 多大?有没有被截断过?评论区晒一下你的三层结构,或者说说你踩过的记忆坑——说不定你的经验就是别人的救命方案。
本文事实性陈述均对齐 OpenClaw 官方文档(2026-07-17 抓取),测试语料使用脱敏内容。任何命中率 / 成本数字请以你自己在相同环境下的实测为准,不要外推。
参考资料
-
OpenClaw Docs · Memory overview[1] -
OpenClaw Docs · Memory search[2] -
OpenClaw Docs · Builtin memory engine[3] -
OpenClaw Docs · QMD memory engine[4] -
OpenClaw Docs · Memory configuration reference[5] -
OpenClaw Docs · Memory LanceDB[6]
: OpenClaw Docs · Memory overview —— 仅纯 Markdown 文件作为记忆载体,默认路径 ~/.openclaw/workspace。 : 同上 —— 从 Codex / Claude Code 迁入的记忆存于 memory/imports/…,被检索但不合并进 MEMORY.md bootstrap。 : 同上 —— MEMORY.md 超限时注入副本被截断,用 /context list / /context detail / openclaw doctor 查。 : OpenClaw Docs · Memory search —— hybrid:vector + BM25 + 文件名索引并行,加权合并。 : 同上 + Memory configuration reference —— provider 列表与默认值。 : 同上 —— 显式远端 provider 不可达时返回 “memory unavailable”,不静默降级。 : 同上 —— temporalDecay 仅对 memory/YYYY-MM-DD.md 生效;MMR 为可选 diversity 钥匙。 : 同上 —— 多模态仅对 extraPaths 生效;session memory 为 experimental。 : 基于本文 memory-layer-design.md 的三层目录设计。 : OpenClaw Docs · Memory overview —— compaction 前 automatic memory flush 默认开启,可指定独立本地模型。 : OpenClaw Docs · Builtin engine / config reference —— memorySearch.extraPaths 外部路径索引,builtin 跳过符号链接。 : 基于本文 benchmark-plan.md 的 A/B/C 方案定义与公平约束。 : 基于本文 benchmark-plan.md 的 15 题测试集与指标记录表。 : OpenClaw Docs · Builtin engine + config reference —— 变更 provider/model/chunking/sources/scope 触发索引失效,需 --force 重建。 : OpenClaw Docs · Memory search / QMD engine —— Local GGUF 自动下载 embedding 与 reranker 模型。 : OpenClaw Docs · QMD engine —— 默认 scope 仅 direct/DM 可见,群/频道默认 deny。 : OpenClaw Docs · Memory LanceDB —— darwin-x64 无原生构建。 : OpenClaw Docs · config reference —— Codex OAuth 不覆盖 embedding 请求。 : OpenClaw Docs · QMD engine / Memory LanceDB —— 进阶引擎的适用判据。 : 同上 —— QMD 的 PATH 依赖;LanceDB 非内置维度须显式 embedding.dimensions。
引用链接
[1]OpenClaw Docs · Memory overview: https://docs.openclaw.ai/concepts/memory
[2]OpenClaw Docs · Memory search: https://docs.openclaw.ai/concepts/memory-search
[3]OpenClaw Docs · Builtin memory engine: https://docs.openclaw.ai/concepts/memory-builtin
[4]OpenClaw Docs · QMD memory engine: https://docs.openclaw.ai/concepts/memory-qmd
[5]OpenClaw Docs · Memory configuration reference: https://docs.openclaw.ai/reference/memory-config
[6]OpenClaw Docs · Memory LanceDB: https://docs.openclaw.ai/plugins/memory-lancedb
夜雨聆风