AI 编程教程中文版
从原理到实战

04 · OpenClaw 的记忆系统:短期、长期、可检索记忆

解释 OpenClaw 如何用 Markdown 文件、记忆搜索、压缩前保存和 Dreaming 组成可审查的记忆系统。

上一章讲 Agent 的大脑循环:模型每一步都要依赖上下文和工具观察。这里自然会遇到一个问题:如果模型本身没有隐藏状态,OpenClaw 怎么让 Agent 记住长期偏好、历史决策和跨会话经验?

结论先说:

OpenClaw 的记忆不是神秘数据库,而是写在 Agent workspace 里的 plain Markdown files;模型只会“记住”被保存到磁盘、并在后续上下文中被加载或检索回来的东西。

这篇不要把它想复杂。先把文件、搜索、压缩、后台提炼四件事分清楚。

1. 模型没有隐藏记忆

官方 Memory overview 说得很直白:OpenClaw remembers things by writing plain Markdown files in your agent's workspace。模型只“记得”保存到磁盘的内容,没有 hidden state。

这意味着三件事:

  1. 用户在聊天里说过,不等于长期记住。
  2. 写进文件,才有跨会话复用的机会。
  3. 后续仍然需要加载或搜索到上下文里,模型才能使用。
flowchart LR
  A[Conversation] --> B{Worth saving?}
  B -- No --> C[Session context only]
  B -- Yes --> D[Write Markdown memory]
  D --> E[Index or load]
  E --> F[Future context]

所以 OpenClaw 的记忆系统不是“模型变成了有意识的长期记忆体”,而是一套围绕文件、索引、召回和提炼的工程系统。

2. 三类核心记忆文件

OpenClaw 当前官方记忆布局可以先记这三类:

文件作用加载/使用方式
MEMORY.md长期记忆,保存 durable facts、preferences、decisions每个 DM session 开始时加载
memory/YYYY-MM-DD.md每日笔记,保存 running context 和 observations今天和昨天的 notes 自动加载
DREAMS.md可选,Dream Diary 和 dreaming sweep summary供人类审查,不是普通聊天历史

这些文件位于 Agent workspace,默认路径是 ~/.openclaw/workspace

~/.openclaw/workspace/
  MEMORY.md
  DREAMS.md
  memory/
    2026-05-05.md
    2026-05-04.md

理解这三类文件,比背很多参数重要:稳定偏好,例如“用户偏好 TypeScript”,更适合放 MEMORY.md;今天任务中的临时观察,例如“这个项目测试暂时卡在依赖版本”,更适合放 memory/YYYY-MM-DD.md;后台提炼的主题、候选长期记忆、梦境摘要,更适合进入 DREAMS.md

DREAMS.md 是可选层,不要把它理解成 Agent 自动加载的普通长期记忆。长期提升最终仍然写入 MEMORY.md

3. Context 和 Memory 不是一回事

Context 是本轮模型能看见的内容。Memory 是存放在磁盘上的材料。

这两个概念经常被混用,但排障时必须分开:

问题属于 Context属于 Memory
本轮 prompt 里有没有这条信息
信息有没有落盘
下次会话还能不能找回不一定有机会
会不会受模型上下文窗口限制文件本身不受本轮窗口限制
模型能否直接使用能,前提是已经在上下文里不能,必须先加载或搜索回来

一个简单例子:

flowchart TD
  A[用户说: 我喜欢简洁回答] --> B[本轮 context]
  B --> C{需要长期保存?}
  C -- Yes --> D[写入 MEMORY.md 或 daily note]
  D --> E[memory_search 索引]
  E --> F[未来按需召回到 context]
  C -- No --> G[会话结束后只留在 transcript 或摘要里]

所以“Agent 失忆”通常有三种不同根因:

  1. 当时没有写入记忆文件。
  2. 写入了,但没有被加载或检索回来。
  3. 检索回来了,但被后续上下文或系统指令稀释。

不要只说“记忆坏了”,要先判断是哪一层的问题。

写进 Memory 只是第一步;后续被加载、搜索或主动召回进本轮 Context,模型才真正能用。

4. MEMORY.md 是长期事实,不是垃圾桶

MEMORY.md 保存 durable facts、preferences、decisions。它会在每个 DM session 开始时加载,因此越应该保持高信号。

适合写入 MEMORY.md 的内容:

  • 长期偏好:用户偏好中文、简洁、先结论。
  • 稳定身份:某个 Agent 的职责、边界、长期协作方式。
  • 反复出现的决策:某个项目固定部署到 Cloudflare Pages。
  • 已验证的工作约定:某个仓库必须通过特定脚本发布。

不适合写入 MEMORY.md 的内容:

  • 一次性任务进度。
  • 未核验的猜测。
  • 短期约会、明天提醒、临时待办。
  • 会过期的状态,例如“今天测试失败”。

官方还单独提到 commitments:有些未来 follow-up 不是 durable facts。例如“明天面试后问我结果”,更像短期承诺,不该粗暴写成永久长期记忆。明确提醒仍应使用 scheduled tasks。

