我有一個用 OpenClaw 搭的 AI 助手,平常幫我做各種事——專案管理、code review、查資料、回訊息。用了幾個月之後,最大的痛點浮現了:它需要記住越來越多東西,但記憶方式很蠢。
怎麼蠢呢?每次對話開始,就把一堆 markdown 檔案整包塞進 context。專案慣例、技術規範、開發守則……二十幾個檔案全部載入。簡單暴力,確實有效,但 token 燒得我肉痛。
所以我花了一整天把知識庫遷移到向量資料庫。然後隔天又改回來了。
原本的做法:檔案就是記憶
一開始的設計很樸素:每個專案的知識寫成一份 markdown,像是 coding-conventions.md、db-naming-rules.md、api-patterns.md 之類的。Agent 啟動時全部載入,塞進 system prompt。
好處顯而易見——精確、完整、可預測。你知道 Agent 看到了什麼,它知道的就是你寫下來的,不多不少。Debug 的時候也好追蹤,打開檔案就能看到 Agent 的「知識庫」是什麼。
壞處也很明顯:
- 22 個知識檔,載入後吃掉大量 context window
- 不是每次對話都需要所有知識,但你不知道這次會需要哪些
- 隨著知識越加越多,token 用量線性成長
- 超過 context window 上限就只能硬砍,砍了又怕漏
就像你出門把家裡所有工具書都塞進背包一樣。安心是安心,但背不動。
向量遷移:看起來很美好
某天看到 LanceDB 的介紹,覺得這根本就是為我的場景設計的——嵌入式向量資料庫,不用開額外服務,直接跑在本地。於是動手遷移。
把 22 份 markdown 檔案濃縮成大約 30 筆知識條目,每筆控制在 500 字以內,盡量原子化。用 Jina 的 embedding model 做向量化,加上 reranker 做二次排序。
檢索架構是 hybrid retrieval:
- 向量相似度佔 70%
- BM25 關鍵字匹配佔 30%
hardMinScore設 0.35,低於這個分數的結果直接丟掉
聽起來很專業對吧?我自己設計完也覺得挺帥的。
測試的時候效果也不錯——問「Controller 的命名規則是什麼?」能正確召回相關條目;問「資料庫欄位怎麼命名?」也能找到 DDL 規範。token 用量從「每次塞滿」變成「只取需要的」,省了至少 60%。
好,完美。收工。
然後現實打臉了
遷移完的隔天,Agent 在做 code review 的時候漏掉了一條重要的 coding convention。
我追查原因:那條規則確實在向量資料庫裡,但 Agent 當時的 query 跟那條規則的語義距離不夠近,similarity score 低於 0.35 的門檻,被過濾掉了。
這讓我意識到一個根本性的問題:
向量查詢的結果是「可能相關」,檔案載入的結果是「確定完整」。
當你做開發規範這種需要精確執行的事情,你要的不是「大概率相關的前 5 筆」,你要的是「所有規則,一條都不能漏」。漏掉一條命名規則,可能就是一個 PR 要打回重做。
向量搜尋的本質是 approximate——它很擅長在大量資料中快速找到「可能有關」的東西,但它不保證完整性。你沒辦法對一個向量查詢說「給我這個主題的所有規則」,因為它不理解「所有」這個概念。它只理解「跟你的 query 最像的 top-K」。
折返:混合模式才是正解
糾結了一陣子之後,我決定不全用向量,也不全用檔案,而是走混合模式。
flowchart TD
A[Agent 遇到決策點] --> B{知識類型?}
B -->|精確規範| C[檔案系統]
B -->|模糊查詢| D[向量資料庫]
C --> C1[載入完整規範檔]
C1 --> E[執行決策]
D --> D1[Hybrid Retrieval]
D1 --> D2[Vector 70% + BM25 30%]
D2 --> D3[Reranker 二次排序]
D3 --> E
E --> F{新知識產生?}
F -->|是| G[判斷歸屬]
G -->|開發規範| H[更新檔案]
G -->|經驗教訓| I[存入向量 DB]
F -->|否| J[完成]
style C fill:#2ecc71,color:#fff
style D fill:#4a9eff,color:#fff
分工邏輯是這樣的:
檔案系統負責「精確」的東西
- 開發規範、命名慣例、code review checklist
- 這些是「必須 100% 遵守」的規則
- 寧可多塞幾個 token,也不能漏掉任何一條
向量資料庫負責「靈活」的東西
- 過去踩過的坑、debug 經驗、設計決策的理由
- 跨專案的知識關聯(某個客戶的坑可能跟另一個客戶相關)
- 不需要每次都載入,用到的時候再查就好
用一個不太精確但還蠻傳神的類比:向量資料庫就像二進制,機器原生、高效、但人不好讀;檔案系統就像 JSON,人機皆讀、好維護、但體積大。你不會把所有東西都存二進制,也不會把所有東西都存 JSON。
Context-Driven Recall:不預載,按需查詢
混合模式裡有一個重要的設計決策:不再開場就載入所有知識。
取而代之的是 context-driven recall——在每個決策點,根據當前的上下文去查詢可能相關的知識。
比如說 Agent 要幫我寫一個新的 API endpoint,它不需要在對話一開始就知道所有的 coding conventions。它需要的是:
- 在設計 Controller 的時候,查一下 Controller 的命名規則
- 在寫 DAL 的時候,查一下 DataModel 的慣例
- 在寫 SQL 的時候,查一下 DDL 命名規範
每個步驟只載入那個步驟需要的知識。這樣 context window 的使用效率大幅提升,而且因為查詢的語境更精確,向量搜尋的準確率也更高。
當然,這對 Agent 的「自我意識」要求比較高——它要知道自己在做什麼、這個步驟需要什麼知識、去哪裡查。這部分要靠好的 system prompt 設計,告訴它「在每個決策點,先查相關慣例再行動」。
自動擷取的雜訊問題
還有一個踩到的坑值得一提。
向量資料庫有一個 autoCapture 功能——自動從對話中擷取重要資訊存入知識庫。聽起來很棒吧?Agent 自己會學習!
結果它學了一堆垃圾。
對話中的 metadata、操作步驟的記錄、甚至「Maple 說了 OK」這種東西都被當成「知識」存了進去。幾天之後向量資料庫裡面塞滿了這種無意義的條目,查詢結果的品質明顯下降——因為那些垃圾條目也在搶排名。
解法是定期清理,但更根本的解法是不要無條件信任自動擷取。有價值的知識應該是人(或 Agent 在明確指令下)主動存入的,不是從對話流裡隨便撈的。
這就像你不會把會議逐字稿直接當作知識庫——你會整理出會議結論和行動項目,然後只存那些。
向量記憶的衛生守則
折騰了這一輪之後,我整理出幾條向量記憶的衛生守則:
- 每筆知識控制在 500 字以內——太長的條目 embedding 品質會下降,而且召回後佔 token
- 原子化——一筆知識只講一件事。不要把「Controller 命名規則」和「DAL 命名規則」塞在同一筆
- 不存重複內容——向量資料庫不會自動去重,你存了三筆差不多的東西,查詢結果前三名可能都是它們
- 定期清理——autoCapture 產生的雜訊、過時的資訊、測試用的條目,每隔一段時間掃一次
- 存完立刻驗證——存入後馬上用 recall 查一次,確認能查到、分數合理。查不到就改寫重存
沒有完美的記憶架構
折騰了一整天遷移到向量,隔天又花半天改回混合模式。看起來好像白做工了?
其實不是。這個過程讓我搞清楚了一件重要的事:記憶架構的選擇取決於你對「精確度」和「靈活度」的需求比例。
如果你的 Agent 主要做的是創意發想、資料蒐集、開放式問答——全向量可能就夠了,因為你要的是「聯想」和「靈活」。
如果你的 Agent 要執行嚴格的規範、遵循特定的流程——純檔案更安全,因為你要的是「確定」和「完整」。
大部分 Agent 的場景介於兩者之間,所以混合模式通常是比較務實的選擇。
重點不是技術多花俏,是它能不能可靠地在正確的時候給你正確的知識。這聽起來像廢話,但在被向量搜尋的 approximate 特性坑了一次之後,我對「可靠」這兩個字有了更深的體會。
如果你也在做 AI Agent 的知識管理,我的建議是:先從檔案開始,等你真的感受到「token 不夠用」的痛了,再考慮向量化——而且只向量化那些「不需要 100% 完整」的部分。精確的規範,就讓它安安靜靜躺在 markdown 裡吧。