從零做一個真的能用的 RAG 知識庫:框架不是第一步,資料清理才是

Community Article
Published June 22, 2026

很多 RAG 教學一開始就裝 LangChain、LlamaIndex、向量資料庫,然後十幾行 code 跑出一個聊天介面。

這種 demo 很適合截圖,不太適合你拿去給公司同事用。

因為真實知識庫最難的不是把 query 丟進 vector DB。最難的是你要讓模型拿到乾淨、正確、版本清楚的資料。資料層沒處理好,後面換什麼模型都只是把垃圾講得更順。

RAG 最早被系統化討論時,重點就是把生成模型和可檢索的外部記憶結合起來。Lewis 等人在 RAG paper 裡講的是 parametric memory + non-parametric memory。今天我們做企業知識庫,也是在做同一件事:模型負責語言和推理,外部資料庫負責可更新事實。

所以第一步不是選框架。

第一步是問:你的資料能不能被機器穩定讀懂?

先定義你的文件物件

不要把 PDF、Notion、網頁、Google Docs 直接丟進去。

先轉成一個標準格式。最少要有:

{
  "doc_id": "pricing_policy_2026_06",
  "title": "Pricing and refund policy",
  "source_url": "https://example.com/pricing",
  "updated_at": "2026-06-01",
  "owner": "billing-team",
  "status": "active",
  "text": "...clean markdown..."
}

為什麼要這麼麻煩?

因為 RAG 壞掉時,你要能追。它引用的是哪份文件?是不是舊版?誰負責維護?這份文件還有效嗎?

如果你只存一段文字,模型答錯時你只能看著向量資料庫發呆。

清理資料比 embedding 更重要

PDF 抽文字會有頁首頁尾。網頁會有導覽列、推薦文章、cookie banner。Notion 匯出會有奇怪的 nested block。客服紀錄裡會混入簽名檔和模板話術。

這些東西如果不清掉,embedding 會很認真地把它們也編進去。

到時候使用者問「退款期限」,系統可能撈到每頁重複的 footer,或一段完全無關的法律聲明。不是模型笨,是你餵它的索引太髒。

建議先做三層處理:

  1. extraction:把來源轉成 markdown 或純文字
  2. cleaning:移除 boilerplate、重複區塊、亂碼
  3. normalization:統一標題、日期、URL、版本欄位

如果你要處理 PDF,至少抽樣人工檢查幾份。尤其是表格和雙欄排版。很多 RAG 在財報、合約、研究報告上出錯,就是 PDF 抽取階段已經壞了。

Chunk 要帶著標題走

切片不要只按 token 數。

比較好的順序是:先照 H1/H2/H3 切,再看段落,最後才按 token 長度補切。每個 chunk 都要保留上層標題。

例如:

{
  "chunk_id": "pricing_policy_2026_06#refund#003",
  "doc_id": "pricing_policy_2026_06",
  "section_path": ["Pricing", "Refund policy", "Enterprise exceptions"],
  "source_url": "https://example.com/pricing#refund",
  "updated_at": "2026-06-01",
  "text": "Enterprise contracts may override the standard 14-day refund policy..."
}

這樣模型看到的不只是文字,還知道這段在哪個脈絡下。

很多人會加 overlap。可以,但不要亂加。Overlap 太多會讓 retrieval 結果看起來有五段,其實都在講同一件事。最後 prompt 被重複內容塞滿,真正需要的補充資料反而進不來。

Retrieval 不是一次搜尋就結束

最簡版 RAG 是 query embedding -> top k chunks。

但實務上常常不夠。

例如使用者問:「Pro 和 Enterprise 的 SSO 權限差在哪?」

這需要找 Pro,也要找 Enterprise,還要找 SSO,不是單一語意相似就能處理。你可以用 multi-query retrieval:先讓模型拆成幾個查詢,再各自檢索。也可以用 HyDE,先生成一段假想答案,再用那段去做 dense retrieval。HyDE 這個方法在 Precise Zero-Shot Dense Retrieval without Relevance Labels 裡有比較完整的討論。它的直覺是:短 query 有時太瘦,先讓模型生成一個「可能相關文件」可以幫 embedding 找到更好的鄰近區域。

但 HyDE 也有風險。它生成的假文件可能有錯,所以後面一定要回到真實 corpus。不要把 HyDE 生成內容當答案,它只是搜尋輔助。

不同 retrieval 做法要拿結果比較,不要只看架構圖

RAG 文章如果只畫「文件 -> embedding -> vector DB -> LLM」那張圖,讀者看完其實還是不知道怎麼選。

比較好的寫法,是直接放一張小型 eval table。不是為了假裝很科學,而是逼自己承認:不同 retrieval 策略在不同題型上差很多。

假設你做一個 50 題內部知識庫評估集,題型包含單點查詢、比較題、版本題、拒答題。你可以用下面這種表格記結果。數字不是通用 benchmark,因為每個 corpus 都不一樣;這種表的價值是讓讀者看到「你真的有測」,不是只憑感覺推薦工具。

