Dify RAG 知識庫:讓 agent 查你自己的文件

📚 Dify 自架實戰系列
用 Dify 做 agent:五道牆、假答案、後端架構
RAG / 知識庫:讓 agent 查你自己的文件(你在這)
③ 更多主題(規劃中)
重點摘要(TL;DR)
  • RAG(知識庫)= 讓 agent 從「查網路 / 憑記憶」變成「查你自己的文件」。
  • 第一個關卡:RAG 需要 embedding 模型,Groq 沒有 → 用本機 bge-m3
  • 它其實存兩個庫:Postgres 存文字、Weaviate 存向量,靠一把 id 對應(不是 pgvector 也行,向量庫可插拔)。
  • 最重要的一課:RAG chatflow 裡「知識檢索 → LLM 上下文」那條線沒接上,就會「查不到」甚至亂編;接上才會照文件答、還附出處。
  • 鐵律:先單獨驗檢索(命中測試看分數),別等 agent 答完才發現撈錯。機密文件 → embedding + 聊天模型「兩個都本機」。

系列上一篇,我們讓 agent 學會「查網路」。這一篇更進一步:讓它查你自己的文件 —— 這就是 RAG(檢索增強生成),在 Dify 裡叫「知識庫」。我拿一批真的幼兒園招生文件(還混了幾份公司內部檔)實測,把「怎麼用、存在哪、怎麼驗、最容易漏的那條線」一次講清楚。

RAG 一句話 + 第一個關卡

RAG 分兩階段:建庫(上傳文件 → 切塊 → 算成向量存起來)、查詢(問題也算成向量 → 找語意最近的幾塊 → 塞給模型當小抄)。第一個關卡馬上來:「算成向量」需要一個 embedding 模型,而 Groq 只有聊天模型、沒有 embedding。所以要先掛本機 bge-m3(在模型供應商加一個「Text Embedding」型的模型,別選成 LLM)。這也是為什麼 RAG 幾乎一定會用到本機模型。

先驗檢索:命中測試(RAG 最重要的紀律)

建好庫、上傳文件(Dify 連 PDF / Word / Excel 都能解析切塊),先別急著接 agent。用知識庫的「命中測試」直接驗檢索:輸入一個「答案只在文件裡」的問題,看它撈回哪幾塊、相似度多少。

問題 撈回的塊 分數
非營利幼兒園費用「非營利…第1胎每月 3,000元」0.62 ✅
招生對象幾歲「招收對象:2足歲至未滿3歲」0.64 ✅

bge-m3 的向量分數落在 0.4~0.7 算健康命中(遠高於雜訊底 0.3)。為什麼要先單獨驗檢索?因為如果檢索就撈錯,後面 agent 答錯,你會誤以為是模型笨——其實是根本沒撈到對的內容。先把「檢索」這一段驗對,再談生成。

存在哪?其實是「兩個庫」

很多人以為 RAG 就一個向量庫。實際上 Dify 存兩個地方,靠一把 id 對應:

Dify RAG 雙庫架構:Postgres 存文字、Weaviate 存向量,建庫與查詢流程
RAG 雙庫:Postgres 存文字內容,Weaviate 存向量;查詢時用 doc_id 從向量庫連回文字庫。
  • Postgres(內容的真相來源):document_segments 存每一塊的實際文字 content + position + tokens + index_node_id(連向量的鑰匙)+ hit_count(被檢索幾次)。
  • Weaviate(語意搜尋專用):每個知識庫一個 collection,存 1024 維向量 + doc_id(= Postgres 的 index_node_id)。

為什麼拆兩個?Postgres 擅長存文字與關聯、但不會做向量相似搜尋;Weaviate 專做向量搜尋、但不適合當內容真相來源。所以:Postgres 當「圖書館的書」,Weaviate 當「按語意排的索引卡」——查到卡片(doc_id)再回圖書館拿書(content)。

向量庫是可插拔的:Dify 靠一個 VECTOR_STORE 環境變數切換,支援 weaviate / qdrant / milvus / pgvector / chroma…。設 pgvector 就把向量塞進 Postgres 擴充、跟文字同一個庫(運維簡單、中小量夠);獨立向量庫(如 Weaviate)則在大規模、高並發下更能撐。同一套 RAG 邏輯,底層向量庫可換。

最重要的一課:「上下文」那條線

在 Dify 用 chatflow 做 RAG,結構是 開始 → 知識檢索 → LLM → 回覆。同一題「非營利幼兒園費用」,我親眼看到三個階段——差別只在一條線接了沒:

階段 答案 原因
上下文沒接、無約束🚫「以中國大陸為例…保教費」用腦內舊知識亂編
加 SYSTEM「禁止編造」⚠️「文件裡查不到」不編了,但上下文還空
上下文接知識檢索 result✅「每月 3,000 元」+ 出處LLM 拿到撈回的塊,照文件答

最容易漏的坑:知識檢索撈到了,但 LLM 節點的「上下文」欄位是空的 —— 撈回的塊躺在檢索節點的輸出裡,沒被交給 LLM。查後端就看得死死的:LLM 收到的 prompt 裡根本沒有那塊文字。把 LLM 節點的「上下文」設成「知識檢索 / result」,那條線才通,撈回的內容才會進 prompt。這條線,就是 RAG chatflow 的命脈。

-- 驗證:LLM 到底有沒有拿到撈回的內容?看它收到的 prompt
-- 沒接上下文時:prompt 裡找不到「3,000」→ 撈了等於沒撈
-- 接上後:那塊「每月 3,000元」進了 prompt → 才答得出來
-- 而被檢索命中的塊,hit_count 會累加(DB 有記)

機密文件:整條鏈都要本機

我故意在庫裡混了公司內部文件。這裡有個容易忽略的洩漏點:embedding 用本機 bge-m3,索引階段安全;但如果回答的聊天模型是雲端(如 Groq),檢索到的機密塊會被塞進 prompt 送上雲。所以對機密資料的鐵律是:embedding 和聊天模型「兩個都要本機」(bge-m3 + 本機 qwen),資料主權才完整——這正是「為什麼要本機 RAG」的實戰理由。附帶一提:一個知識庫別混太多不相關領域,否則檢索會互相干擾,真上線要「一領域一庫」。

一句話心法:RAG 不難,難在「先驗檢索、再接生成」——先確認撈對(命中測試看分數),再把「知識檢索 → LLM 上下文」那條線接上。撈對 + 接上,才有「照文件答、還附出處」的可信 agent。

延伸閱讀:Dify 自架實戰 #1:五道牆與後端架構地端 Agentic RAG:斷網怎麼上線真實手冊 RAG 一日實戰:15 個坑

留言

在〈Dify RAG 知識庫:讓 agent 查你自己的文件〉中有 2 則留言

  1. […] ① 今天:用 Dify 做 agent —— 五道牆、一個假答案、與後端架構(你在這) ② RAG / 知識庫:讓 agent 查你自己的文件 […]

  2. […] 前兩篇我們讓自架的 Dify agent 學會上網查、也 查自己的文件。這一篇更進一步:讓它接進你「會變動、能做事」的系統——ERP、訂單、庫存。這一步,才是 agent 從「會聊天」變成「真的幫你辦事」的關鍵。我用一個假的訂單 API 練手,再接一個真的內部系統,把整條路和一路踩到的坑一次講清楚。 […]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *