博客 / 詳情

返回

RAG 的失敗,大多在“切文檔”那一刻就已經註定

很多 RAG 項目,在“切文檔”這一步就已經失敗了

如果你認真覆盤過幾個 RAG 項目,會發現一個非常殘酷、但又極其真實的現象。

很多 RAG 系統:

  • 架構看起來沒問題
  • 模型選型也不差
  • embedding、向量庫、prompt 都配置齊全

但效果始終“説不上來哪裏對”。

而當你真正把檢索出來的 chunk 拿出來,自己一條一條讀的時候,
你往往會冒出一句話:

“這切的是什麼玩意?”

這不是玩笑。

在真實工程裏,文檔切分,幾乎決定了 RAG 的上限
而且非常反直覺的是:
它往往也是被最隨意對待的一步

一個必須先建立的共識:RAG 檢索的最小單位不是“文檔”,而是“chunk”

這是理解“為什麼切分這麼重要”的第一步。

在 RAG 系統裏,模型永遠不會看到“完整文檔”。
它看到的,永遠只是你切出來的一小塊文本。

也就是説:

  • 模型是否能答對
  • 不取決於你“有沒有這份文檔”
  • 而取決於:你有沒有切出一個“能獨立支撐答案”的 chunk

如果 chunk 本身是殘缺的、斷裂的、缺上下文的,
那後面再強的 embedding、rerank、模型,都只能在“信息碎片”上發揮。

為什麼“切小一點方便檢索”是一個危險的直覺

這是我見過最多人踩的第一個坑。

很多人切文檔時的第一反應是:
“切小一點,檢索更精確。”

於是你會看到:

  • 固定 300 / 500 token 切
  • 不管段落、不管語義
  • 表格、列表被直接截斷

這種切法,在技術上完全可行
但在效果上,幾乎必然翻車

因為你忽略了一件事:
檢索精確 ≠ 信息完整。

模型不是搜索引擎,它無法在多個 chunk 之間自動“拼上下文”。

RAG 裏最常見的失敗 chunk:看起來相關,但什麼也説明不了

這是你在調試 RAG 時,一定會遇到的一類 chunk。

它們通常有這些特徵:

  • 包含了關鍵詞
  • embedding 相似度不低
  • 排名還挺靠前

但你自己讀完之後,會發現:

  • 沒有結論
  • 沒有條件
  • 沒有上下文

這種 chunk,對模型幾乎沒有任何幫助

模型在這種情況下,要麼拒答,要麼開始“自由發揮”。

為什麼“語義完整性”比“長度控制”重要得多

在 RAG 切分中,有一個優先級經常被搞反。

很多人關注的是:

  • chunk 多長
  • token 會不會超限

但真正應該優先考慮的是:
這個 chunk 能不能作為一個“完整信息單元”存在。

一個好的 chunk,至少應該滿足一件事:

如果你只看到這一段文字,你能不能理解它在説什麼。

如果答案是否定的,那這個 chunk 基本就不合格。

41
語義完整 vs 語義殘缺 chunk 對比

表格、列表、步驟説明:RAG 切分的“重災區”

這是 RAG 項目裏翻車率極高的一類內容。

很多知識文檔裏,真正關鍵的信息,往往藏在:

  • 表格
  • 列表
  • 步驟説明

但如果你用“純文本 + 固定長度”的方式切分,結果往往是:

  • 表頭和內容分離
  • 步驟被拆散
  • 條件和結論不在一個 chunk 裏

最終檢索出來的,是一堆結構被破壞的殘片

一個非常重要的認知:chunk 是給“生成模型”用的,不是給“檢索模型”用的

這是很多人一直沒想清楚的一點。

在 RAG 裏,有兩個模型:

  • embedding 模型
  • 生成模型

embedding 模型關心的是“語義相似度”;
但生成模型關心的是:
這段文字能不能直接用來回答問題。

你在切 chunk 時,如果只從 embedding 的角度考慮,
很容易得到一堆“相似但沒法用”的結果。

切分的終極評判標準,不是“好不好搜”,
而是:“好不好答”。

為什麼切分錯誤,會讓你誤以為“embedding 不行”

這是一個非常典型的誤判路徑。

RAG 效果差 → 檢索不準 → embedding 不行 → 換模型

