這是我們在 OpenClaw 系統實作記憶機制的心得,也是對「讓 AI Agent 學會做夢」一文的延伸。我們不談論文,只談踩過的坑和做出來的解法。


為什麼 AI Agent 需要記憶?

不是所有 LLM 應用都需要記憶。一個回答使用者問題的客服機器人,問完就可以忘了;一個生成文案的工具,用完就走。但當 Agent 需要 長期運行累積經驗理解上下文,情況就完全不同了。

我們的 OpenClaw Agent 需要:

  • 記住使用者的偏好(他喜歡高密度資訊,不愛廢話)
  • 記住基礎設施的狀態(哪台機器開了、哪個服務掛過)
  • 記住決策的來龍去脈(當初為什麼選這個方案)

沒有記憶,每次對話都是獨立的瞬間,Agent 永遠是新手。這就是我們要解決的問題。


難題一:壓縮 — context window 有限,保留什麼?

問題

即使是 GPT-5.4 或 Claude 4.6,context window 終究有限。當記憶累積超過臨界點,你不可能把全部東西都塞進去。壓縮不是選項,是必然。

但壓縮代表選擇。選擇本身就是困難的:

  • 哪些對話值得記住?
  • 抽象化(summarization)會不會丟失關鍵細節?
  • 如果壓縮演算法選錯了重要資訊,後果是什麼?

業界做法

常見的壓縮策略有幾種:

方法說明缺點
簡單摘要LLM 產出濃縮版本容易遺漏細節,無法精確檢索
向量檢索存 embedding, query 時召回只能搜「相似」,無法知道「重要」
優先級排序依重要性決定保留顆粒度依賴準確的優先級判斷

我們的做法

我們採用 三層記憶架構,用「分層」取代「一次性壓縮」:

daily memory(便簽)→ MEMORY.md(長期)→ reference/(結構化知識)

  • daily memory:每天的 raw 紀錄,像貼在冰箱上的便利貼
  • MEMORY.md:萃取後的長期知識,需要主動維護
  • reference/:結構化資料(設定檔、API 文件、流程 SOP)

同時搭配 P 級優先級

等級保留時間範例
P0永久個人偏好、基礎設施配置
P190 天技術決策、專案進展
P230 天實驗記錄、臨時觀察

這不是最優解,但實際運行下來,足夠實用。我們發現 P 級判斷比任何複雜的壓縮演算法都可靠——因為它直接對應「這件事過期後還有價值嗎?」

學到的教訓

一開始我們試過全自動摘要,結果某次維護紀錄被摘要成「伺服器正常」,實際上那是凌晨三點搶修的災難紀錄。壓縮的資訊損失是隱性的,爆發時你才會發現。

所以我們後來改成「高層次用摘要,低層次用歸檔」——不強求把所有東西壓進 context,而是用分層 + 過期的機制,讓 context window 裡永遠是「最近相關」的東西。

2026-03 更新:社群出現了 lossless-claw 這樣的方案——用 SQLite 保留 100% 原始對話,DAG 分層摘要取代截斷。這和我們的三層架構思路一致:不要丟東西,而是分層壓縮。差別在於 lossless-claw 作用在 session 內的 context window,我們的方案作用在跨 session 的長期記憶。兩者可以共存。


難題二:演化 — 記憶不是靜態的

問題

記憶不是寫入後就靜止的。使用者的偏好會變:

「上次你說不要問,直接做。」「不對,我現在需要你先確認。」

知識也會過時:

「那個 API 去年改過了。」「這台機器已經換 IP 了。」

當記憶和現實脫節,Agent 會給出過時的建議,甚至可能造成損害。

業界做法

  • 時間戳記:每條記憶加時間,query 時過濾
  • 版本化:不覆蓋,永遠存新版本
  • 主動刷新:定時重新驗證記憶的正確性

我們的做法

我們用 兩個自動化腳本 來處理演化問題:

1. memory-reflect.sh(反芻)

每天 21:00 執行,對比「今天的記憶」vs「長期記憶」:

  • 檢測矛盾(例如:今天記「偏好用 Qwen」,但長期記「偏好用 Claude」)
  • 檢測過時(例如:三個月前提到的 API 版本)
  • 產出整合建議(哪些記憶該更新、哪些該合併)

這不是簡單的比對,而是一次 LLM 對話。讓模型自己判斷:「這兩條資訊衝突了,我該相信哪個?」

實際運行後發現,reflect 最大的價值不是「糾錯」,而是 發現隱性矛盾。有些偏好我們自己都沒意識到在漂移,Agent 反而看見了。

2. memory-expire.sh(過期歸檔)

