懶人包:ANNsmemory(外掛名cognitive-memory)是一個 Claude Code 認知記憶外掛,用 Go 寫的memctlbinary 當唯一寫入者,把 AI 的記憶拆成 episode / semantic / procedural 三種節點,存進一個你自己掌控的 git repo(~/.claude-memory),跨專案、跨機器都能 recall。它解的是我手寫 memory 檔最痛的兩個坑:索引脫鉤、同主題長出三胞胎。本文拆它的架構、安裝、四個指令、三種節點,附實測踩坑與 FAQ。
📌 目錄
- 為什麼我想試一個「認知記憶」外掛
- ANNsmemory 到底是什麼
- 核心設計:為什麼 Go binary 要當唯一寫入者
- 安裝:三步驟接到 Claude Code
- 四個指令怎麼用
- 三種記憶節點:episode / semantic / procedural
- 跟手寫 memory 檔比,差在哪
- 我預期會踩的坑
- 常見問題 FAQ
- 🔗 延伸資源
🧠 為什麼我想試一個認知記憶外掛
我自己用 Claude Code 很久,記憶這塊一直是手刻的:~/.claude/memory/ 底下一堆 feedback_*.md、reference_*.md,外加一份 MEMORY.md 當索引。這套能用,但維護起來有兩個老問題。
第一個是索引脫鉤。我新增了一個 memory 檔,卻忘了同步更新 MEMORY.md,結果這條記憶下次 session 根本不會浮出來——它存在,但等於沒存。
第二個是三胞胎。同一個主題,我這次寫 feedback_X.md、下次又反射性開 feedback_X_v2.md,三個檔 70% 內容重疊,越長越散。我後來甚至寫了一段「寫 memory 前必跑 ls 找既有檔」的硬規則來擋這件事——但這是靠自律,靠自律的東西遲早會破。
所以當我看到 ANNsmemory 這個外掛的設計——用一個 Go 程式當唯一能改檔的人,LLM 只能起草、不能親手寫 frontmatter——我第一個反應是:這正面解了我那兩個坑。索引由程式產,不靠記得;分類由程式判,不靠自律。本文就是把它拆開來看值不值得接。
⭐ ANNsmemory 到底是什麼
ANNsmemory 是一個 Claude Code 外掛,外掛名叫 cognitive-memory,作者是 White(謝智宇),MIT 授權。它把自己定位成「神經認知式的外部記憶系統」,講白話就是:給 Claude Code 一個持久、結構化、跨專案的長期記憶,而且 recall 的結果是可重現的(deterministic scoring,同樣輸入給同樣排序)。
它跟一般「在 repo 裡放幾個 .md 筆記」最大的差別,在於它有一個明確的資料模型和一個確定性的引擎:
| 維度 | 一般 memory 筆記 | ANNsmemory |
|---|---|---|
| 寫入者 | 你 / LLM 自由編輯 | 只有 memctl(Go binary) |
| 結構 | 自由 Markdown | 三型節點 + typed frontmatter |
| 索引 | 手動維護 | 由 memctl 衍生(derived) |
| Recall | 靠 grep / 靠記得 | 確定性加權檢索 |
| 跨專案 | 自己複製貼上 | global pool + 每專案 projection |
| 跨機器 | 自己同步 | git-backed pool |
⚖️ 核心設計:為什麼 Go binary 要當唯一寫入者
這是整個外掛我覺得最聰明、也最值得學的一條設計原則:single writer(單一寫入者)。
規則很簡單——只有 memctl 這支 Go binary 可以寫 frontmatter,LLM 只負責起草 prose(內文文字)。為什麼要這樣切?因為 LLM 寫結構化欄位(node_id、scope、weight、timestamp)很容易出包:日期格式飄、欄位拼錯、id 撞號。一旦結構壞了,整個 recall 的可信度就崩了。把寫入權收斂到一支確定性的程式,schema 就不會被「順手改一下」搞爛。
整個儲存結構長這樣:
~/.claude-memory/ # 你自己掌控的 git repo(authoritative pool)
├── episodes/ # 專案範圍的經驗
├── semantics/ # 概念 / 規則(預設 global)
├── procedures/ # 可重複的任務流程(預設 global)
├── archive/ # 歸檔
├── index.md # 由 memctl 衍生,別手改
└── .memctl/ # schema、migrations
<project>/.memory/ # 每個專案的輕量投影
├── index-local.md # projection,也是 derived
└── .project # 釘住專案 slug
關鍵點:~/.claude-memory 是權威池(authoritative pool),每個專案底下的 .memory/ 只是一個投影(projection)——它不是另一份真相,而是從池子衍生出來的本地視圖。這個「一份真相、多處投影」的設計,正是手寫筆記做不到的:你不會再有「這台機器的 memory 跟那台不一樣」的問題。
它還有一條我很喜歡的硬約束:memctl 只接受絕對路徑、禁止 ../ 逃逸、不准寫進 .claude/ 或專案根目錄。記憶池永遠待在 .memory/ 子目錄裡。這種「把寫入面積縮到最小」的紀律,是內部工具最該有的安全感。
⚡ 安裝:三步驟接到 Claude Code
ANNsmemory 走 Claude Code 的 plugin marketplace 機制,預編譯 binary 已經 commit 進 repo,所以安裝時不需要 build 步驟。
先確認前置依賴
| 依賴 | 最低版本 | 驗證指令 |
|---|---|---|
| Claude Code | 支援 /plugin 指令的版本 | claude --version |
| Git | 任意近代版本 | git --version |
| GitHub 認證 | 能存取該 repo | gh auth status |
注意:這是一個私有 marketplace,/plugin marketplace add 會走你的 GitHub 認證。沒權限就會 add 不進去。
一鍵指令
在 Claude Code 裡依序執行:
/plugin marketplace add SmallWhite-TW/ANNsmemory
/plugin install cognitive-memory@cognitive-memory-marketplace
如果 marketplace 解析有問題,README 提供了顯式 git URL 的 fallback:
/plugin marketplace add git@github.com:SmallWhite-TW/ANNsmemory.git
驗證裝好了沒
裝完後,輸入 /cognitive-memory: 應該能看到四個指令補全出來(recall / remember / consolidate / memory-migrate)。如果 auto_session_recall 是預設的 true,下次開新 session 時會在 session-start 被動注入相關記憶——這就是 round-trip 確認它真的活著的方式:不是看「安裝成功」字串,是看新對話開頭有沒有把舊記憶帶進來。
📝 四個指令怎麼用
外掛對外暴露四個 slash 指令,背後各對應一個 skill:
| 指令 | 對應 skill | 做什麼 |
|---|---|---|
/cognitive-memory:recall | memory-recall | 針對當前任務,撈出相關的記憶節點 |
/cognitive-memory:remember | memory-store | 把新知識分類、寫成結構化節點 |
/cognitive-memory:consolidate | hippocampus | 提出優化建議(升級 / 歸檔) |
/cognitive-memory:memory-migrate | memory-migrate | 把舊的記憶結構匯入進來 |
remember 在你想存一條知識時觸發:LLM 起草內容、判斷它屬於哪一型節點,但真正落檔由 memctl 寫。recall 則是把當前任務當查詢,做一次確定性加權檢索,把相關節點拉回上下文。
consolidate 比較有意思——它對應的 skill 直接叫 hippocampus(海馬迴),負責提案式的記憶整理:哪些 project 節點用得夠頻繁、該升成 global;哪些太久沒被 activate、該進 archive。它只提案,不擅自動手,符合 single-writer 的謹慎調性。
memory-migrate 預設是 dry-run,先給你看會怎麼搬,確認後才加 --apply 真寫:
/cognitive-memory:memory-migrate # 預設 dry-run,只看不寫
# 檢視結果,確認 OK 後再用 --apply 落地
它的 parser 蠻寬容的:能吃沒有 frontmatter 的檔、能認三種不同的 node_id 命名法、缺 TLDR 會自動合成並標記。對我這種已經有一堆手寫 memory 檔的人,這條等於是「升級路徑」而不是「砍掉重練」。
🗂️ 三種記憶節點:episode / semantic / procedural
ANNsmemory 把記憶分成三型,這個分類學我覺得是它最有「認知科學」味道的地方:
episode:YYYY-MM-DD-slug → 專案範圍的經驗(這天、這個專案、發生了什麼)
semantic:slug → 概念 / 規則(預設 global,到處都適用)
procedural:slug → 可重複的任務流程(預設 global)
對應到人的記憶:episode 是「事件記憶」(我那天踩了什麼坑),semantic 是「語意記憶」(這個概念是什麼、這條規則為什麼成立),procedural 是「程序記憶」(這個流程怎麼跑)。
每個節點帶一組 typed 欄位:node_id、type、title、created_at、project、scope、tags、weight、activation_count、last_activated、tldr。
scope 只有兩個值,但這兩個值決定了 recall 行為:
| scope | 行為 |
|---|---|
global | 到哪個專案都吃滿權重 |
project | 只在它出生的那個專案吃滿權重 |
recall_cross_project_weight(預設 0.40)控制:別的專案的記憶不是不出現,而是以 0.4 的背景權重出現——既不會完全失聯,也不會喧賓奪主。這個「背景權重」的設計,比我手寫筆記那種「全有或全無」細緻多了。
⚖️ 跟手寫 memory 檔比,差在哪
我直接把它跟我現在這套手寫 memory/*.md + MEMORY.md 索引對照:
| 痛點 | 手寫 memory | ANNsmemory |
|---|---|---|
| 索引脫鉤(新檔忘了登記) | ✗ 常發生,靠自律 | ✓ 索引由 memctl 衍生 |
| 同主題三胞胎 | ✗ 靠「寫前先 ls」自律 | △ 有 consolidate 提案,但仍需你按 |
| Recall 可重現 | ✗ 靠 grep / 靠記得 | ✓ 確定性加權 |
| 跨機器一致 | ✗ 自己同步 | ✓ git-backed pool |
| schema 不被寫壞 | ✗ 隨手可改 | ✓ single-writer 鎖死 |
| 上手成本 | ✓ 零,就是寫 .md | △ 要懂節點模型 + 一次 migrate |
consolidate 提案,不是自動合併,最後還是要你點頭——但至少把「要不要合」這件事顯性化、排到你面前,而不是埋在一堆散檔裡等你哪天自己發現。
對我來說,最有價值的不是某個指令,是那條 single-writer 原則。它把「記憶會不會壞」這個風險從「靠人小心」變成「結構上不可能」。這是我會想把它搬進自己工作流的真正理由。
🕳️ 我預期會踩的坑
我還在評估接入,以下是從它的 README 約束推出來、我預期一定會撞到的幾點,先記下來:
私有 marketplace 的認證
/plugin marketplace add SmallWhite-TW/ANNsmemory 走 GitHub 認證。如果你的 gh 當前 active 帳號沒有該 repo 權限,會 add 不進去。先 gh auth status 確認,必要時切到有權限的帳號——這跟我之前 push 撞到「預設 active 帳號是另一個」是同一類坑。
index.md 千萬別手改
~/.claude-memory/index.md 和每個專案的 index-local.md 都是 derived(衍生) 的——它們由 memctl 產生,不是讓你編的。手改了下次 index-rebuild 會被覆蓋,白做工。記憶要進去一律走 remember,別繞過 binary 直接編檔。
git 衝突要自己收
它把 ~/.claude-memory 當 git repo,但不自動 commit——memctl 只會回報 git.is_repo,commit 的節奏由你自己掌握。多機器同時改、又忘了先 pull,就會撞 conflict。它的解法是 memctl index-rebuild 重建索引,但前置的 merge 還是 git 那一套,得自己處理。
migrate 先 dry-run,別直接 --apply
memory-migrate 預設 dry-run 是有道理的。我打算先看完它怎麼分類我那堆 feedback_* / reference_*,確認 episode/semantic/procedural 分得對,再 --apply。直接 apply 等於讓它一次重組我整個記憶庫,風險太大。
❓ 常見問題 FAQ
Q1:ANNsmemory 跟直接在專案裡放 .md 筆記有什麼不同?
最大差別是「誰能寫」跟「索引怎麼來」。手寫筆記是你自由編、索引手動維護;ANNsmemory 只有 memctl 能寫 frontmatter、索引由程式衍生,所以不會有索引脫鉤、schema 被改壞的問題,recall 也是確定性的。
Q2:它需要我會寫 Go 嗎?
不用。它 95.5% 是 Go 沒錯,但 binary 已經預編譯 commit 進 repo,marketplace 安裝時不會 build。你只會用到四個 slash 指令,碰不到 Go 原始碼。要自己改才需要 make build(會交叉編譯 darwin/linux × arm64/amd64)。
Q3:記憶存在哪?換電腦會不會不見?
存在 ~/.claude-memory,這是一個你自己掌控的 git repo。換機器就把這個 repo 同步過去即可(它不自動 commit,commit 節奏你自己抓)。每個專案底下的 .memory/ 只是投影,不是另一份真相。
Q4:跨專案的記憶會互相污染嗎?
不會無差別污染。節點有 scope:project 範圍的記憶只在原專案吃滿權重;其他專案的記憶以 recall_cross_project_weight(預設 0.4)的背景權重出現——既保留跨專案聯想,又不會喧賓奪主。
Q5:我已經有一堆舊 memory 檔,能直接搬進來嗎?
能。用 /cognitive-memory:memory-migrate,預設 dry-run 先給你看搬法。它的 parser 容錯度高:吃得下沒有 frontmatter 的檔、認三種 node_id 命名法、缺 TLDR 會自動補並標記。確認分類正確後再 --apply。
🔗 延伸資源
- ANNsmemory GitHub repo — 原始碼、README、marketplace 設定
- Claude Code Plugins 官方文件 —
/plugin marketplace機制怎麼運作 - Andrej Karpathy 談 LLM「作業系統」與記憶 — 為什麼 LLM 需要外部結構化記憶
- 我用 Claude Code skill 把發文流程自動化的踩坑記錄 — 同樣是「把自律換成結構」的思路