但在很多情況下,embedding 模型本身沒有問題,
真正的問題是:
你讓 embedding 去比較的是“被切壞的文本”。

你用再好的 embedding,
也很難讓它在語義已經破碎的情況下,給你奇蹟。

一個真實的工程現象:切分方式一換,模型“突然變聰明瞭”

這是很多工程師第一次真正意識到“切分重要性”的時刻。

你什麼都沒換:

  • 模型沒換
  • prompt 沒換
  • embedding 沒換

只是調整了切分方式:

  • 按段落切
  • 保留標題
  • 合併相關説明

然後你發現:
RAG 效果明顯提升了。

不是模型變聰明瞭,
而是你終於把“對的信息”,以“對的形態”給了它。

42
切分優化前後 RAG 效果對比

一個非常實用的切分自檢方法:把 chunk 當“答案草稿”看

這是我個人在做 RAG 時,最常用的一個判斷方法。

對每一種切分策略,你可以問自己一個問題:

如果模型只能照抄這個 chunk,它能不能給出一個“勉強可接受的答案”?

如果不能,那這個 chunk 本身就不具備“生成價值”。

這個方法非常原始,但極其有效。

不同內容類型,切分策略本來就不該一樣

這是很多 RAG 系統做不好的根本原因之一。

你很難用一種切分策略,同時處理:

  • 產品説明
  • 操作步驟
  • FAQ
  • 技術規範
  • 故障案例

但很多系統就是這麼幹的。

更合理的做法是:

  • 識別文檔類型
  • 為不同類型採用不同切分策略

一個簡單但有用的代碼示例:段落級切分 vs 固定長度切分

下面這段代碼不是“最佳實踐”,
而是用來直觀説明:
切分策略,會直接影響 chunk 的可讀性。

def naive_chunk(text, size=500):
    return [text[i:i+size] for i in range(0, len(text), size)]

def paragraph_chunk(text):
    return [p for p in text.split("\n\n") if len(p.strip()) > 0]

你會發現:

  • naive_chunk 更均勻,但語義經常斷裂
  • paragraph_chunk 長短不一,但語義完整度更高

在 RAG 場景裏,後者往往效果更好

為什麼“切得剛剛好”幾乎不存在

這是一個很多人不願意承認的事實。

文檔切分,本身就是一種妥協:

  • 切太大 → 檢索不精確
  • 切太小 → 信息不完整

不存在一個“萬能長度”。

真正成熟的系統,往往是:

  • 接受這種不完美
  • 用 rerank、query rewrite 來彌補
  • 而不是幻想“一刀切解決所有問題”

切分錯誤,會直接污染你的評估結論

這是一個後果非常嚴重、但經常被忽略的問題。

如果你的 chunk 本身不可用,那你在評估 RAG 時:

  • 會誤以為模型不行
  • 會誤以為 prompt 不行
  • 會誤以為架構不行

最終,你在錯誤的方向上不斷加複雜度。

43
切分錯誤 → 評估誤導的鏈式反應

一個現實建議:先把切分當成“核心工程”,而不是預處理

在成熟的 RAG 系統裏,文檔切分從來不是“順手做一下”的步驟。

它應該是:

  • 可迭代的
  • 可回滾的
  • 可評估的

否則,你永遠不知道:
效果變化到底是模型、檢索,還是切分導致的。

在探索階段,小規模反覆試切分,比一開始就做全量索引更重要

這是一個非常務實的工程建議。

在 RAG 初期,與其:

  • 一次性切完所有文檔
  • 建一個巨大索引

不如:

  • 選一小部分核心文檔
  • 多試幾種切分方式
  • 直接看檢索結果和生成效果

在反覆驗證切分策略是否合理時,使用 LLaMA-Factory online 快速跑通 RAG 流程、對比不同切分方式下的效果,比一次性投入全量工程更容易找準方向。

總結:RAG 的成敗,往往在“切文檔”那一刻就已經決定了

如果你只記住這一篇裏的一句話,那應該是這句:

RAG 的 80% 問題,不是模型、不是向量庫,而是你切出來的 chunk 本身。

模型並不會幫你修復被切壞的信息。
它只會在你給它的文本上,盡力發揮。

真正成熟的 RAG 實戰,不是“怎麼調模型”,
而是怎麼把知識切成模型真正能用的形態

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.