這是我們在 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 | 永久 | 個人偏好、基礎設施配置 |
| P1 | 90 天 | 技術決策、專案進展 |
| P2 | 30 天 | 實驗記錄、臨時觀察 |
這不是最優解,但實際運行下來,足夠實用。我們發現 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 的矛盾檢測就是為這題設計的。當偵測到衝突,腳本會:
- 標記:註明哪些記憶互相矛盾
- 分析:LLM 判斷情境(是偏好改變?還是情境不同?)
- 建議:產出「整合建議」,告訴人類(或 agent)該怎麼處理
# 輸出範例
## 矛盾檢測
- [daily] 偏好用 Telegram 傳送訊息
- [MEMORY] 偏好用 LINE 傳送訊息
→ 建議:更新 MEMORY.md,註記「近期改用 Telegram」
但這裡有個實務問題:不是所有矛盾都需要解決。有些矛盾是因為情境變了(家裡 vs 公司),有些是因為偏好真的改了。我們的原則是:
- 低風險矛盾:不主動干預,等累積夠多再處理
- 高風險矛盾(例如安全設定):立即警告
學到的教訓
我們曾經試過「發現矛盾就立刻修正」,結果造成過度反應——使用者只是隨口說說,結果長期記憶被改亂了。
現在的做法是 「觀察 → 累積 → 驗證 → 行動」:讓矛盾累積一陣子,確認是趨勢而非雜訊,再由 reflect 統一處理。
我們的答案:讓 Agent 學會「睡覺」
把三個難題的解法拼在一起,就是我們的 記憶睡眠循環:
| 時間 | 腳本 | 作用 |
|---|---|---|
| 每天 21:00 | memory-reflect.sh | 反芻:矛盾檢測 + 整合建議 |
| 每週日 03:00 | memory-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——每一個設計都是為了回答一個具體問題:
- 壓縮 → 用分層取代全量摘要
- 演化 → 用 reflect + expire 自動處理過時
- 衝突 → 用 reflect 統一檢測和整合
如果你也在做類似的事情,我們的 workspace-template 是開源的:
github.com/kindomLee/openclaw-workspace-template
裡面包含所有提到的腳本(memory-dream.sh、memory-reflect.sh、memory-expire.sh),歡迎取用、批評、改進。
記憶系統沒有終極解答。我們的解法也不見得適合所有人。但如果你被「到底要留什麼」或者「記憶越來越亂」困住,希望這篇分享能給你一些方向。
如果喜歡這篇文章,或想看我們更多關於 AI Agent 實作的筆記,歡迎追蹤我們的 blog。
