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. 官方資料

本頁目錄