---
title: "04 · OpenClaw 的记忆系统：短期、长期、可检索记忆"
description: "解释 OpenClaw 如何用 Markdown 文件、记忆搜索、压缩前保存和 Dreaming 组成可审查的记忆系统。"
verifiedAt: "2026-05-06"
---

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

结论先说：

> [!TIP]
> 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. 后续仍然需要加载或搜索到上下文里，模型才能使用。

```mermaid
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`。

```text
~/.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 里有没有这条信息 | 是 | 否 |
| 信息有没有落盘 | 否 | 是 |
| 下次会话还能不能找回 | 不一定 | 有机会 |
| 会不会受模型上下文窗口限制 | 是 | 文件本身不受本轮窗口限制 |
| 模型能否直接使用 | 能，前提是已经在上下文里 | 不能，必须先加载或搜索回来 |

一个简单例子：

```mermaid
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. 检索回来了，但被后续上下文或系统指令稀释。

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

> [!IMPORTANT]
> 写进 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 会越来越多，不能指望每一条旧日记都自动进入每一轮上下文。

```mermaid
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_search` 和 `memory_get`

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

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

`memory_search` 的关键是 hybrid search：

```mermaid
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 通常可以自动工作。也可以显式配置：

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

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

排障时先跑：

```bash
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，避免旧上下文被摘要后丢失细节。

> [!NOTE]
> Memory flush 不是万能自动记忆，而是 compaction 前的一次保护动作：先把值得保留的事实落盘，再压缩上下文。

```mermaid
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 配一个独立模型：

```json
{
  "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_search`、`wiki_get`、`wiki_apply`、`wiki_lint`。

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

## 12. 写记忆的判断标准

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

建议按这个顺序判断：

```mermaid
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 后续越容易自信地引用错误背景。

> [!WARNING]
> 记忆不是越多越好。低质量长期记忆会污染未来判断，比没有记忆更难排查。

## 13. 给 Agent 的实践任务

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

```text
请检查你的记忆系统状态：
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.md`、`memory/YYYY-MM-DD.md`、`DREAMS.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. 接下来去哪

<Cards>
  <Card href="/docs/openclaw/understanding/05-context-management" title="05 · Context 管理" description="继续看哪些信息会进入本轮上下文，以及上下文太长时 OpenClaw 怎么处理。" />
  <Card href="/docs/openclaw/understanding/03-agent-brain" title="03 · Agent 的大脑" description="回到 Agent loop，确认记忆工具如何进入模型-工具循环。" />
  <Card href="/docs/openclaw/official/01-gateway-runtime/agents" title="官方教程：Agents" description="对照官方 Agents 页继续看 workspace、runtime、tools 和 agent 配置。" />
</Cards>

## 16. 官方资料

- [Memory Overview](https://docs.openclaw.ai/concepts/memory)
- [Memory Search](https://docs.openclaw.ai/concepts/memory-search)
- [Compaction](https://docs.openclaw.ai/concepts/compaction)
- [Dreaming](https://docs.openclaw.ai/concepts/dreaming)
- [Active Memory](https://docs.openclaw.ai/concepts/active-memory)
- [Memory Wiki](https://docs.openclaw.ai/plugins/memory-wiki)
- [Memory CLI](https://docs.openclaw.ai/cli/memory)
