記憶系統撐到了極限
跑了四個月的 AI agent,記憶目錄(memory/)膨脹到 37 個檔案。聽起來不多,但仔細一看:
- 日常日誌(
2026-03-12.md、2026-03-13.md…)佔大多數 - 混雜著主題檔(
sso-booking.md、cramclaw-webhook.md) - 還有 session 元數據(只有 5 行的 session key/id)
- 甚至有一個
.html檔案不知道怎麼混進來的
Agent 每次啟動要讀今天和昨天的日誌,加上 MEMORY.md 長期索引。理論上這套系統能運作,但實際上出了幾個問題。
問題一:日誌噪音
每天的日誌什麼都記——閒聊、debug 過程、中間嘗試、最終結論。當你搜尋「WireGuard 設定」,會找到五天前的 debug 記錄,卻找不到最終的設定方案,因為那被埋在某天日誌的第 200 行。
問題二:知識碎片化
同一個主題散落在不同日期的日誌裡。咖啡研究在 3/10、3/18、3/23 都有,但沒有一個統一的地方彙整「我目前對 Soup Method 的理解」。Agent 沒辦法回答「關於 X 我知道什麼」——它只能回答「某天發生了什麼跟 X 有關的事」。
問題三:重複與矛盾
知識庫(Obsidian notes)裡有 377 個筆記,掃描後發現 9 組重複(18 個檔案)。同一個技術方案在 02-Areas/Tech/ 和 01-Projects/ 各有一份,內容略有差異。哪個是對的?都不完全對。
借鏡:Harness Engineering 的 Entropy Management
2026 年 AI 工程圈開始談 Harness Engineering——不只是讓 agent 能做事,而是控制它做事的品質。三個支柱:
- Context Engineering:給 agent 什麼資訊
- Architectural Constraints:限制 agent 的行為邊界
- Entropy Management:防止系統隨時間退化
記憶系統的問題本質上是 entropy 問題。沒有主動管理,資訊會自然趨向混亂——重複累積、過時不清、碎片分散。
ByteRover 提出了 Context Tree 的概念:用層次化的樹狀結構組織記憶,而不是扁平的日期序列。NLAH 論文(arXiv:2603.25723)則指出,agent 的工作記憶和長期記憶應該分開管理,定期做整合。
這些概念很好,但多數實作需要額外的工具或資料庫。我想要一個純檔案、零依賴的方案。
兩層架構:Journal + Knowledge
核心想法:把「發生了什麼」和「學到了什麼」分開存。
workspace/
├── memory/ # Layer 1: Journal(時序日誌)
│ ├── 2026-03-28.md # 今天發生的事
│ ├── 2026-03-27.md # 昨天發生的事
│ └── archive-2026-03/ # 5 天前的自動歸檔
├── notes/ # Layer 2: Knowledge(語意知識庫)
│ ├── areas/ # 按主題分類(咖啡、技術、基礎設施...)
│ └── resources/ # 工具/服務參考
├── MEMORY.md # 長期索引(P0/P1/P2 分級)
└── reference/ # 深度參考文件
分類決策樹
每次記憶寫入前,過一個簡單的分類:
這是「發生了什麼」還是「學到了什麼」?
├─ 發生了什麼 → memory/YYYY-MM-DD.md
│ └─ 重要到值得長期索引?→ 同時更新 MEMORY.md
├─ 學到了什麼
│ ├─ 已有相關筆記?→ 合併到現有筆記
│ ├─ 新主題且超過 500 字?→ notes/ 建新檔
│ └─ 碎片不到 500 字?→ 先放日誌,等 cron 整理
└─ 不確定?→ 放日誌(安全選項)
關鍵原則是合併優先——寫入前先搜尋有沒有相關的筆記,有就追加,不要每次都建新檔案。這是控制 entropy 的核心手段。
第一步:清理現有的混亂
先處理存量,再改架構。
日誌歸檔
memory/ 只保留最近 5 天的日誌。超過的全部移到 archive-YYYY-MM/:
# 把 03-24 之前的日誌全部歸檔
for f in memory/2026-03-{12..23}*.md; do
mv "$f" memory/archive-2026-03/
done
14 個檔案歸檔。session 元數據、html 檔案也一併清掉。memory/ 從 37 個檔案降到 13 個。
筆記去重
用 sub-agent 掃描 377 個筆記,找到 9 組重複。處理策略:
- 內容較完整的保留
- 另一份移到
04-Archive/merged/ - 合併後的筆記補上缺失的資訊
8 組合併完成(16 → 8 檔),加上 4 個過時筆記歸檔。最終 377 → 365 個活躍筆記。
YouTube 筆記修復
5 個 YouTube 筆記缺少 frontmatter status 欄位,補齊。
第二步:打通搜尋
清理完成後,要讓 memory_search 能搜到 notes/ 裡的知識。OpenClaw 支援 memorySearch.extraPaths 設定:
{
"memorySearch": {
"extraPaths": ["notes/areas", "notes/resources", "reference"]
}
}
設定後,embedding 索引會把這些目錄下的 .md 檔案也納入。搜尋「Soup Method」不再只找到某天日誌裡的片段,而是直接命中主題筆記。
一個小坑:Gemini 免費 tier 的 embedding API 有 rate limit,401 個檔案不可能一次索引完。解法是寫一個自動重試的 cron,每 10 分鐘嘗試一次,完成後自動通知並移除自己:
#!/bin/bash
INDEXED=$(openclaw memory status 2>&1 | grep "Indexed:" | head -1)
CURRENT=$(echo "$INDEXED" | grep -oP '\d+(?=/)')
TOTAL=$(echo "$INDEXED" | grep -oP '(?<=/)\d+')
if [ "$CURRENT" -ge "$TOTAL" ]; then
# 完成,移除 cron
crontab -l | grep -v "memory-index-retry" | crontab -
openclaw message send --message "Memory index 完成: $INDEXED"
exit 0
fi
openclaw memory index --force
第三步:更新寫入規則
架構改了,寫入規則也要跟著改。更新了三個地方:
AGENTS.md(agent 的操作手冊)
兩層記憶:journal(memory/ 時序日誌)+ knowledge(notes/ 語意知識庫)
- Journal:事件、決策、狀態變更。保留 5 天,之後歸檔。
- Knowledge:主題知識。合併優先,不新建碎片。
- 不在 memory/ 放主題檔:主題知識進 notes/,memory/ 只放日期 journal
save-memory skill
分類決策從扁平的「P0/P1/P2 加上 notes/reference/learnings」改成先判斷 journal vs knowledge,再決定具體存放位置。
cron-memory-sync
每小時的記憶同步腳本本來就會把 memory/ 的內容整理到 Obsidian 筆記。現在加上更明確的規則:合併到現有筆記,不要建碎片檔。
清理前後對比
| 指標 | Before | After |
|---|---|---|
memory/ 活躍檔案 | 37 | 13(-65%) |
notes/ 活躍筆記 | 377 | 365(-3%) |
| 重複筆記組 | 9 組 | 0 |
| 缺 frontmatter | 5 | 0 |
memory_search 範圍 | memory/ only | memory/ + notes/ + reference/ |
數字上的變化不是重點。重點是資訊流向變清晰了:
對話 ──→ memory/YYYY-MM-DD.md(發生了什麼)
──→ notes/areas/(學到了什麼)
──→ MEMORY.md(長期索引)
↓
memory_search 全部搜得到
這套架構的局限
誠實說幾個還沒解決的問題:
索引延遲。Gemini 免費 tier 的 rate limit 意味著新加入的 notes 不會立即被索引。目前是靠重試 cron 漸進完成,但在索引完成前,搜尋會有盲區。
合併判斷。「這個知識應該合併到哪個現有筆記」是一個需要語意理解的判斷。目前交給 agent 自己決定,偶爾會判斷錯。
歸檔時機。5 天的 rolling window 是拍腦袋定的。太短可能錯過需要回顧的近期事件,太長又回到噪音問題。目前沒有數據支持最佳值。
跨層一致性。journal 裡記了一個決策,knowledge 裡也有相關筆記,兩邊的資訊可能不一致。rumination(反芻)機制理論上能抓到矛盾,但實際上覆蓋率有限。
下一步
幾個想嘗試的方向:
- reference/ 搬進 notes/:目前
reference/是獨立目錄,但語意上它就是 knowledge 的一部分。合併後統一入口。 - 自動合併建議:cron 定期掃描 notes/,用 embedding 相似度找出可能該合併的筆記,生成建議清單。
- memory hit tracking:追蹤哪些 notes 被
memory_search命中最多次,用來判斷哪些知識最有價值、哪些可以歸檔。
記憶系統不是建一次就完成的東西。它跟程式碼一樣需要重構——只是重構的不是邏輯,而是資訊的組織方式。
這是 AI agent 記憶系列的第三篇。前兩篇:OpenClaw 記憶管理:從零到自迭代的架構演化、讓 AI Agent 學會做夢:記憶的睡眠循環機制。
