讓 OpenClaw 找得回以前聊過的事:用本機 EmbeddingGemma 建立長期記憶語意搜尋
前幾天我請 OpenClaw 幫我下載兩篇醫學論文,接著又想找回前面處理過的相關紀錄。原本以為這只是很普通的記憶搜尋,沒想到查下去才發現:記憶檔都還在,直接讀取也沒有問題,但卻無法進行近似概念的語意搜尋,後來才發現是「跨檔案語意搜尋的向量索引」這個功能其實還沒有建立。
AI 明明「記得」資料放在哪裡,為什麼換一種問法就找不到?
原因是對 AI agent 來講:把紀錄留下來,和日後找得回來,是兩種不同能力。
OpenClaw 原本就會把值得保留的資訊寫進 MEMORY.md、每日記憶檔與相關文件。而這次配置的本機 Embedding,負責把這些記憶內容建立向量索引,讓我不必記得原句、檔名或日期,也能用類似概念的自然語言跨檔案搜尋,而這也才符合我們正常人類生活中的實際用法,不然誰有辦法每次都用一模一樣的關鍵字?
我想要的長期記憶,不是什麼都存
OpenClaw 熱潮之後,另一套 AI Agent「Hermes Agent」也受到不少關注。它的官方文件主打跨 session 保存記憶、搜尋歷史工作階段,以及逐步累積使用者偏好與專案脈絡。這類設計讓 AI 用久之後,更有「它知道我以前做過什麼」的感覺。
本文不打算深入比較兩套 Agent。對我來說,Hermes 比較像一個容易理解的參照:OpenClaw 把既有記憶內容向量化之後,同樣可以做到「以前處理過的事情,就算換句話問,還是有機會找回來」。
不過我個人更喜歡選擇性記憶。我不需要每一次臨時問答、測試指令或隨手嘗試,都進入主要的長期記憶索引。哪些內容值得留下,可以由我和 Agent 決定,再寫進長期記憶或每日紀錄。以後搜尋時少一點雜訊,也不必讓大量用完即丟的內容一直累積。
換句話說,OpenClaw 本機 Embedding 補上的是「語意召回」,不會自動替我判斷所有事情的重要性,也不等於複製另一套 Hermes Agent 的使用者建模或自我學習功能。
區別 OpenClaw 的三種「記憶」存取方式
在介紹 Embedding 相關設置以前,我想把「讀取記憶」和「搜尋記憶」區分成三種情況。
已知檔案時,直接讀取
如果已經知道內容在 MEMORY.md,或知道是哪一天的記憶檔,OpenClaw 可以直接打開指定內容。這不需要 Embedding,也不需要向量資料庫。
記得明確字詞時,用關鍵字搜尋
假如還記得 PMID、工具名稱、workflow 名稱或某個特殊詞,傳統全文搜尋通常就能找到。OpenClaw 的內建記憶引擎使用 SQLite,也支援 FTS5 關鍵字搜尋。
只記得意思時,用語意搜尋
真正麻煩的是:記得以前做過這件事,卻忘了當時用了什麼標題、寫在哪一份檔案,甚至連原本的說法都想不起來。
這時候 Embedding 才派得上用場。它會找「意思接近」的內容,不要求查詢文字和原文一模一樣。
Embedding 到底做了什麼?
用最白話的方式說,Embedding 模型會把一段文字轉成一組數字,讓電腦可以比較兩段文字在語意上接不接近。
OpenClaw 的處理流程大致如下:
MEMORY.md/每日記憶檔
→ 切成較小的文字區塊
→ Embedding 模型轉成向量
→ 寫入 SQLite 索引
→ 查詢文字也轉成向量
→ 比較相似度,找回相關片段
→ 交給目前的思考模型整理答案這裡的 EmbeddingGemma 不是聊天模型。它不會替我閱讀論文,也不會自己回答問題。它做的是前面的「從過往記憶快速找資料」,找到相關片段後,才交給我目前使用的 Codex OAuth 思考模型理解與回答。
OpenClaw 的內建記憶引擎還會把向量相似度與傳統關鍵字結果一起參考。實際查看 JSON 結果時,可以看到 vectorScore 和 textScore。前者偏向語意相似度,後者偏向文字命中程度。
圖:記憶檔先經過 EmbeddingGemma 建立本機向量索引;日常提問時,Agent 再從索引找回相關片段。
為什麼 Codex OAuth 正常,卻冒出 OpenAI API 額度問題?
這次我遇到 OpenClaw 記憶搜尋索引異常,主要就是嵌入模型沒有手動正確設定。
我的對話與推理模型走 Codex OAuth,日常使用完全正常。我也從未訂閱 OpenAI API,照理說不該突然出現 API 額度問題。後來檢查才確認,Codex OAuth 與 OpenAI Embeddings API 是兩套不同的授權路線。
OpenClaw 目前的內建記憶引擎若沒有明確指定 memorySearch.provider,預設會使用 OpenAI embeddings。於是系統嘗試呼叫 text-embedding-3-small 建立索引,卻沒有可用的 OpenAI API 計費額度,最後回傳 429 insufficient_quota。
這不代表我們用完 OpenAI API 額度,只是這條 Embeddings API 路線原本就沒有可用額度。Codex OAuth 能使用 GPT 模型,也不表示它同時包含 Embeddings API。
我們可以改接一個可用的雲端 Embedding provider,也可以讓模型留在本機執行。我最後評估後選擇後者。
雲端 Embedding 和本機模型,我怎麼選?
我手上原本就有幾家雲端服務的 API key,所以先把可行方案測了一輪。
- Google Gemini 的
gemini-embedding-001可以正常呼叫,設定省事、速度也快,但要考慮 API 配額、費用與記憶內容送往雲端。 - NVIDIA 有可用的 Embedding 模型。測試時用正確的環境 API key,
nvidia/nv-embedqa-e5-v5可正常回傳向量。 - Ollama 與 LM Studio 也能在本機提供 Embeddings API,但服務必須啟動,並另外載入適合的 Embedding 模型。
- 我測試當時,Groq 與 Agnes 的模型清單中沒有可直接使用的 Embedding 模型。
最後我選 OpenClaw 的 local provider,理由很單純:沒有 API 費用,記憶內容留在本機,也不用為了這件事另外維持 Ollama 或 LM Studio 服務。
安裝 llama.cpp provider 與 EmbeddingGemma
這些指令要在哪裡輸入?
我這篇文章的環境是 Windows 加上 WSL Ubuntu,所以接下來看到的指令,都是在 WSL 的 Ubuntu 終端機中執行,不是貼到 OpenClaw 對話框,也不是輸入 Windows 的 CMD。
如果你是第一次接觸 WSL,可以從 Windows 開始功能表搜尋並開啟「Ubuntu」。畫面出現類似 使用者名稱@電腦名稱:~$ 的提示文字後,就可以把指令貼在 $ 後面。$ 只是提示符號,不用跟著輸入。
不確定自己有沒有進入正確環境,可以先執行:
openclaw --version看得到 OpenClaw 版本,通常就代表找對地方了。如果你的 OpenClaw 原本是安裝在原生 Linux、macOS 或其他環境,請在當初安裝 OpenClaw、能正常執行 openclaw 指令的終端機操作。重點是所有安裝、設定與索引指令都要在同一個 OpenClaw 執行環境完成。
我使用的 OpenClaw 版本是 2026.6.11,因此把 llama.cpp provider 固定在相同版本:
openclaw plugins install @openclaw/llama-cpp-provider@2026.6.11如果你使用的是較新的 OpenClaw,應先查看目前版本與官方文件,選擇相容的 provider 版本,不必照抄我當時的版號。
接著用三行指令,把 OpenClaw 的記憶搜尋指向本機 provider。openclaw config set 會自動修改 OpenClaw 設定,不需要自己打開設定檔尋找欄位:
openclaw config set agents.defaults.memorySearch.provider local
openclaw config set agents.defaults.memorySearch.fallback none
openclaw config set agents.defaults.memorySearch.local.modelPath 'hf:ggml-org/embeddinggemma-300m-qat-q8_0-GGUF/embeddinggemma-300m-qat-Q8_0.gguf'fallback: "none" 是我刻意保留的設定。如果本機 Embedding 發生問題,我希望它直接報錯,不要在我不知情的情況下改走雲端 provider,將記憶內容送出去。
想確認剛才三項設定是否已寫入,可以執行:
openclaw config get agents.defaults.memorySearch --json第一次執行狀態檢查或建立索引時,系統也會下載 EmbeddingGemma 模型。本次實測模型檔約 313 MB,所以第一次操作前要先確認網路連線正常,並預留一些下載時間。
完成設定後重新啟動 Gateway,再檢查狀態:
openclaw gateway restart
openclaw memory status --deep --agent main第一次建立完整索引:
openclaw memory index --force --agent main--force 會重建全部向量,平常不需要一直執行。OpenClaw 的內建記憶引擎會監看 MEMORY.md 與 memory/*.md 的變更;Gateway 運作中,只要記憶檔新增或修改,通常約 1.5 秒後就會自動進行增量索引,不需要自己設定排程,也不用每次手動更新。
如果新內容一直搜尋不到,或懷疑 Gateway 曾經異常、漏掉檔案變更,才需要手動執行一次增量索引:
openclaw memory index --agent main完整的 --force 重建主要留給更換 Embedding provider、模型、向量切塊設定,或索引資料庫異常等情況。它不是日常維護指令,也不建議固定每週或每月執行。
圖:完成設定後的 memory status。
沒有獨立顯示卡,也能跑嗎?
可以。我這次完整建立索引時,雖然電腦有 RTX 4050 Laptop GPU,但實際上沒有使用 GPU,而是由 CPU 完成。
我的測試環境如下:
- Windows 主機:32 GB RAM
- WSL 當時配置:約 15 GiB
- CPU:Intel Core i7-13700H
- 本機模型:EmbeddingGemma 300M Q8 GGUF,模型檔約 313 MB
- 記憶資料:263 個 Markdown 檔,約 1.1 MB
- 索引結果:1,245 個文字區塊,向量維度 768
第一次強制重建全部索引花了 494.94 秒,約 8 分 15 秒;尖峰記憶體約 587 MB。獨立執行一次命令列搜尋,包含冷啟動載入模型,大約 4 秒,使用約 500 MB RAM。Gateway 已經載入模型後,我曾測到搜尋階段約 76 毫秒。
這些數字是我的單機實測,不是 OpenClaw 官方最低硬體需求。實際速度會受 CPU、記憶檔數量與系統負載影響。
如果只是一般規模的文字記憶,我會把實用建議抓在:現代 64 位元 CPU、至少 4 核心、整機 8 GB RAM 可以使用,16 GB 以上會比較舒服。GPU 可以加快部分工作,但不是必要條件。第一次建立大量索引可能要等一下,後續只更新異動檔案就快得多。
實際搜尋:不用記得原句,也能找回內容
要做有說服力的壓力測試,就不能單純把記憶檔裡的原句複製貼上,而是刻意換成不同於原文的說法。
找回部落格文章歸檔流程
我的記憶中保存過部落格文章完成後,幾個寫作階段留下的檔案應如何收整。測試時我沒有照抄 workflow 名稱,而是這樣問:
openclaw memory search "文章發布後,五個寫作階段留下的資料最後要如何收整" \
--agent main \
--max-results 5 \
--json程式碼中的反斜線 \ 是 Bash 的「下一行繼續」符號,方便把較長指令分行顯示。可以整段複製到 Ubuntu 終端機執行;如果改寫成同一行,就不需要這些反斜線。
第一筆結果正確找到發文收尾與五類資料歸檔紀錄,vectorScore 約 0.742,textScore 為 0。
textScore 為 0 很有意思。這次沒有明顯的關鍵字重疊,結果主要由向量語意召回。當然,0.742 不是 74.2% 正確率,它只是這次排序使用的相似度分數。
圖:第一筆結果的 vectorScore 約 0.742、textScore 為 0。
忘了工具名稱,只記得文獻下載順序
第二個案例是我自己建立的 PubMed Agent workflow。我故意不寫工具名稱,只描述當初設計的處理邏輯:
openclaw memory search "哪套流程會先查 PMID 資料,再找公開全文,找不到才走機構電子資源" \
--agent main \
--max-results 5 \
--json第一筆結果正確找到 PubMed Agent 的全文下載與機構資源 fallback 紀錄,vectorScore 約 0.675,textScore 同樣為 0。
這很接近我平常真正會遇到的情境:我記得以前做過一套流程,也記得大致邏輯,偏偏忘了檔名與位置。以前只能靠自己猜關鍵字,現在可以直接描述「它當時怎麼做」。
搜尋結果仍要人工判讀
語意搜尋不是有結果就算成功。我原本也測過「之前下載的超低劑量免疫治療第三期研究」,結果前三筆沒有穩定命中正確的 DELII 論文紀錄。英文查中文記憶的測試,也可能受到原始記憶中本來就有英文摘要影響。
這兩組我沒有拿來當成功案例。搜尋工具的價值在於提高找回機率,不是保證第一筆永遠正確。正式使用時還是要看來源檔案、片段內容與上下文。
平常使用時,不需要一直開啟終端機
前面使用 WSL 指令,是為了完成安裝、建立索引、檢查狀態,以及把搜尋分數攤開來測試。這比較像設定與排錯工具,不代表日常每次回想舊資料,都要打一次 openclaw memory search。
平常直接在 OpenClaw 的 WebChat、Telegram 或其他對話介面,用自然語言詢問就可以。例如:
我以前是不是設定過一套 PubMed 文獻下載流程?請先搜尋記憶,再告訴我當時的處理順序。
或是:
請搜尋先前的記憶,找出部落格文章發布完成後,各階段資料要如何歸檔。
當記憶搜尋工具可用,而且 Agent 判斷舊紀錄有助於回答時,它可以自行呼叫語意搜尋,再讀取命中的片段整理答案。多數時候不必指定工具名稱;如果想讓測試結果更明確,可以直接加一句「請先搜尋記憶」,避免 Agent 只根據目前對話內容回答。
所以日常使用可以很輕鬆:你只要描述記得的概念,搜尋工具由 Agent 在背後調度。CLI 比較適合第一次安裝、確認索引是否正常、查看分數,或排查為什麼沒有命中。
你可以怎麼測試自己的記憶搜尋?
先確認索引狀態:
openclaw memory status --deep --agent main正常情況下,至少要確認 provider 是 local,Embeddings 與 Semantic vectors 顯示 ready,索引檔案數也符合自己的記憶資料。
一般搜尋:
openclaw memory search "你想找的內容" --agent main --max-results 5這行指令中幾個常見參數的意思如下:
--agent main:指定搜尋主要 Agent 的記憶索引。如果你的 Agent ID 不是main,要換成自己的 ID。--max-results 5:最多顯示 5 筆搜尋結果。它只控制回傳數量,不代表最低分數,也不表示一定會找到 5 筆相關內容。--json:用 JSON 顯示詳細結果,方便查看來源檔案、命中片段、vectorScore與textScore。--min-score 0.4:過濾綜合分數低於 0.4 的結果。這個 0.4 是搜尋排序門檻,不是 40% 正確率。
想看詳細分數與命中片段,可加上 --json:
openclaw memory search "你想找的內容" --agent main --max-results 5 --json結果太雜時,可以設定最低分數:
openclaw memory search "你想找的內容" \
--agent main \
--max-results 10 \
--min-score 0.4測試題目最好不要照抄原文。可以從以下幾種方式改寫:
- 忘記名稱,只描述用途:「哪套流程會先查文獻資料,再依序尋找公開與機構全文?」
- 忘記日期,只描述原因:「Google 授權為什麼每隔幾天就要重新登入,之前怎麼處理?」
- 忘記檔案位置,只描述收尾動作:「文章完成後,各階段資料最後要收去哪裡?」
跨語言也可以測,但不能只看系統有沒有吐出結果。第一筆是不是同一件事、原始記憶中是否本來就有另一種語言,都要一起檢查。
這套做法有哪些限制?
本機向量索引讓記憶更容易搜尋,但它有清楚的邊界。
- 它只搜尋已納入 OpenClaw memory corpus 的內容,不會自動搜尋整顆硬碟。
- 記憶內容寫得太短、缺乏上下文,日後仍可能找不準。Embedding 不會替原本含糊的紀錄補齊背景。
- 選擇性記憶代表取捨。當時沒有寫入、也沒有納入索引的臨時內容,之後自然找不到。
vectorScore是相似度,不是正確率。不同查詢之間也不宜只用單一分數硬比較。- 更換 Embedding provider 或模型後,既有向量不能直接混用,需要重新建立索引。
- 本機方案不花 API 費用,資料也不必送往雲端;代價是第一次建立大量索引通常比較慢。
我最後留下的是「選擇性記憶+語意找回」
這次設定完成後,以前留下的內容並沒有改變。最明顯的差別是:我現在可以換一種說法,快速把它們重新找出來。
我仍然不打算把所有臨時對話都收進長期記憶。真正值得留下的專案決策、工作流程、排錯結果與個人偏好,整理後再交給本機 Embedding 建立索引,已經很符合我的使用方式。
如果你也在使用 OpenClaw,可以先跑一次 openclaw memory status --deep --agent main。接著挑一件自己確定以前記錄過的事,故意不用原本的關鍵字重問一次。如果第一筆結果真的找到了,代表這套語意搜尋已經開始派上用場了。
留言
張貼留言