偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

RAG 調(diào)優(yōu)核心:文本切分決定 70% 的性能表現(xiàn)

發(fā)布于 2025-10-23 07:48
瀏覽
0收藏

分塊(Chunking)是構(gòu)建高效RAG(檢索增強生成)系統(tǒng)的核心。從固定分塊、遞歸分塊到語義分塊、結(jié)構(gòu)化分塊和延遲分塊,每種方法都在優(yōu)化上下文理解和準確性上扮演了關(guān)鍵角色。這些技術(shù)能大幅提升檢索質(zhì)量,減少“幻覺”(hallucination),并充分發(fā)揮你的RAG pipeline的潛力。

在我近一年構(gòu)建可擴展AI系統(tǒng)的經(jīng)驗中,我發(fā)現(xiàn)RAG系統(tǒng)的成功大多取決于檢索(retrieval)。你如何切分和存儲文檔——也就是分塊(chunking)——往往是成功背后的隱形推手。

引言

RAG(Retrieval-Augmented Generation)pipeline的性能很大程度上取決于你如何切分文檔(分塊)。在這篇文章中,我會帶你了解RAG的流程,重點講講分塊在其中的位置,然后深入探討固定分塊、遞歸分塊、語義分塊、基于結(jié)構(gòu)的分塊和延遲分塊這五種技術(shù),包括它們的定義、權(quán)衡和偽代碼,幫你選擇適合自己場景的方法。

RAG工作流程(高層次概覽)

標準流程如下:

RAG 調(diào)優(yōu)核心:文本切分決定 70% 的性能表現(xiàn)-AI.x社區(qū)

  1. 文檔攝取與分塊
    拿來大份文檔(PDF、HTML、純文本) → 切分成小塊(chunk) → 計算embeddings → 存儲到vector DB中。
  2. 查詢與檢索
    用戶輸入查詢 → 將查詢轉(zhuǎn)為embedding → 檢索top-k最相似的塊(通過cosine similarity)。
  3. 增強與提示構(gòu)建
    將檢索到的塊(加上metadata)注入到LLM的提示中,通常會用模板和過濾器。
  4. 生成
    LLM基于檢索到的上下文和模型先驗知識生成答案。

因為生成器(generator)只能看到你喂給它的內(nèi)容,檢索質(zhì)量直接決定了結(jié)果。如果分塊不合理或無關(guān)緊要,哪怕最好的LLM也救不回來。這就是為什么很多人說RAG的成功70%靠檢索,30%靠生成。

在深入探討技術(shù)之前,先說說為什么好的分塊不是可有可無的:

  • Embedding和LLM模型有context window限制,你沒法直接處理超大文檔。
  • 分塊需要語義連貫。如果你在句子或概念中間切開,embedding會變得雜亂或誤導(dǎo)。
  • 如果分塊太大,系統(tǒng)可能會漏掉細粒度的相關(guān)內(nèi)容。
  • 反過來,如果分塊太小或重疊太多,你會存儲冗余內(nèi)容,浪費計算和存儲資源。

接下來,我們來探索五種主流的分塊技術(shù),從最簡單到最復(fù)雜。

1. 固定分塊(Fixed Chunking)

按固定大?。ò磘oken、單詞或字符)把文本切成等大的塊,通常塊之間會有重疊。

這是RAG項目的良好起點,適合文檔結(jié)構(gòu)未知或內(nèi)容單一的場景(比如日志、純文本)。

實現(xiàn)代碼示例:

def fixed_chunk(text, max_tokens=512, overlap=50):
    tokens = tokenize(text)
    chunks = []
    i = 0
    while i < len(tokens):
        chunk = tokens[i : i + max_tokens]
        chunks.append(detokenize(chunk))
        i += (max_tokens - overlap)
    return chunks

2. 遞歸分塊(Recursive Chunking)

先按高層邊界(比如段落或章節(jié))切分。如果某個塊還是太大(超過限制),就遞歸地進一步切分(比如按句子),直到所有塊都在限制范圍內(nèi)。

適合半結(jié)構(gòu)化文檔(有章節(jié)、段落),你想盡量保留語義邊界,同時控制塊大小。

它能盡量保留邏輯單元(段落),避免不自然的切分,生成適合內(nèi)容變化的多種塊大小。

遞歸分塊示例(LangChain):

from langchain.text_splitter import RecursiveCharacterTextSplitter

# 示例文本
text = """
輸入文本占位符...
"""

# 定義遞歸分塊器
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=200,           # 每個塊的目標大小
    chunk_overlap=50,         # 塊之間的重疊以保持上下文連貫
    separators=["\n\n", "\n", " ", ""]  # 遞歸切分的優(yōu)先級
)

