檢索是 RAG 系統的搜索引擎,分塊則是這個搜索引擎的基礎。分塊太長、太短、有噪聲、切錯了位置——隨便犯哪個錯LLM 都會有問題。行業里有句話流傳很廣:"分塊決定了 RAG 質量的 70%。"
這個說法不夸張:好的分塊讓檢索器拿到完整、有上下文、真正相關的信息;差的分塊把文檔打成碎片,上下文斷裂,LLM 只能靠"編"來填補空白。
![]()
什么是分塊?
RAG 的起點是文檔收集與攝取:把所有原始材料(文檔、文章、知識庫條目)匯聚到一起。在進入檢索環節之前,這些文檔要經過文本分塊處理也就是切分成更小的、有意義的片段。
每個分塊應當是連貫且自包含的,這樣檢索器才能在面對查詢時快速定位、排序,并返回最相關的信息。
![]()
分塊就是在生成 Embedding 之前,把大段文本拆成更小語義單元的過程。檢索器真正搜索的對象而不是整篇文檔就是這些分塊。
分塊做得好,文檔中的內容就能被干凈地捕獲,上下文得以保留LLM 能做出有意義的推理。分塊做得差,語義被割裂檢索充滿噪聲。向量存儲、Embedding 模型、Reranker——這些統統排在分塊之后,分塊才是真正的起點。
固定大小分塊
這是最簡單的方式。按預設的字符數或 Token 數直接切分,比如每 500 個 Token 一塊完全不管句子和段落的邊界在哪。
速度快,行為可預測,處理大規模、結構混亂的數據集時很實用。但缺點也很明顯——語義經常被攔腰切斷。一個句子在這個分塊里開了頭,到下一個分塊才結束,Embedding 的語義表達力就會打折扣。
![]()
實踐中一般會在相鄰分塊之間設置一定的重疊來緩解這個問題:
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50
)
chunks = splitter.split_text(long_text)
切分文本時,連續的分塊之間通常會加入一小段重疊區域來維持上下文的連貫。所謂重疊,就是前一個分塊的尾部幾句話,在下一個分塊的開頭再出現一次。
![]()
這么做是為了防止跨越分塊邊界的關鍵信息丟失。沒有重疊的話,檢索器可能只拿到部分內容LLM 因此漏掉了關鍵上下文,給出殘缺甚至誤導性的回答。重疊量一般控制在分塊長度的 10% 到 20%,在冗余和效率之間找一個平衡點。
固定大小分塊適合的場景包括日志文件、郵件、代碼倉庫,以及結構參差不齊的大型語料庫。
基于句子的分塊
這種方式按完整句子來劃分文本,而不是按任意長度一刀切。每個分塊至少包含一個或多個完整的句子,語法完整,語義連貫。
![]()
好處是每個分塊都是一個有意義的思想單元。檢索器向 LLM 返回的信息更精確、更易理解,碎片化回答的風險降低不少。實際使用中通常也會搭配小幅重疊,進一步保證分塊之間的銜接。
基于段落的分塊
以完整段落為單位切分,不再拘泥于單個句子或固定 Token 數。這種方式天然保留了文檔的結構和行文節奏,檢索器更容易抓到完整的想法。
每個分塊往往對應一個獨立的主題或子主題,LLM 處理起來更從容,也更容易給出準確的回答。對長篇文檔、研究論文、綜述類文章來說,段落級分塊效果不錯。和句子級分塊一樣,也可以加重疊來保持連貫。
語義分塊
語義分塊的切入點不是長度,而是語義本身。它利用 Embedding 或相似度分數來識別文本中天然的斷裂點——主題切換、上下文轉折、章節邊界。
產出的分塊語義清晰度更高,邊界和語義對齊,檢索質量有明顯提升,尤其在知識庫、技術文檔、結構化文章這類內容上效果突出。代價是計算開銷更大而且分塊長度不一致,后續處理需要額外考慮。
from langchain_experimental.text_splitter import SemanticChunker
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
chunker = SemanticChunker(model, breakpoint_threshold=0.4)
chunks = chunker.split_text(long_text)
如果文檔質量高、主題流轉有明確脈絡,語義分塊往往是精度最高的選擇。
遞歸分割
遞歸分割是固定大小和語義分塊之間的一個折中方案。核心思路是優先尊重文檔結構,只有在必要時才進一步拆分。
具體做法是先嘗試按標題切分。如果某個章節還是太長,就按段落切。段落還不夠就按句子。句子仍然超限,最后才按字符兜底。這樣得到的分塊既保有語義完整性,尺寸也在可控范圍內。
recursive_splitter = RecursiveCharacterTextSplitter(
separators=["\n## ", "\n### ", "\n", ". ", ""],
chunk_size=600,
chunk_overlap=80
)
chunks = recursive_splitter.split_text(long_doc)
開發者文檔、技術手冊、學術論文、研究報告——凡是層級結構明確的內容,遞歸分割都很適合。
滑動窗口分塊
有些文本的語義天然是跨句分布的。法律合同、科學論文、長段論證,一個完整的意思可能橫跨好幾個句子。滑動窗口就是為這種場景設計的。
它不生成彼此獨立的分塊,而是創建相互重疊的窗口。比如窗口大小 400 Token,每次滑動 200 Token,這樣相鄰的分塊之間有一半的內容是共享的,語義在邊界處不會斷裂。
上下文保持得很好,但分塊數量會膨脹,存儲和檢索的成本都會上升。
法律 RAG、金融分析、醫學文獻檢索、合規審查——這些領域用滑動窗口的比較多。
層次化分塊
層次化分塊是一個多層級的架構:小分塊負責細粒度精確檢索,中等分塊支撐平衡的推理,大分塊維持全局上下文。
檢索時,系統先用小分塊鎖定精確位置,再把關聯的大分塊拉進來補充完整上下文。這種組合能有效壓制幻覺,提升推理的深度。
企業級 RAG 系統和 LlamaIndex 這類多粒度檢索框架,背后都有層次化分塊的影子。
實踐中常見的分塊失誤
多數 RAG 項目翻車根源都是分塊層面的問題。分塊過大模型被不相關的細節淹沒。分塊過小語義喪失殆盡。句子被攔腰切斷、不相關的段落被混到一個分塊里,Embedding 質量直接垮掉。沒有重疊,上下文斷裂。沒有元數據,檢索器找不到方向。還有一個常見錯誤——所有類型的文檔套用同一種分塊策略。
分塊沒有萬能方案。政策文件和教科書不一樣,通話記錄和研究論文不一樣。策略必須跟著文檔類型和檢索任務走。
![]()
總結
分塊不是一個可有可無的預處理環節,它是 RAG 管道的脊梁。好的分塊是一個有意義的、自包含的知識單元;差的分塊是一個孤零零的碎片,把 LLM 帶向歧途。
檢索是引擎分塊是燃料。燃料的質量決定了整個系統是輸出干凈、可靠的結果,還是不斷產出噪聲和幻覺。LLM 本身再好,也救不了爛分塊。
https://avoid.overfit.cn/post/e6520bd283254415ae61cfa28fb2ef32
作者:Abinaya Subramaniam
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.