總覽:切塊是 RAG 品質的隱形殺手
Embedding 模型再強,也救不回「切錯位置」的知識庫——本篇只深入 Chunking 與檢索調校,不重複 RAG pipeline 全貌。
在 RAG 架構綜合手冊 裡,我們把線上路徑畫成「Embed → Retrieve → Prompt → Generate」。實務上,召回品質往往在離線 ingest 的切塊階段就定生死:塊切得太粗,向量被多主題平均掉;切得太細,答案被拆散到不同 chunk;切在句子中間,關鍵條件與例外條款分離——之後再怎麼調 Top-k 也只是在噪音裡打轉。
綜合篇交代 pipeline 與痛點;本篇假設你已懂「為何需要 RAG」,專心回答:固定長度怎麼選、要不要 overlap、metadata 寫什麼、以及 parent-child / small-to-big 如何同時兼顧召回與上下文。
固定長度 vs 語意切塊
兩條主幹路線:可預期、便宜、好批次;或對齊段落/標題,讓一塊幾乎對應一個語義單元。
- 依 token 或字元數切(常見 256–512 tokens)。
- 實作簡單、吞吐高、成本可預期。
- 易在句中切斷;多主題同塊會稀釋向量。
- 適合結構亂、HTML 雜訊多、或先求「有索引」的冷啟動。
- 依標題、段落、列表、或 embedding 相似度斷點切。
- 一塊較像「一個可回答單元」,召回更乾淨。
- 實作與調參成本高;長度不均影響 batch。
- 適合手冊、政策、RFC 等有清楚結構的文件。
| 維度 | 固定長度 | 語意切塊 |
|---|---|---|
| 實作成本 | 低(計數器即可) | 中高(解析器/相似度斷點) |
| 塊內純度 | 不可控,常混主題 | 較高,一塊一意 |
| 長度分布 | 齊整,利於 batch | 長尾,需設 max/merge 規則 |
| 面試答法 | 冷啟動、雜訊語料首選 | 結構化知識庫品質首選 |
先看「塊內純度」那一列:固定長度的不可控正是語義稀釋的來源。實務常採「語意優先 + 固定上限兜底」——先依標題/段落切,超過 max tokens 再二次固定切。
加大 chunk 看似「比較完整」,卻讓向量平均掉細節;Top-k 命中一塊卻塞滿無關段落,反而擠掉真正相關的其他塊。大小要對齊「一個問題通常需要多少上下文」,不是對齊模型最大窗口。
Overlap 與 Metadata 標註
Overlap 修補邊界切斷;Metadata 讓檢索可過濾、生成可引用——兩者常比換 embedding 模型更划算。
Overlap(重疊窗)
相鄰 chunk 保留一段重疊(常見為窗長的 10%–20%)。當答案橫跨切點時,至少有一塊仍同時含「條件 + 結論」。代價是索引膨脹與近似重複;overlap 過大等於變相加大塊並製造近重複命中。
Metadata(檢索與引用的把手)
每塊至少應帶:doc_id、title/路徑、section、page 或偏移、updated_at、以及權限標籤。線上路徑用 metadata 先過濾再 ANN(或 post-filter),避免把過期政策、無 ACL 權限的片段送進 prompt。
| 欄位 | 用途 | 不做會怎樣 |
|---|---|---|
| section / heading | 組 prompt 時還原章節語境 | 模型不知道「這段適用哪個產品線」 |
| updated_at | 新鮮度過濾、衝突時取新 | 舊政策與新政策同時進 Context |
| acl / tenant | 檢索側權限隔離 | 敏感 chunk 泄漏進 prompt |
| source_url | 強制引用與人工稽核 | 答案無法回溯,無法除錯召回 |
Overlap 修的是「切點剛好落在答案中間」;它治不好多主題同塊的語義稀釋。結構清楚時,寧可語意切塊 + 小 overlap,也不要超大固定窗假裝「一定覆蓋」。
Parent-Child 與 Small-to-Big 檢索
小塊負責「好命中」,大塊(父段)負責「好生成」——把召回粒度與生成上下文拆開。
Parent-Child(父子索引):把文件切成較大的 parent(例如一整節),再切成較小的 child(句子/短段)。索引與 ANN 只打在 child;命中後用 child 的指標回填對應 parent,把 parent 全文(或標題 + parent)塞進 prompt。
高純度召回
補足前提與例外
大塊說清楚
看箭頭的方向:比對用的是左邊的小塊(child),送進 LLM 的卻是右邊回填的父塊——同一份資料的兩種粒度,檢索粒度與生成粒度在這裡被拆開。
Small-to-Big 是同一思路的檢索說法:先用小單位找準位置,再「放大」到足夠回答的上下文。變形包括:命中句 → 取前後 N 句;命中段落 → 取整節;多個 child 同 parent 時去重,只送一次 parent。
| 做法 | 優點 | 代價/留意 |
|---|---|---|
| 只索引大塊 | 實作簡單 | 向量稀釋,細問題召回差 |
| 只索引小塊 | 召回準 | Context 缺前提,易斷章取義 |
| Parent-Child | 召回準+生成完整 | 雙層索引/映射表;要去重 parent |
| 膨脹 Top-k | 不用改切塊 | 噪音與 token 成本上升,治標 |
同一 parent 被多個 child 打中時,務必依 parent_id 去重,否則 prompt 被重複段落洗版,既浪費窗口又讓模型過度關注同一節。評測時應同時看「召回是否對」與「送進 Context 的唯一 parent 數」。
互動 · 同一文件、三種切法
固定無重疊、固定+overlap、句界語意——同一份原文、同一個問題,三條管線的塊數、切斷句數與答案覆蓋差在哪裡。(parent-child 的回填留在第 4 節論述,這裡只比切法本身。)
尺上的紅色切線是「切在句子中間」——固定切法會不會踩到它,完全由你設的 chunk 大小與這份原文的句長分布決定。分數這裡用關鍵詞重疊 ÷ √塊長代替 embedding 相似度,為的是讓每個數字都能手算驗證;長度歸一化正是「塊越大分數越平」的來源。
檢索調校清單(不動模型先調這些)
換 embedding 很貴;先把切塊、過濾、Top-k 與去重調穩,通常就能拉開一截品質。
| 旋鈕 | 常見起點 | 觀察訊號 |
|---|---|---|
| chunk_size | 256–512 tokens(手冊可更短) | 塊太大→分數平;太小→答案碎片 |
| overlap | 10%–20% 窗長 | 跨句問題漏召回時先加;過大則近重複 |
| Top-k | 先 3–8,有 rerank 可取更大候選池 | 無 rerank 時盲目加大常變差 |
| metadata filter | 產品線/版本/ACL/時效 | 答到錯產品或過期條款 |
| parent 去重 | 依 parent_id 唯一化再組 Context | Context 重複、窗口被洗版 |
純向量仍可能漏「精確型號/錯誤碼」——那是 Hybrid Search + Reranking 的戰場。本篇把「塊切對、上下文夠」做完,再往混合檢索與評估篇走,才不會把問題全怪到模型頭上。
面試折衷與實務清單
能講清「為何切錯會害死召回」、並畫出 parent-child,就比只背「用 LangChain 切一下」有說服力。
| 決策點 | 一端做法 | 另一端做法 | 留意 |
|---|---|---|---|
| 切塊策略 | 固定窗:快、齊 | 語意切:純、準 | 結構化文件別死守固定窗 |
| 上下文策略 | 加大單一 chunk | Parent-Child / small-to-big | 加大塊會稀釋;父子要去重 |
| 邊界保護 | 無 overlap | 10%–20% overlap | overlap 是止血,不是萬靈丹 |
| 除錯單位 | 只看最終答案 | 看命中 chunk + metadata | 沒引用就無法判「切錯還是生成錯」 |
(1)一組「答案橫跨段落邊界」的回歸問句;(2)每塊必有 section/版本/來源 URL;(3)若用父子索引,量測「唯一 parent 進 Context」而非只看 child 分數。這三樣能快速分辨是切塊問題還是生成問題。