长期记忆的质量,决定 Agent 越用越稳,还是越用越乱。

5. Daily notes 是短期工作轨迹

memory/YYYY-MM-DD.md 是 daily notes。它保存 running context 和 observations。官方说明今天和昨天的 notes 会自动加载。

它适合记录:

  • 今天做过哪些排障。
  • 某个临时错误的现象。
  • 本周正在推进的项目状态。
  • 还没验证到足以进入 MEMORY.md 的线索。

它不适合承载所有长期规则。原因很简单:daily notes 会越来越多,不能指望每一条旧日记都自动进入每一轮上下文。

flowchart LR
  D1[memory/2026-05-04.md] --> L[Auto load recent notes]
  D2[memory/2026-05-05.md] --> L
  D3[memory/older.md] --> S[memory_search]
  L --> C[Current context]
  S --> C

旧 daily note 主要靠 memory_search 找回,而不是靠全部加载。

6. memory_searchmemory_get

OpenClaw 给 Agent 提供两个记忆工具:memory_search 用来语义搜索相关 notes,即使用词不同也能找;memory_get 用来读取某个具体 memory file 或行范围。

这两个工具由 active memory plugin 提供,默认是 memory-core

memory_search 的关键是 hybrid search:

flowchart LR
  Q[Query] --> E[Embedding]
  Q --> K[Keyword tokens]
  E --> V[Vector search]
  K --> B[BM25 search]
  V --> M[Merge]
  B --> M
  M --> R[Relevant memory snippets]

它会把两条路径合并:

  • Vector search:按语义相似度找,例如“gateway host”能匹配“the machine running OpenClaw”。
  • BM25 keyword search:按精确词匹配,例如配置键、错误码、路径、ID。

这解释了为什么记忆搜索比普通 grep 更适合“用户偏好”“项目背景”这类软信息,也解释了为什么它仍然需要关键词路径:错误日志、配置 key、文件名必须精确命中。

7. Embedding provider 决定搜索质量

官方列出的 memory_search provider 包括 Bedrock、Gemini、GitHub Copilot、Local、Mistral、Ollama、OpenAI、Voyage。

如果你已经配置了 GitHub Copilot subscription、OpenAI、Gemini、Voyage 或 Mistral key,memory search 通常可以自动工作。也可以显式配置:

{
  "agents": {
    "defaults": {
      "memorySearch": {
        "provider": "openai"
      }
    }
  }
}

没有 API key 时,也可以用 provider: "local",但本地 embedding 会带来模型下载、构建和速度问题。

排障时先跑:

openclaw memory status
openclaw memory status --deep
openclaw memory index --force

几个典型症状:

症状可能原因处理
没有结果索引为空openclaw memory index --force
只有关键词命中embedding provider 没配置或不可用openclaw memory status --deep
中文找不到FTS 索引需要重建openclaw memory index --force
结果重复大量 daily notes 相近开启 MMR
旧内容总排前面历史 note 太多开启 temporal decay

MMR 用来减少重复结果。Temporal decay 会让旧 notes 逐渐降权,但 evergreen files 如 MEMORY.md 不衰减。

8. Compaction 前的 memory flush

上一章讲过,Agent loop 有上下文窗口限制。官方 Compaction 文档说明:当会话接近上下文限制时,OpenClaw 会把旧消息压缩成 summary;完整历史仍在磁盘上,compaction 改变的是下一轮模型看见什么。

记忆系统和 compaction 的关系在这里:

Before compaction, OpenClaw can run a silent memory flush turn to store durable notes to disk。

也就是压缩前,OpenClaw 可以静默提醒 Agent 把重要内容写进 memory files,避免旧上下文被摘要后丢失细节。

Memory flush 不是万能自动记忆,而是 compaction 前的一次保护动作:先把值得保留的事实落盘,再压缩上下文。

flowchart TD
  A[Conversation grows] --> B[Near context limit]
  B --> C[Silent memory flush]
  C --> D[Save important notes to memory files]
  D --> E[Compaction summary]
  E --> F[Next turn uses compacted context]

这不是“每隔固定多少字就写记忆”的万能机制。它是 compaction 前的保护动作。你也可以给 memory-flush turn 配一个独立模型:

{
  "agents": {
    "defaults": {
      "compaction": {
        "memoryFlush": {
          "model": "ollama/qwen3:8b"
        }
      }
    }
  }
}

注意这个 override 是 exact model override,不继承 active session fallback chain。

9. Dreaming 是后台提炼,不是默认开关

Dreaming 是 memory-core 里的 background memory consolidation system。它帮助 OpenClaw 把强短期信号移动到 durable memory,同时保持过程可解释、可审查。

两个硬事实:

  • Dreaming 是 opt-in,默认 disabled。
  • Long-term promotion 仍然只写入 MEMORY.md

Dreaming 有三类输出或状态:memory/.dreams/ 放机器状态,包括 recall store、phase signals、checkpoints、locks;DREAMS.md 放人类可读的 Dream Diary 和 phase summaries;memory/dreaming/<phase>/YYYY-MM-DD.md 放可选阶段报告。

它的三阶段模型:

