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。
這意味著三件事:
- 使用者在聊天裡說過,不等於長期記住。
- 寫進檔案,才有跨會話複用的機會。
- 後續仍然需要載入或搜尋到上下文裡,模型才能使用。
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 失憶”通常有三種不同根因:
- 當時沒有寫入記憶檔案。
- 寫入了,但沒有被載入或檢索回來。
- 檢索回來了,但被後續上下文或系統指令稀釋。
不要只說“記憶壞了”,要先判斷是哪一層的問題。
寫進 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_search 和 memory_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_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. 寫記憶的判斷標準
不是所有資訊都應該寫入記憶。
建議按這個順序判斷:
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. 本章自檢
讀完這一篇,你應該能回答:
- OpenClaw 為什麼說沒有 hidden state?
MEMORY.md、memory/YYYY-MM-DD.md、DREAMS.md分別是什麼?- Context 和 Memory 的邊界在哪裡?
memory_search為什麼要同時用 vector search 和 BM25?- memory flush 和 compaction 的關係是什麼?
- Dreaming 為什麼預設 disabled?
- Active Memory 適合哪些會話,不適合哪些任務?
- Memory Wiki 和 active memory plugin 的分工是什麼?
能回答這些問題,再看下一篇上下文管理,就能理解為什麼“寫進記憶”和“進入本輪 prompt”仍然是兩件事。
15. 接下來去哪
05 · Context 管理
繼續看哪些資訊會進入本輪上下文,以及上下文太長時 OpenClaw 怎麼處理。
03 · Agent 的大腦
回到 Agent loop,確認記憶工具如何進入模型-工具迴圈。
官方教程:Agents
對照官方 Agents 頁繼續看 workspace、runtime、tools 和 agent 配置。