「讓 LLM 知道你的私有資料」是 Agentic SaaS 最常見的需求之一。RAG(Retrieval-Augmented Generation)是目前最成熟的解法,但它比 demo 裡看起來複雜得多:選什麼向量庫、怎麼切塊、召回品質如何量測、記憶分幾層管理——每個環節都有工程取捨。

RAG 的基本架構

索引階段(離線)

  1. 把文件切成小塊(chunks)
  2. 每個 chunk 用 embedding model 轉成向量
  3. 把向量和原始文字存入向量資料庫

查詢階段(線上)

  1. 把用戶問題轉成向量(用相同 embedding model)
  2. 在向量庫做相似度搜索,取回 top-k 相關 chunks
  3. 把 chunks 塞進 LLM 的上下文(context)
  4. LLM 根據這些 retrieved context 回答問題

這個流程看起來簡單,但有四個環節容易出問題:

分塊策略(Chunking)

分塊是 RAG 品質的核心變數,卻是 demo 裡最常被忽略的。

固定大小分塊(Fixed-size,按 token 數切):實作最簡單,但會在句子中間斷開,破壞語意完整性。常用大小 512 tokens,有 50-100 token 的 overlap 減少邊界遺失。

語意分塊(Semantic chunking):用 embedding 相似度判斷語意邊界,同一主題的段落放在同一 chunk。理論上品質更好,但計算成本高、邊界判斷本身也可能出錯。

文件結構分塊(Structural chunking):按 markdown 標題、HTML tag、PDF 段落邊界分塊。在有良好結構的文件(技術文件、法律文件)上效果好;非結構化文字效果有限。

Parent-child 分塊:把文件切成小 child chunks 用於高精度向量搜索,同時保留對應的大 parent chunk 作為 LLM 的實際上下文。Google 的 RAG best practices 文件和 LlamaIndex 均推薦這個模式(這是主張,有大量工程師驗證,但缺乏嚴格對照實驗)。

向量資料庫的選型

主流選項的工程特性:

工具特性適用場景
pgvector(PostgreSQL extension)在現有 Postgres 裡加向量搜索,運維成本低資料量 < 1M 向量,希望用 SQL 做 hybrid search
Pinecone全托管,無需自建,支援 metadata filtering快速上線,不想管基礎建設
Weaviate開源,內建 hybrid search(BM25+向量)需要語意+關鍵字混合搜索
Qdrant開源,高性能,支援 payload filtering向量量大、需要複雜 filter

「用什麼向量庫最好」是個取捨問題,不是技術優劣問題。pgvector 在資料量小、希望減少系統複雜度時是合理選擇;Pinecone 在需要快速驗證時省事;Weaviate/Qdrant 在有 hybrid search 需求時有優勢。

召回品質:Pure Vector 的局限

Pure vector search 的致命弱點是精確比對(exact match)。如果用戶問「LLM01 是什麼」而文件裡只有「Prompt Injection」的段落,向量相似度可能不夠高,即使語意上是同一件事。反之,如果搜索「帳戶」而文件有「account」(不同語言),向量通常能搭橋,但關鍵字搜索不行。

業界普遍的解法是 Hybrid Search:向量搜索和 BM25/TF-IDF 關鍵字搜索結果用 Reciprocal Rank Fusion(RRF)合併排名。這是個工程主張(業界廣泛實作),但「最佳 hybrid 權重」依資料分布和任務性質不同,沒有放諸四海的答案。

記憶的分層架構

RAG 是「知識庫召回」,但一個完整的 Agentic SaaS 還需要更細緻的記憶分層:

In-context memory(上下文記憶) 直接放在 LLM 當前請求的 context window 裡的資訊:system prompt、近期對話、被召回的 chunks。有上限(Claude 200K tokens、GPT-4o 128K),且每 token 都有 API 費用。Context window 再大,也不適合把整個知識庫塞進去(成本和延遲都不可接受)。

Semantic memory(語意記憶/向量召回) 就是 RAG 在做的事:把大量知識存在向量庫,按需搜索取回相關片段。適合「靜態或緩慢變化的知識」(產品文件、FAQ、法規)。

Episodic memory(事件記憶) 用戶的歷史操作、過去的對話摘要、已完成的任務記錄。通常存在結構化資料庫(PostgreSQL)或 KV store,按 user_id 和 session_id 索引。Stanford Generative Agents(Park et al., 2023)用 recency × importance × relevance 三維評分決定哪些歷史事件值得召回——這個框架在學術上是已發表的研究,但工業實作中各家取捨不同。

Procedural memory(程序記憶) Agent 學到的技能、工作流程、已知的工具使用模式。最難實作,目前多以 fine-tuning 或精心設計的 few-shot examples 近似——這個分層的工程實作尚未成熟,業界沒有統一做法。

知識庫的新鮮度問題

RAG 最容易被忽略的問題是:知識庫的索引怎麼跟上資料的變化?

文件更新後,舊的 chunks 仍然在向量庫裡,會被召回並給 LLM 看過時的資訊。常見的工程解法:

  • 每個 chunk 記錄 source_doc_idupdated_at;文件更新時刪除舊 chunks 重新索引
  • 增量更新比全量重索引效率高,但需要仔細追蹤文件版本
  • 重要文件在 prompt 裡標注資訊截止日期,讓 LLM 在回答時有機會判斷是否過時

「知識庫的更新頻率」和「重索引的成本與複雜度」之間的取捨,是 RAG 系統上線後最常被低估的維運問題。

延伸