OpenClaw · Memory Deep Dive

记忆存下来之后怎么用?
梦境又是干什么的?

记忆写入文件只是第一步。本文解释:存好的记忆怎么被取出来放进 AI 的"眼睛"里, 以及为什么 AI 需要像人一样"做梦"才能让记忆真正有用。

存好的记忆,是怎么被 AI 读到的?

记忆文件躺在磁盘上不会自动发挥作用。每次用户发起对话,OpenClaw 都要经历 "检索 → 过滤 → 注入"三个阶段,才能让记忆真正出现在 AI 的视野里。

🔄 完整流程:从用户一句话到 AI 看见记忆
1

用户发送消息

例如:"帮我写一个 API 接口,使用我平时喜欢的代码风格"
这句话触发了 OpenClaw 的整个记忆检索管道。

2

查询理解 —— 提取检索意图

系统把"API 接口""代码风格""喜欢"等关键词提取出来, 同时把这句话转换成一个向量,准备做语义搜索。

3

双路检索 —— BM25 关键词 + 向量语义

BM25(精确词):在倒排索引中找包含"代码风格"的文件, 结果:user.md
向量(语义近似):找和"编码习惯偏好"最相似的片段, 结果:project.md session/2026-05-10.md
两路合并,按 70% 语义 + 30% 关键词 加权排序。

4

时间衰减 + 访问频率加权

每条记忆有一个"鲜活度分数":越近期创建 / 越频繁访问的记忆,分数越高。 公式大致为:final = relevance × 0.95^天数 × log(访问次数+1)。 不活跃的记忆排名下降,但不删除。

5

MMR 去重 —— 避免塞入重复内容

如果 user.md 和 session/xxx.md 里都记录了"用 TypeScript", MMR 算法会对相似的结果扣分,让不同方向的记忆都能出现, 避免把有限的上下文空间全给"重复信息"占满。

6

注入 Prompt —— 记忆终于"出现在 AI 眼前"

系统把排名最高的 N 条记忆片段(通常 3~8 条)以 片段级方式嵌入 prompt 的专用区域, 不是整个文件,而是最相关的那几段话。AI 此时才真正"看见"这些记忆。

📋 AI 实际收到的 Prompt 长什么样?

记忆被注入到一个专用的 <memory> 区块, 夹在系统提示词和用户消息之间:

┌─ Prompt 结构 ─────────────────────────────────────
│ [SYSTEM PROMPT]        角色定义 / SOUL.md
│ <memory>                ★ 检索到的记忆片段注入这里
│   ── user.md 片段:用户偏好 TypeScript,使用 Prettier 格式化
│   ── project.md 片段:后端用 Fastify,数据库 PostgreSQL
│   ── session/2026-05-10.md:上次讨论了 JWT 鉴权方案
│ </memory>
│ [CONVERSATION HISTORY]  最近几轮对话记录
│ [USER MESSAGE]          帮我写一个 API 接口...
└──────────────────────────────────────────────────
💡 关键点:记忆不是"整个文件"注入,而是"相关片段"注入。 你可以有几千条记忆存在磁盘上,但每次只有最相关的几条会出现在 AI 视野里, 所以记忆再多也不会撑爆上下文。
♻️ 记忆被使用后,会更新自身的"热度"

每次记忆被检索并注入到 prompt,系统会自动更新该记忆的元数据:

--- memory/user.md front-matter --- type: user_preference created: 2025-11-15 last_accessed: 2026-05-18 # ← 每次被使用都更新这里 access_count: 25 # ← 被用了 25 次,永远不会被"遗忘" decay_score: 0.94 # ← 每次访问后 score 被 boost,不再衰减 ---
🌿 结论:经常用到的记忆会越来越"强",很久不用的记忆会慢慢排到后面。 这不是删除,而是自然的"重要性排序"——就像你书桌上最常翻的书总在最顺手的地方。

梦境(Dream)是什么?为什么需要它?

记忆存下来、能检索到,听起来已经够用了——但有个隐藏问题: 随着时间推移,记忆碎片越来越多、越来越零散, 像一堆乱糟糟的便利贴,贴满了整面墙。 "梦境"就是 AI 定期对这些碎片做的一次整理、合并、升华

🧑

人类大脑

白天接收大量信息碎片(场景、对话、感受), 夜晚睡眠时海马体把短期记忆转换为长期记忆, 相关的事件被关联压缩,不重要的被淡忘。

这个过程就是"睡梦"。

🤖

OpenClaw AI

每次对话都产生记忆碎片(用户说了什么、做了什么决策、出现了什么错误), 定时离线批处理把这些碎片整合成结构化知识, 相似的合并,无用的降权。

这个过程就是 AI 的"梦境"。

🚨 如果没有梦境,会发生什么?

想象你用了这个 AI 6 个月,每天对话 10 次,每次产生 5 条记忆碎片:

5月1日:用户喜欢 TypeScript
5月3日:用户说要用 TypeScript
5月8日:TypeScript 是用户的偏好语言
6月2日:用户选择了 TS 而不是 JS
6月15日:用户在项目里用 TypeScript
... 还有 9000 条类似的碎片
❌ 问题一:碎片爆炸 — 9000 条几乎重复的碎片,检索时要全部遍历打分
❌ 问题二:信息稀薄 — 明明可以总结为"用户一直用 TypeScript",却散落成 9000 条
❌ 问题三:模式盲区 — 很多跨时间的规律(比如用户每周五才活跃)没有人把它提炼出来
❌ 问题四:检索噪音 — 相似内容太多,MMR 去重依然无法完全避免结果雷同
🌙 梦境阶段实际做的 5 件事
Dream Task 1
🧩 碎片合并(Consolidation)
把内容高度相似的多条碎片合并成一条。 "5月1日用 TypeScript"+ "5月3日用 TypeScript"+ ... → 一条 用户长期偏好 TypeScript。 合并后的记忆比原始碎片更干净、信息密度更高。
Dream Task 2
🔗 关联发现(Association)
跨会话寻找隐性规律。例如: "用户总在报错后要求解释" + "用户说不喜欢过度注释" → 用户想理解原理但讨厌废话,解释要简洁有深度 这种洞察从来不会被单次对话记录下来,只有在俯瞰所有历史后才能发现。
Dream Task 3
📈 知识升华(Abstraction)
把大量具体事件提炼为更高层的知识。 10 次"用户让我用 Fastify"的碎片 → 一条"该项目技术栈:Fastify + PostgreSQL + TypeScript"。 上层知识更稳定,被检索到后能回答更广泛的问题。
Dream Task 4
🔄 向量重建(Re-embedding)
合并和升华后的记忆需要重新生成 embedding 向量。 旧的碎片向量被废弃,新的高质量记忆的向量被写入索引。 这样下次语义搜索时,返回的是精华内容,而不是原始碎片。
Dream Task 5
🗑️ 垃圾清理(Pruning)
极低分且已被合并的碎片,在梦境阶段可以真正被标记为"已归档"。 注意:不是删除文件,而是不再参与检索。 就像把整理后的旧便利贴装进档案盒,需要时还能翻,但平时不占空间。
⏰ 梦境在什么时候触发?

梦境是离线批处理——它不能在用户等待回复时运行(太慢), 而是在系统空闲时自动执行:

☀️ 白天(活跃对话中)

  • 用户发消息 → 实时检索记忆 → 注入 prompt
  • 对话结束 → 新记忆碎片写入磁盘
  • 访问的旧记忆的 access_count +1
  • 不做任何整合,只是快速读写

🌙 夜晚(低活跃 / 定时任务)

  • Cron 定时任务触发(如每天凌晨 3 点)
  • 或会话数超过阈值时触发
  • 启动梦境 Agent:扫描所有新碎片
  • 执行合并、关联、升华、重建向量
  • 更新 .openclaw/memory/.index/
  • 写入 dream_log.md 记录此次整合内容
为什么不能实时做? 合并和关联需要对比成百上千条记忆,还要重新生成 embedding(调用 API)。 放到对话里做会让用户等 10~30 秒,完全不可接受。 所以只能离线批量处理,用"稍晚一点"换取"不影响体验"。
✨ 梦境前 vs 梦境后:记忆质量的变化

🌅 梦境前(原始碎片)

  • 9000 条零散碎片,大量内容重复
  • 只有"发生了什么",没有"代表什么"
  • 检索结果雷同,上下文空间浪费
  • 跨会话的规律完全看不见
  • 向量质量参差不齐(原始话语生成)

🌟 梦境后(整合知识)

  • 200 条精华记忆,信息密度高
  • 不仅有事实,还有提炼出的行为模式
  • 检索结果多样,上下文利用率高
  • 跨会话的洞察被显式存储
  • 向量基于精华内容重建,语义更准确
一个具体的例子:梦境把下面左边 5 条碎片整合成右边 1 条高质量记忆:
用户强烈偏好 TypeScript,
要求开启 strict 模式,
不接受 any 类型逃逸。

记忆的完整生命周期

把两个部分串起来,看一条记忆从诞生到被使用再到被"梦境升华"的全过程。

🔁 一条记忆的一生

诞生 — 写入磁盘

对话中 AI 触发 create_memory 工具, 把"用户喜欢 TypeScript"写入 .openclaw/memory/session/2026-05-18.md, 同时更新倒排索引和向量嵌入。

首次被用 — 检索注入

下次用户问"帮我写代码"时, 系统检索到这条记忆,注入到 prompt 的 <memory> 区块, AI 据此自动选用 TypeScript。
同时:access_count: 0 → 1last_accessed 更新。

时间流逝 — 自然衰减

如果长时间没被访问,decay_score 每天乘以 0.95, 检索时排名逐渐下滑。但文件本身不动,随时可以被重新找到。

梦境整合 — 从碎片到知识

夜间梦境任务发现 10 条关于 TypeScript 的碎片, 把它们合并为一条高质量的 memory/user.md 条目, 原始碎片被标记为"已归档",新向量重建入库。

长期稳定存在 — 高频使用永不遗忘

合并后的记忆信息更丰富、向量更精准、被检索概率更高。 只要用户还在用 TypeScript,它就一直排在检索结果前列, 成为 AI 理解用户的"长期人格记忆"。

📥 记忆怎么被使用

  • 用户提问 → 双路检索(BM25 + 向量)
  • 时间衰减 + 访问频率综合打分
  • MMR 去重保证结果多样性
  • Top-N 片段注入 prompt 的 <memory> 区
  • AI 看见记忆 → 做出个性化回答
  • 被使用后 access_count++,记忆强化

🌙 梦境是什么

  • 离线批处理:低活跃 / 定时触发
  • 合并相似碎片 → 减少冗余
  • 发现跨会话的隐性规律
  • 提炼高层抽象知识
  • 重建向量让检索更精准
  • 归档低价值碎片但不删文件

❓ 为什么需要梦境

  • 长期运行会产生海量重复碎片
  • 碎片多 → 检索慢、结果质量差
  • 单条对话无法发现跨时间规律
  • 实时整合太慢,影响对话体验
  • 梦境 = 用低峰期时间换高质量记忆
  • 让 AI 越用越聪明,而不是越用越乱