前言

當你給一個 AI agent 一台 VPS、一堆 API key、和一個空白的工作區,它要怎麼「記住」東西?

這篇記錄了我在 OpenClaw 上建構 AI agent 記憶系統的過程——從最初的空白 MEMORY.md,到現在帶有優先級標籤、自動過期清理、事件時間軸的結構化架構。不是教學文,而是真實的踩坑記錄。


第零天:空白的開始

OpenClaw 啟動時,工作區裡有四個檔案:SOUL.md(人格設定)、USER.md(使用者資訊)、AGENTS.md(行為規範)、和一個空的 MEMORY.md

Agent 每次醒來(新 session)都是失憶狀態——它只知道人格和行為規範。所有對話、決策、偏好,隨著 session 結束就消失了。

第一個問題:agent 要怎麼知道「上次我們聊到哪了」?


第一階段:Daily Files(流水帳)

最自然的做法:每天一個 markdown 檔,如 memory/2026-01-26.mdmemory/2026-01-27.md,記錄當天發生的事。

格式很自由——## 標題 分段,裡面就是對話摘要、設定紀錄、debug 過程。Agent 在每次 session 開始時讀今天和昨天的 daily file,大概知道最近在幹嘛。

好處: 簡單、自然、寫入無摩擦。

壞處:

  • 兩週前的事?要翻十幾個檔案。
  • 「上次 OpenClaw 升級是什麼時候?」→ 沒人記得在哪個 daily file 裡。
  • 重要決策淹沒在日常瑣事中。

第二階段:MEMORY.md(策展式長期記憶)

Daily file 是流水帳,MEMORY.md 是策展。

想法很簡單:把真正重要的東西從 daily file 「升級」到 MEMORY.md。Agent 每次啟動都讀這個檔案,等於它的「核心記憶」。

最初的 MEMORY.md 很簡單:分成 Profile(基本資料)、Infrastructure(系統設定)、Preferences(偏好)三個區塊,各放幾條 bullet point。

問題來了:誰來維護?

答案是——人工。我(或 agent 在我要求下)定期把 daily file 裡的重要內容搬到 MEMORY.md。這顯然不可持續。


第三階段:Priority Tags + Memory Janitor

MEMORY.md 只增不減,很快就膨脹了。每個區塊的重要性不同:基礎設施設定是永久的,但某次 espresso 實驗的參數可能一個月後就沒用了。

解法:優先級標籤 + 自動過期清理。

每個 ## 標題後面加上標籤:

  • [P0] — 永久保留(個人資料、基礎設施、核心偏好)
  • [P1] [日期] — 90 天後自動歸檔
  • [P2] [日期] — 30 天後自動歸檔

例如:

## Infrastructure [P0] → 永不過期 ## X Timeline Scraping [P1] [2026-02-01] → 90 天後歸檔 ## Espresso [P2] [2026-02-15] → 30 天後歸檔

配套的 memory-janitor.py 每天 20:00 跑一次,自動掃描過期區塊。不刪除,只是搬到 archive——萬一需要還找得到。

實際跑起來長這樣:14 個章節全部在保留期內,P1 的 X Timeline Scraping 已過 17 天(上限 90 天),P2 的 Espresso 才 3 天(上限 30 天)。


第四階段:借鑑 OpenViking 的記憶分類

字節跳動開源了 OpenViking——一個專為 AI agent 設計的上下文數據庫。它的記憶分類啟發了我們重新整理 MEMORY.md

六類記憶:

類別用途我們的對應
Profile使用者基本資料## Mark Profile [P0]
Preferences偏好和習慣## Mark Preferences [P0]
Entities相關實體## Mark Entities [P0]
Events事件時間軸## Events Timeline [P0]
Agent Cases解決過的問題## Agent Cases [P0]
Agent Patterns可重用最佳實踐## Agent Patterns [P0]

其中 Agent CasesAgent Patterns 是最有價值的新增。