每月 1 號執行,超過 30 天的 daily memory 自動搬到 archive/。不是刪除,是歸檔——哪天需要回溯,還是可以查出來。

# 實際邏輯(簡化版)
if [[ "$P_LEVEL" == "P2" && "$DAYS_SINCE" -gt 30 ]]; then
    mv "$file" "archive/"
fi

學到的教訓

一開始我們只有「定期刪除」,沒有「歸檔」。結果某次需要回溯三個月前的決策,發現什麼都沒了。現在我們相信:寧可多存,不可錯殺。 歸檔比刪除安全。


難題三:衝突 — 新舊記憶矛盾時怎麼辦?

問題

這是三個難題中最麻煩的。

使用者今天說「用 Telegram」 但長期記憶裡寫的是「用 LINE」

是新記憶對了,還是舊記憶對了?或者,兩者都對(因為情境不同)?

業界做法

  • 最後寫入優先(Last-Write-Wins)
  • 手動解決(交給人類裁判)
  • 多重版本並存(不解決,只標記)

我們的做法

memory-reflect.sh 的矛盾檢測就是為這題設計的。當偵測到衝突,腳本會:

  1. 標記:註明哪些記憶互相矛盾
  2. 分析:LLM 判斷情境(是偏好改變?還是情境不同?)
  3. 建議:產出「整合建議」,告訴人類(或 agent)該怎麼處理
# 輸出範例
## 矛盾檢測
- [daily] 偏好用 Telegram 傳送訊息
- [MEMORY] 偏好用 LINE 傳送訊息
→ 建議:更新 MEMORY.md,註記「近期改用 Telegram」

但這裡有個實務問題:不是所有矛盾都需要解決。有些矛盾是因為情境變了(家裡 vs 公司),有些是因為偏好真的改了。我們的原則是:

  • 低風險矛盾:不主動干預,等累積夠多再處理
  • 高風險矛盾(例如安全設定):立即警告

學到的教訓

我們曾經試過「發現矛盾就立刻修正」,結果造成過度反應——使用者只是隨口說說,結果長期記憶被改亂了。

現在的做法是 「觀察 → 累積 → 驗證 → 行動」:讓矛盾累積一陣子,確認是趨勢而非雜訊,再由 reflect 統一處理。


我們的答案:讓 Agent 學會「睡覺」

把三個難題的解法拼在一起,就是我們的 記憶睡眠循環

時間腳本作用
每天 21:00memory-reflect.sh反芻:矛盾檢測 + 整合建議
每週日 03:00memory-dream.sh做夢:跨領域洞察(8 個隨機片段)
每月 1 號memory-expire.sh過期歸檔:30 天以上的 daily memory 搬家

為什麼叫「睡眠」?

因為這三個腳本都在 非工作時間 執行。Agent 醒著的時候處理請求,睡著的時候整理自己。這和人類睡眠時大腦做記憶整合的概念類似——不是一直在輸入,而是在適當的時候處理

dream.sh 在做什麼?

這是我們最「瘋狂」的實驗。每週日凌晨,系統隨機抽 8 個 memory 片段(可能是三週前的技術筆記、兩天前的使用者偏好、一個月前的故障記錄),讓 LLM 試著找「跨領域洞察」。

老實說,大部分產出是廢話。但偶爾會出現意想不到的觀點:

「你上個月處理過 WireGuard MTU 問題,上週又遇到 Docker network 問題。這兩者都涉及網路層,可能需要一個通用的網路除錯 SOP。」

這是 冷記憶聯想——平時不會放在一起想的東西,在做夢模式下被強制湊對,說不定能產生新的洞見。


結語:實用的記憶系統

這篇文章沒有提出什麼新穎的理論。我們只是在面對「AI Agent 需要長期記憶」這個實際問題時,一步一步堆出來的做法。

三層架構、P 級優先、sleep cycle——每一個設計都是為了回答一個具體問題:

  1. 壓縮 → 用分層取代全量摘要
  2. 演化 → 用 reflect + expire 自動處理過時
  3. 衝突 → 用 reflect 統一檢測和整合

如果你也在做類似的事情,我們的 workspace-template 是開源的:

github.com/kindomLee/openclaw-workspace-template

裡面包含所有提到的腳本(memory-dream.sh、memory-reflect.sh、memory-expire.sh),歡迎取用、批評、改進。

記憶系統沒有終極解答。我們的解法也不見得適合所有人。但如果你被「到底要留什麼」或者「記憶越來越亂」困住,希望這篇分享能給你一些方向。


如果喜歡這篇文章,或想看我們更多關於 AI Agent 實作的筆記,歡迎追蹤我們的 blog。