# 切分文本
chunks = text_splitter.split_text(text)

# 顯示結(jié)果
for i, chunk inenumerate(chunks, 1):
    print(f"Chunk {i}:\n{chunk}\n{'-'*40}")

這能確保后續(xù)embedding和檢索時,不會丟失邊界處的關(guān)鍵上下文。

3. 語義分塊(Semantic Chunking)

根據(jù)語義變化來切分文本。用embeddings(比如sentence embeddings)決定一個塊的結(jié)束和下一個塊的開始。如果相鄰段落的相似度很高,就把它們放在一起;當相似度下降時,就切分。

適合需要高檢索精度的場景(法律文本、科學(xué)文章、支持文檔),但要注意embedding和相似度計算的成本,定義相似度閾值也需要仔細調(diào)整。

實現(xiàn)代碼示例:

from sentence_transformers import SentenceTransformer, util

model = SentenceTransformer("all-MiniLM-L6-v2")

defsemantic_chunk(text, sentence_list, sim_threshold=0.7):
    embeddings = model.encode(sentence_list)
    chunks = []
    current = [sentence_list[0]]
    for i inrange(1, len(sentence_list)):
        sim = util.cos_sim(embeddings[i-1], embeddings[i]).item()
        if sim < sim_threshold:
            chunks.append(" ".join(current))
            current = [sentence_list[i]]
        else:
            current.append(sentence_list[i])
    chunks.append(" ".join(current))
    return chunks

4. 基于結(jié)構(gòu)的分塊(Structure-based Chunking)

利用文檔的固有結(jié)構(gòu)(比如標題、副標題、HTML標簽、表格、列表項)作為自然的切分邊界。
比如,每個章節(jié)或標題可以成為一個塊(或者再遞歸切分)。
適合HTML頁面、技術(shù)文檔、類似Wikipedia的內(nèi)容,或任何有語義標記的內(nèi)容。

根據(jù)我的經(jīng)驗,這種策略效果最好,尤其是結(jié)合遞歸分塊時。
但它需要解析和理解文檔格式,如果章節(jié)太大,可能會超過token限制,可能需要結(jié)合遞歸切分。

實現(xiàn)提示:

  • 用HTML/Markdown/PDF結(jié)構(gòu)解析庫。
  • 以章節(jié)/等作為塊的根。
  • 如果某部分太大,就回退到遞歸切分。
  • 對于表格/圖片,要么單獨作為一個塊,要么總結(jié)其內(nèi)容。

5. 延遲分塊(Late Chunking / 動態(tài)/查詢時分塊)

定義
延遲分塊是指推遲文檔的切分,直到查詢時才決定。不是提前把所有內(nèi)容切好,而是存儲更大的段落甚至整個文檔。收到查詢時,只對相關(guān)段落動態(tài)切分(或過濾)。這樣做的目的是在embedding時保留完整上下文,只在必要時切分。

Weaviate將延遲分塊描述為“顛倒傳統(tǒng)的embedding和chunking順序”。

  • 先用長上下文模型對整個文檔(或大段)做embedding。
  • 然后池化并創(chuàng)建塊的embeddings(基于token范圍或邊界線索)。

概念流程:

  • 在索引中存儲大段或整個文檔。
  • 查詢時,檢索1-2個最相關(guān)的段落。
  • 在這些段落中,動態(tài)切分(比如語義或重疊)出匹配查詢的部分。
  • 過濾或排序這些塊,喂給生成器。

這種方法就像編程中的late binding,推遲到有更多上下文時再決定。

RAG 調(diào)優(yōu)核心:文本切分決定 70% 的性能表現(xiàn)-AI.x社區(qū)

適用場景:

  • 大型文檔集(技術(shù)報告、長篇內(nèi)容),跨段落的上下文很重要。
  • 文檔內(nèi)容經(jīng)常變化的系統(tǒng),避免重新切分節(jié)省時間。
  • 高風(fēng)險或精度敏感的RAG應(yīng)用(法律、醫(yī)療、監(jiān)管),誤解代詞或引用可能代價高昂。

聽起來很高級,但它也有成本。
對整個文檔(或大段)做embedding計算成本高,可能需要支持長token限制的模型。
查詢時的計算成本和潛在延遲也會更高。

本文轉(zhuǎn)載自??PyTorch研習(xí)社??,作者:AI研究生

已于2025-10-23 11:17:43修改
收藏
回復(fù)
舉報
回復(fù)
相關(guān)推薦