Retrieval 設計 Top-5 命中正確 chunk 答案引用正確率 平均延遲 最適合場景 最常見失敗
只用 dense vector search 68% 54% FAQ、語意接近的短問題 語意像但不是答案,尤其容易抓錯版本
BM25 + dense hybrid 78% 63% 中低 有產品名、API 參數、錯誤碼、專有名詞的文件 query 太口語時,keyword match 仍然抓不到
Multi-query retrieval 82% 67% 比較題、多條件問題,例如 Pro vs Enterprise 生成的子查詢太散,會帶入雜訊
HyDE + dense retrieval 80% 61% 原始 query 太短、使用者描述很模糊時 假想文件會引入不存在的細節,需要後面 rerank 壓住
Hybrid + reranker 88% 76% 中高 要上線的客服、sales enablement、內部 policy bot 成本和延遲上升,但通常值得
Hybrid + metadata filter + reranker 91% 82% 中高 有版本、權限、地區、產品線差異的知識庫 metadata 維護很煩,髒資料會直接毀掉結果

這張表的結論很無聊,但很實際:如果只是 demo,dense vector search 很快;如果要上線,通常要 hybrid + rerank + metadata filter。

BM25 這種老方法不要太早丟掉。BEIR benchmark 那篇 A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models 其實也提醒過,retrieval 沒有單一模型能在所有資料集上穩贏。dense retrieval 很會抓語意,但遇到 SKU、錯誤碼、函式名、法條編號、產品版本,keyword signal 仍然有用。

所以我會這樣看:

  • 問題很短、文件很乾淨:dense search 可以先跑
  • 文件有大量專有名詞:加 BM25 / hybrid
  • 問題常常要比較兩個東西:加 multi-query
  • 使用者問法很模糊:可以測 HyDE
  • 要上線給真人用:加 reranker
  • 文件有新舊版本和權限差異:metadata filter 不可省

如果你懶得做完整 benchmark,至少手工測 30 題。每一題記下 top-5 chunks 和最後答案。你會很快看到問題不是「模型不夠強」,而是 retrieval 根本沒把正確資料撈上來。

第一版技術選型不要太華麗

如果你本來就有 Postgres,先用 pgvector 很合理。少一個系統要維護。

如果你想快速做本地 demo,可以用 Chroma 或 Qdrant。資料量很小時,甚至 numpy + cosine similarity 都可以。

我會把常見選項粗暴分成這樣:

選項 適合誰 優點 缺點 我會怎麼選
numpy / 本地檔案 只想理解 RAG 流程的人 最透明,沒有黑盒 不適合多人、更新、權限 教學或 spike 用
Chroma 快速 demo、小型內部工具 開發快,本地很好跑 production 維運能力要自己評估 原型可以用
pgvector 本來就有 Postgres 的團隊 少維護一套系統,metadata / transaction 好處理 超大規模向量搜尋不是它最強項 多數 SaaS 第一版我會選這個
Qdrant 想要正式 vector DB 但又不想太重 filter、payload、部署彈性不錯 還是多一個服務要管 中型 RAG 產品很合理
Weaviate 需要比較完整的 semantic search stack 功能多,生態成熟 對小團隊可能太重 資料團隊較完整再考慮
Pinecone 想少管 infra、直接用 managed vector DB 省維運,scale 較輕鬆 成本和資料控制要評估 有預算、要快上線可選

重點不是一開始選最強 vector DB,而是把資料流打通:

  • ingest 能不能重跑?
  • 文件更新後舊 chunk 會不會失效?
  • chunk_id 是否穩定?
  • metadata 能不能 filter?
  • retrieval 結果能不能 debug?

很多團隊過早上重型架構,結果連哪個 chunk 被命中都看不到。

Prompt 要把引用變成硬規則

一個基本模板可以長這樣:

你是內部知識庫助手。只能根據 CONTEXT 回答。
如果 CONTEXT 沒有明確答案,回答「目前資料不足」。
每個關鍵結論後面都要附 source_url 或 chunk_id。
不要使用未提供的外部知識補充。

這不會完美,但比「請回答使用者問題」好很多。

更進一步,你可以要求輸出 JSON:answer、citations、missing_info、confidence。這樣前端可以檢查 citation 是否存在,沒有 citation 就不顯示答案。

一開始就要記 log

每次問答都要記:

  • user question
  • rewritten query
  • retrieved chunks
  • reranked chunks
  • final context
  • model answer
  • citations
  • user feedback

這些 log 不是之後有空再做。

沒有 log,你就不知道失敗是 retrieval 問題、資料問題、prompt 問題,還是模型問題。RAG 會變成玄學。

結論

RAG 知識庫不是把文件丟進向量資料庫。

它是一套資料產品:文件標準化、清理、切片、metadata、召回、重排、引用、拒答、log。

框架可以幫你省 code,但不能幫你定義資料品質。

所以第一次做 RAG,不要急著問「LangChain 還是 LlamaIndex」。先問你的資料是不是乾淨、可追、可更新。如果不是,後面的 AI 都只是在替爛資料化妝。

Community

Sign up or log in to comment