Agent Cases 記錄解決過的具體問題。例如「Cron sub-agent 發送失敗」這個 case,記了問題(target 寫 “mark” 而非 chat ID)、解法(改靠 announce 機制)、和可重用模式(isolated session 永遠不要自己發訊息)。

Agent Patterns 記錄可重用的最佳實踐,像是「三段式 pipeline」(腳本抓取 → agent 摘要 → 腳本發送)和「驗證四防線」(創建 → 執行 → 送達 → 失敗告警)。

Agent 遇到類似問題時,可以直接套用已知的解法,而不是從頭踩坑。


第五階段:L0 索引 + Events Timeline + 自動提取

最新一輪改進來自一場「agent 辯論」——我 spawn 了兩個 sub-agent:

  1. 架構設計 agent:提出完整的三級索引方案(L0 routing、自動提取 pipeline、結構化 extraction format)
  2. Devil’s advocate agent:把方案批得體無完膚

Devil’s advocate 的核心批評:

這份方案的根本問題是在 3KB 的記憶系統上設計了一套適合 30KB+ 系統的架構。目前的瓶頸不是檢索效率,而是「有沒有記下來」。

最終收斂出的極簡版:

L0 Comments(文檔自描述)

每個 ## 區塊加一行 HTML comment 作為摘要,例如 Infrastructure 區塊下面加一行 <!-- L0: VPS, HA, NAS, WireGuard, Chrome CDP -->

不寫索引腳本、不拆檔案——3KB 的檔案不值得做 routing。但 L0 comment 讓人和 agent 都能一眼掃到每個區塊在講什麼。

Events Timeline(時間軸索引)

在 MEMORY.md 頂部加一個按月分組的事件列表,每條一句話、≤80 字,只記結論不記過程。像是「02-17 多 Instance cron 洩漏修復」、「02-14 Memory Janitor 上線」。

回答「上次 X 是什麼時候」再也不用翻 daily file。

自動提取規則

AGENTS.md 加了一段話:

重要對話結束時,直接 edit MEMORY.md 對應區塊追加記錄。觸發條件:新決策、設定變更、新知識。不觸發:閒聊、簡單查詢、重複 routine。

沒有結構化格式、沒有暫存檔、沒有去重機制——這些都是 devil’s advocate 砍掉的「過度設計」。最簡單的規則往往最持久。


現在的架構全貌

整個記憶系統由四層組成:

  • MEMORY.md — 策展式長期記憶,14 個區塊,含 Events Timeline、Profile、Infrastructure、Agent Cases、Agent Patterns 等
  • memory/*.md — 每日流水帳(daily files)
  • memory/archive/ — 過期章節歸檔
  • notes/ — Obsidian vault(PARA 結構),每小時 cron 同步

資料流很直覺:對話中產生的內容即時寫入 daily file,重要事件同步寫入 MEMORY.md,每小時同步到 Obsidian,每天 20:00 由 memory-janitor 清理過期內容。


學到的事

  1. 從簡單開始。 空白 MEMORY.md → daily files → 策展式長期記憶。每一步都是被真實痛點推動的,不是預先設計的。

  2. 讓 devil’s advocate 砍掉你的設計。 架構設計 agent 提出了很酷的三級索引系統。Devil’s advocate 指出 3KB 檔案不需要 routing。結果省了一堆無意義的基礎建設。

  3. Agent Cases 是最有價值的記憶類型。 比個人偏好、比基礎設施設定都有價值。因為它直接減少了「重複踩坑」的次數。

  4. 過期機制必須從第一天就有。 否則 MEMORY.md 會膨脹到 agent 自己都讀不完。P0/P1/P2 + janitor 是最小的可行方案。

  5. 「有沒有記下來」比「怎麼檢索」重要十倍。 在記憶系統很小的時候,最大的風險不是找不到,而是根本沒記。自動提取規則解決的就是這個問題。


這篇文章由 Mark 和他的 OpenClaw agent 協作完成。agent 從 memory files 取材、整理結構、撰寫初稿,Mark 提供方向和最終確認。