RAG:讓模型
先翻手冊再回答
LLM 什麼都懂一點,唯獨不懂你的資料。問它你店裡的 Wi-Fi 密碼,它不會說不知道—— 它會自信地編一個。RAG 的解法很樸素:回答前先從你的資料找出最相關的幾段,貼進提示詞, 再請模型只根據這些回答。下面是一間虛構的貓咪咖啡廳,切換開關看差別(內容是 notebook 的實測紀錄):
資料是一份十小節的繁體中文店務手冊;向量用第 1 課 gateway 的 qwen3-embedding-0.6b, 索引用上一課的記憶體 Qdrant,生成用 nemotron-3.5-lightning。notebook 從切段到評測每一步都量化。
先看它怎麼瞎掰,再決定怎麼切
notebook 第一格就問「Wi-Fi 密碼是多少?」——模型會給一個煞有介事的密碼(實測拿過 sakura2024、 camelliahouse),問「哪隻貓最怕生」要嘛發明一隻叫「豆漿」的貓、要嘛打太極說每隻貓都有個性。 這不是模型壞,是它沒有你的資料。
RAG 的第一個設計決策是怎麼切:切太大帶進無關內容,切太小失去上下文。 這份手冊結構乾淨,用最自然的切法——一個 ## 小標=一段,切出 10 段、每段 59–91 字:
十段變十個向量,問題也走同一條路
十段文字一次 API 呼叫批次變成 1024 維向量(input 給整個 list), 存進記憶體 Qdrant,payload 放原文與標題——檢索回來要貼進提示詞的是文字,向量只是索引。 問題也經過同一個 embedding 模型變向量,問 Qdrant 最近的 top_k 段。
看 score 的落差:「哪一隻貓最怕生?」命中「店貓介紹:煤球」0.53,但另兩隻貓的段落也有 0.51—— 三段都在講貓,檢索分不太開,靠模型讀內文判斷;「Wi-Fi 密碼」則是 0.70 對 0.31,一段獨大。 notebook 有輸入框與 top_k 拉桿,多試幾個問題感受分數的意義。
到 notebook 的 3️⃣–4️⃣ 節:入庫、互動檢索三條規矩,少一條都不行
只根據參考資料、沒有就說沒寫、不要編造——少了它們,模型會把參考資料和自己的想像混著講。 notebook 的 answer(question, use_rag=True/False) 一個開關切換兩種模式, 並排顯示同一題的兩個回答。
到 notebook 的 5️⃣ 節:提示詞、並排對照數字說話,以及「會說不知道」才是好 RAG
一個例子不算證據。7 題有標準答案的問題,每題用一個關鍵字判斷答對與否,兩種模式各跑一輪。實測多次: 沒 RAG 只矇對 0–2 題(例如「可以帶狗嗎」偶爾猜中「禁止」),有 RAG 7 題全對。 這種關鍵字命中是最陽春的評測,但它便宜、客觀——每次動了切段、top_k、提示詞,都該重跑。
| 問題 | 沒 RAG(實測節錄) | 有 RAG |
|---|---|---|
| Wi-Fi 密碼是多少? | ❌ 山茶屋的 Wi-Fi 密碼是:sakura2024 | ✅ meow2026 |
| 山茶屋週日幾點打烊? | ❌ 週日 18:00 打烊 | ✅ 21:00 |
| 領養一隻貓要多少錢? | ❌ 約新臺幣 2,000~5,000 元,已包含疫苗… | ✅ 1500 元 |
| 你們有賣牛排嗎?(手冊沒有) | 沒有販售牛排(矇對,但無從分辨是知道還是猜) | ✅ 手冊裡沒有寫(檢索分數全部 < 0.4) |
最後一列是 RAG 最被低估的價值:檢索永遠會回最近的幾段(哪怕都不相關), 但提示詞的規矩讓模型老實說沒寫,而不是拿不相關的段落硬湊。
到 notebook 的 6️⃣–7️⃣ 節:評測表、長條圖、範圍外問題換你動手
top_k 改 1 再跑評測——哪一題最先出錯、為什麼?改 5 會不會因雜訊變差?
在手冊加一個新小節(例如「外送服務」),不改其他程式重跑——新知識立刻可用,這是 RAG 相對微調的最大優勢。
刪掉「手冊裡沒有寫」那句看牛排問題怎麼答;再加一個分數門檻,top-1 太低就不送模型。用評測找出不誤殺的門檻。
卡住了?每一題在 notebook 末節都有折疊解答——先自己做,再打開對照。
情境測驗
離開前試試看:下面的情境都真的會遇到。每題選一個你認為的最佳做法,選了馬上看得到解釋。
Q1 情境題
你要把公司的產品 FAQ(Markdown,每個問題一個 ## 小標)做成 RAG 知識庫。切段應該怎麼切?
切段要在「太大帶進無關內容、太小失去上下文」之間取捨,文件結構乾淨時最自然的切法就是跟著小標——本課的手冊就是這樣切出 10 段、每段 59–91 字。A 讓檢索失去意義(永遠整份都命中),提示詞塞滿無關內容;B 切太小會失去上下文——「牠對雞肉凍乾沒有抵抗力」單獨一句,誰也不知道「牠」是麻糬;D 會把小節攔腰切斷,一段的前後文被拆散在兩個 chunk 裡。
Q2 錯誤診斷
你問「你們有賣牛排嗎?」(手冊裡完全沒有),檢索卻照樣回來 3 段,而且全是不相干的內容。這代表什麼?
檢索是「最近鄰」查詢,哪怕全部不相關也照樣回 top_k 段——範圍外問題的訊號不是「回不回」,是分數全部偏低(實測範圍內 top-1 至少 0.46,牛排最高只有 0.37)。所以要靠提示詞的「沒有就說沒寫」或分數門檻來擋。A 不成立:同一個模型把範圍內的問題都命中了(Wi-Fi 0.70);B 搞混了——top_k=3 回 3 段是設計不是 bug,調小照樣回不相關的;C 的話範圍內的問題也會亂掉,但評測是 7 題全對。
Q3 錯誤診斷
同事的 RAG 客服檢索一切正常,但回答會混入手冊裡根本沒有的內容。最可能的原因是?
這正是課裡 LEVEL 3 拿掉那句規矩後的實測結果:模型從「咖啡廳」自行腦補菜單,講得很像真的。修法是把三條規矩加回 system prompt——少一條都不行。B 症狀相似但題目已說檢索正常;C 搞錯層次——編造不是能力問題,是沒有被禁止,大模型一樣混著講;D 撈不到不存在的東西,手冊裡根本沒有菜單段落。
Q4 情境題
你把切段方式從「## 小標一段」改成固定 200 字一段,想知道整體有沒有變差。最佳做法是?
關鍵字命中評測陽春但便宜、客觀、可重複——每次動了切段、top_k、提示詞都重跑一輪,課裡那 7 題就是幹這個用的。A 是一個例子不算證據,別題可能默默壞掉;C 分數只是檢索訊號,不等於答案正確(三隻貓 0.53/0.51/0.51 分不開時是靠模型讀內文救回來的),而且切段變了分數本來就會變、不可比;D 等於拿使用者當測試,發現時已經晚了。
實作在 molab 跑(免費)
molab 的登入狀態進不了內嵌框架(瀏覽器的跨站 cookie 保護), 所以 notebook 要在新分頁執行——把它跟本頁並排開,左邊教學照樣對照。
- 登入 molab(GitHub / Google)
- 開啟課程 notebook,Fork 成自己的副本即可編輯
- 從第一格往下全部執行(首次安裝套件約 1 分鐘)——免費 CPU 環境即可,不需要 GPU
不想用 molab?下載 rag-zh_ext.py 後在自己電腦
uvx marimo edit --sandbox rag-zh_ext.py,依賴會自動安裝。