Phase做什么是否写长期记忆
Light整理和暂存近期短期材料
REM反思主题和重复想法
Deep评分并提升 durable candidates是,写入 MEMORY.md

Deep phase 的候选提升不是随便写。官方列出评分信号包括 frequency、relevance、query diversity、recency、consolidation、conceptual richness。候选还要通过 score、recall frequency、query diversity 等门槛。

这说明 Dreaming 的定位不是“每天自动把所有日记塞进长期记忆”,而是带阈值、可审查的后台提炼。

10. Active Memory 是回复前召回

多数记忆系统是 reactive:主 Agent 想起来才查,或者用户明确说“记住这个”“搜索记忆”才查。Active Memory 解决的是另一类问题:在生成主回复之前,给系统一次有边界的机会先找相关记忆。

官方定义:Active memory 是 optional plugin-owned blocking memory sub-agent,运行在 eligible conversational sessions 的主回复之前。

它适合:

  • 持久用户偏好。
  • 反复出现的个人习惯。
  • 需要自然延续感的长期上下文。

它不适合:

  • 自动化任务。
  • 内部 worker。
  • one-shot API 调用。
  • 不应该隐藏个性化的场景。

默认建议从 direct-message sessions、queryMode: "recent"、较短 timeout 开始,因为它在主回复路径上,会直接影响延迟。

11. Memory Wiki 是知识层,不替代记忆层

memory-wiki 是 bundled plugin,用来把 durable memory 编译成更像知识库的 vault。

它不替代 active memory plugin。官方分工是:Active memory plugin,例如 memory-core、QMD、Honcho,拥有 recall、semantic search、promotion、dreaming、memory runtime;memory-wiki 拥有 compiled wiki pages、provenance-rich syntheses、dashboards、wiki-specific search/get/apply。

Memory Wiki 适合你希望记忆更像“维护过的知识层”,而不是一堆 Markdown 日记。它可以提供:

  • deterministic page structure。
  • structured claims and evidence。
  • contradiction and freshness tracking。
  • generated dashboards。
  • compiled digests。
  • wiki_searchwiki_getwiki_applywiki_lint

实践规则:泛化召回一段记忆先用 memory_search;跨 memory 和 wiki 做广义召回用 memory_search corpus=all;需要来源、可信度、页面结构时用 wiki_search + wiki_get;要维护 claims、contradictions、freshness 时用 memory-wiki

12. 写记忆的判断标准

不是所有信息都应该写入记忆。

建议按这个顺序判断:

flowchart TD
  A[New information] --> B{Will it matter after this session?}
  B -- No --> X[Do not write]
  B -- Yes --> C{Stable and durable?}
  C -- Yes --> D[MEMORY.md]
  C -- No --> E{Useful for current workstream?}
  E -- Yes --> F[memory/YYYY-MM-DD.md]
  E -- No --> G[Maybe commitment or scheduled task]

高质量记忆通常满足:

  • 可复用:未来任务会再次用到。
  • 可验证:不是猜测或情绪化印象。
  • 可压缩:一句话能说明用途。
  • 有边界:知道适用范围和过期条件。

低质量记忆通常是:

  • “用户今天说了很多话”这种流水账。
  • “某个任务做到一半”但没有后续价值。
  • 没有来源的推断。
  • 已经过期的临时状态。

长期记忆写得越乱,Agent 后续越容易自信地引用错误背景。

记忆不是越多越好。低质量长期记忆会污染未来判断,比没有记忆更难排查。

13. 给 Agent 的实践任务

把下面任务交给你的 OpenClaw Agent:

请检查你的记忆系统状态:
1. 说明你的 workspace 记忆文件布局:MEMORY.md、memory/、DREAMS.md 是否存在。
2. 用 memory_search 查询“用户偏好”和“当前项目约定”,说明返回了哪些结果。
3. 用 memory_get 读取最相关的一条记忆来源。
4. 判断这些内容应该保留在 daily note,提升到 MEMORY.md,还是不应该长期保存。
5. 如果搜索为空,给出 memory status、status --deep、index --force 的排障顺序。

你要观察它有没有分清楚:

  • 文件存在不等于已索引。
  • 已索引不等于会自动进上下文。
  • daily note 不等于长期记忆。
  • Dreaming 不等于默认自动提炼。
  • Memory Wiki 不等于替代 memory-core

14. 本章自检

读完这一篇,你应该能回答:

  1. OpenClaw 为什么说没有 hidden state?
  2. MEMORY.mdmemory/YYYY-MM-DD.mdDREAMS.md 分别是什么?
  3. Context 和 Memory 的边界在哪里?
  4. memory_search 为什么要同时用 vector search 和 BM25?
  5. memory flush 和 compaction 的关系是什么?
  6. Dreaming 为什么默认 disabled?
  7. Active Memory 适合哪些会话,不适合哪些任务?
  8. Memory Wiki 和 active memory plugin 的分工是什么?

能回答这些问题,再看下一篇上下文管理,就能理解为什么“写进记忆”和“进入本轮 prompt”仍然是两件事。

15. 接下来去哪

16. 官方资料

本页目录