Claude Code 本地跨 Session 記憶:用 macOS NLContextualEmbedding 做語意搜尋
原文主張
@jonas.jonas.ko 分享自己替 Claude Code 裝了跨 session 記憶,而且完全本地運行。他用外掛方式加了一套記憶系統,不需要改 Claude Code 原始設定;每次開新 session 時,自動把相關舊記憶注入進來。
關鍵不是傳統關鍵字比對,而是 Embedding / 向量搜尋:只要語意接近,就能找到相關記憶。
原文推薦可直接丟給 Claude 的需求句:
幫我用 NLContextualEmbedding 做本地向量搜尋,包成 localhost HTTP server,float32 向量
為什麼 NLContextualEmbedding 值得注意
NLContextualEmbedding 藏在 macOS NaturalLanguage framework 裡,不需要另外安裝大型 embedding model,也不必呼叫外部 API。
它不是簡單字典或關鍵字工具,而是能產生上下文語意向量,適合「意思接近」的搜尋。
資料不需要送到 OpenAI、Anthropic、Voyage、Cohere 或其他 embedding 服務,對私有 session、專案筆記與商業內容更安全。
macOS framework 可由 Swift / Objective-C 包裝成本地 HTTP server,再讓 Python 腳本用普通 HTTP 呼叫,避免 Python 直接橋接 Apple framework 的複雜度。
最小架構
| 層級 | 工作 | 實作要點 |
|---|---|---|
| Memory capture | 從舊 session 擷取可重用記憶 | 不要整段 transcript 全塞;應整理成 100–200 字摘要、決策、偏好、專案規則或踩坑紀錄。 |
| Embedding server | 用 NLContextualEmbedding 產生向量 | 以 macOS 本地 server 包成 /embed API,輸出 float32 vector。 |
| Vector index | 保存記憶與向量 | 小規模可用 JSON / SQLite + numpy cosine similarity;大規模再考慮 sqlite-vss、FAISS 或 LanceDB。 |
| Retrieval | 新 session 開始時查相關記憶 | 用當前任務描述或系統 prompt 摘要作 query,取 top-k。 |
| Injection | 把最相關記憶注入 prompt | 原文做法是只注入前 3 筆,每筆 100–200 字,總成本約 500 token。 |
Token 成本怎麼控制
留言有人問這樣會不會很吃 token。作者回答:不會很誇張,因為只注入前 3 筆最相關記憶,每筆大概 100–200 字摘要,加起來約 500 token。
| 做法 | 優點 | 風險 |
|---|---|---|
| 整份歷史摘要注入 | 簡單、不漏資訊 | token 爆炸、過期資訊干擾、新任務被舊上下文綁架 |
| 關鍵字搜尋注入 | 好實作、可解釋 | 同義詞、語意相近但字面不同的內容容易漏掉 |
| Embedding top-k 注入 | 能找語意相關內容,token 可控 | 需要 embedding 與相似度計算;摘要品質仍然很重要 |
| 人工 pinned memory | 穩定、可控、適合長期規則 | 不適合大量細碎任務經驗;需人工維護 |
本地方案 vs 付費記憶層
留言也有人貼 Nowledge Mem,作者回覆:付費方案省去自己架的麻煩完全合理;他自己走本地方案,是為了搞清楚底層怎麼運作,順便當學習過程。兩條路都能到同一個終點。
重視資料不出機器、想理解底層、願意處理 indexing / retrieval / injection 細節、主要在 Mac 上跑 AI coding workflow 的人。
想跨多工具同步、不想維護 server / index / migration、重視即開即用、願意用費用換維護成本的人。
對 Claude Code / Hermes 類 Agent 的啟發
這篇對任何長期使用 AI coding agent 的人都很有價值。問題不是「AI 會不會記得」,而是要設計一個可控的記憶管線:
- 記憶要先摘要:不要把 raw transcript 當長期記憶;先萃取成偏好、規則、決策、環境事實、踩坑。
- 記憶要可檢索:同一件事不可能永遠靠關鍵字找得到,embedding retrieval 能補足語意落差。
- 記憶要少量注入:每次只拿最相關的 top-k,避免上下文污染。
- 記憶要有壽命:專案進度、PR、issue、短期狀態不應長期注入;穩定規則與可重用流程才值得保存。
- 記憶要能被驗證:涉及環境、憑證、API、路徑、版本的內容,使用前仍要讀檔或查 live state。
可落地的實作草圖
# Conceptual flow POST /embed { "text": "記憶摘要或查詢文字" } → returns { "vector": [float32, float32, ...] }Store memory
memory = { "id": "2026-06-24-001", "text": "專案 X 的 API base 已包含 /api/v1,module 不要重複加 prefix。", "tags": ["project-x", "api", "frontend"], "vector": embed(text) }
Retrieve for new session
query_vector = embed(current_task_summary) results = cosine_similarity(query_vector, memory_vectors) inject top 3 summaries into session context
對 Allen 的實務判讀
Allen / Kate / Hermes 的工作流本來就有長期記憶、skills、session_search 與專案規則。這篇值得收藏的原因是,它提供一個更輕量的本地語意檢索方向:
把過去 session 的高價值摘要轉成本地向量,當 Allen 問「之前那個怎麼處理」或 Kate 需要找相似踩坑時,可比純 FTS 更柔性。
當新任務進來時,用任務描述找相近 skill、經驗檔與過去案例,降低漏載技能或重犯舊錯的機率。
像「不要修改 Telegram config」、「工多多先讀 CLAUDE.md」這類硬規則仍應保留在明確 system / skill / memory 中,不應只靠 embedding 找回。
結論
跨 session 記憶的關鍵,不是把所有過去都塞給模型,而是建立一個本地、可控、可查詢的記憶層。macOS 的 NLContextualEmbedding 提供了一條低依賴路線:不送資料出去、不需額外 embedding 套件、能用 localhost API 服務 Python / agent script。
Source: Threads / @jonas.jonas.ko