文檔太長(zhǎng)模型“吃不下”?試試這15種Chunking策略,輕松搞定RAG! 原創(chuàng) 精華
RAG系統(tǒng)也能“切塊”?15種Chunking技巧讓你的檢索生成更聰明!
你知道嗎?在構(gòu)建一個(gè)強(qiáng)大的RAG(Retrieval-Augmented Generation)系統(tǒng)時(shí),決定其“聰明程度”的,可能不是模型本身,而是——你怎么“切塊”你的文檔。
在NLP領(lǐng)域,RAG系統(tǒng)已經(jīng)成為處理復(fù)雜問答、文檔摘要、知識(shí)庫檢索等任務(wù)的利器。但面對(duì)動(dòng)輒上萬字的文檔,如何在不丟失上下文的前提下,把它們“切”成模型能消化的“小塊”,就成了關(guān)鍵。
今天這篇文章,我們就來系統(tǒng)聊聊:15種Chunking技巧,幫你打造一個(gè)既快又準(zhǔn)的RAG系統(tǒng)。無論你是做問答系統(tǒng)、文檔檢索,還是構(gòu)建企業(yè)知識(shí)庫,這篇文章都值得你收藏。
01|什么是Chunking?為什么它這么重要?
在RAG系統(tǒng)中,Chunking(切塊)指的是:把大文檔拆分成小塊,以便模型更好地理解和檢索信息。
你可能會(huì)問:為什么不能直接把整篇文檔丟給模型?原因很簡(jiǎn)單:
- 大模型有token限制(比如GPT-4最多支持8K tokens);
 - 文檔太長(zhǎng),模型容易“看漏”關(guān)鍵信息;
 - 不切塊,檢索系統(tǒng)很難精準(zhǔn)定位答案。
 
所以,Chunking不是簡(jiǎn)單的“切”,而是要在“保留上下文”和“適配模型能力”之間找到平衡。
02|Chunking的三大核心考量
在正式介紹15種技巧之前,我們先來理解Chunking的三個(gè)關(guān)鍵因素:
1. 塊的大?。–hunk Size)
- 太大:容易超token限制,檢索慢;
 - 太小:上下文丟失,生成質(zhì)量差;
 - 建議:根據(jù)模型token上限,控制在100~500 tokens之間。
 
2. 上下文保留(Context Preservation)
- 切塊不能“斷句斷意”,否則模型會(huì)“看不懂”;
 - 使用滑動(dòng)窗口、語義切塊等方式,能有效保留上下文。
 
3. 多模態(tài)處理(Modality Handling)
- 文檔中可能包含表格、圖片、代碼塊;
 - 不同內(nèi)容類型需要不同的切塊策略。
 
03|15種Chunking技巧全解析(附代碼)
接下來,我們進(jìn)入正題:15種Chunking技巧,每種都配有使用場(chǎng)景、優(yōu)缺點(diǎn)和代碼示例,建議收藏!
1. 固定大小切塊(Fixed-Size Chunking)
原理:按固定詞數(shù)或token數(shù)切分。
適用場(chǎng)景:結(jié)構(gòu)簡(jiǎn)單的小文檔。
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單,速度快。
缺點(diǎn):可能切斷句子,丟失語義。
def fixed_size_chunk(text, max_words=100):
    words = text.split()
    return [' '.join(words[i:i + max_words]) for i in range(0, len(words), max_words)]2. 句子切塊(Sentence-Based Chunking)
原理:按句子邊界切分。
適用場(chǎng)景:需要保留語義完整性的文檔。
優(yōu)點(diǎn):語義清晰,上下文連貫。
缺點(diǎn):句子長(zhǎng)度不一,chunk大小不穩(wěn)定。
import spacy
nlp = spacy.load("en_core_web_sm")
def sentence_chunk(text):
    doc = nlp(text)
    return [sent.text for sent in doc.sents]3. 段落切塊(Paragraph-Based Chunking)
原理:按段落切分。
適用場(chǎng)景:結(jié)構(gòu)清晰的文檔,如論文、報(bào)告。
優(yōu)點(diǎn):自然分段,語義完整。
缺點(diǎn):段落長(zhǎng)度不一,可能超token限制。
def paragraph_chunk(text):
    return text.split('\n\n')4. 語義切塊(Semantic Chunking)
原理:基于語義相似度進(jìn)行切塊。
適用場(chǎng)景:技術(shù)文檔、復(fù)雜文本。
優(yōu)點(diǎn):上下文保留好。
缺點(diǎn):實(shí)現(xiàn)復(fù)雜,需依賴模型。
def semantic_chunk(text, max_len=200):
    doc = nlp(text)
    chunks = []
    current_chunk = []
    for sent in doc.sents:
        current_chunk.append(sent.text)
        if len(' '.join(current_chunk)) > max_len:
            chunks.append(' '.join(current_chunk))
            current_chunk = []
    if current_chunk:
        chunks.append(' '.join(current_chunk))
    return chunks5. 模態(tài)感知切塊(Modality-Specific Chunking)
原理:文本、表格、圖片分別處理。
適用場(chǎng)景:PDF、技術(shù)手冊(cè)等混合內(nèi)容文檔。
優(yōu)點(diǎn):保留多種模態(tài)信息。
缺點(diǎn):實(shí)現(xiàn)復(fù)雜。
def modality_chunk(text, images=None, tables=None):
    text_chunks = paragraph_chunk(text)
    return {'text_chunks': text_chunks, 'images': images, 'tables': tables}6. 滑動(dòng)窗口切塊(Sliding Window Chunking)
原理:相鄰chunk之間有重疊。
適用場(chǎng)景:法律、學(xué)術(shù)文檔。
優(yōu)點(diǎn):上下文連貫。
缺點(diǎn):內(nèi)容重復(fù),處理量大。
def sliding_window_chunk(text, chunk_size=100, overlap=20):
    tokens = text.split()
    chunks = []
    for i in range(0, len(tokens), chunk_size - overlap):
        chunk = ' '.join(tokens[i:i + chunk_size])
        chunks.append(chunk)
    return chunks7. 層級(jí)切塊(Hierarchical Chunking)
原理:按章節(jié)、段落、子段落分層切塊。
適用場(chǎng)景:結(jié)構(gòu)化文檔,如論文、合同。
優(yōu)點(diǎn):保留文檔結(jié)構(gòu)。
缺點(diǎn):實(shí)現(xiàn)復(fù)雜。
def hierarchical_chunk(text, section_keywords):
    sections = []
    current_section = []
    for line in text.splitlines():
        if any(keyword in line for keyword in section_keywords):
            if current_section:
                sections.append("\n".join(current_section))
            current_section = [line]
        else:
            current_section.append(line)
    if current_section:
        sections.append("\n".join(current_section))
    return sections8. 內(nèi)容感知切塊(Content-Aware Chunking)
原理:根據(jù)內(nèi)容特征動(dòng)態(tài)調(diào)整切塊策略。
適用場(chǎng)景:電子書、技術(shù)文檔。
優(yōu)點(diǎn):靈活適應(yīng)不同內(nèi)容。
缺點(diǎn):邏輯復(fù)雜。
def content_aware_chunk(text):
    chunks = []
    current_chunk = []
    for line in text.splitlines():
        if line.startswith(('##', '###', 'Introduction', 'Conclusion')):
            if current_chunk:
                chunks.append('\n'.join(current_chunk))
            current_chunk = [line]
        else:
            current_chunk.append(line)
    if current_chunk:
        chunks.append('\n'.join(current_chunk))
    return chunks9. 表格感知切塊(Table-Aware Chunking)
原理:將表格獨(dú)立切塊。
適用場(chǎng)景:財(cái)務(wù)報(bào)表、技術(shù)文檔。
優(yōu)點(diǎn):保留表格結(jié)構(gòu)。
缺點(diǎn):格式可能丟失。
import pandas as pd
def table_aware_chunk(table):
    return table.to_markdown()10. Token級(jí)切塊(Token-Based Chunking)
原理:按token數(shù)切塊,適配Transformer模型。
適用場(chǎng)景:GPT、BERT等模型。
優(yōu)點(diǎn):適配模型限制。
缺點(diǎn):可能切斷句子。
from transformers import GPT2Tokenizer
tokenizer = GPT2Tokenizer.from_pretrained("gpt2")
def token_based_chunk(text, max_tokens=200):
    tokens = tokenizer(text)["input_ids"]
    chunks = [tokens[i:i + max_tokens] for i in range(0, len(tokens), max_tokens)]
    return [tokenizer.decode(chunk) for chunk in chunks]11. 實(shí)體感知切塊(Entity-Based Chunking)
原理:基于NER識(shí)別實(shí)體進(jìn)行切塊。
適用場(chǎng)景:簡(jiǎn)歷、合同、法律文檔。
優(yōu)點(diǎn):保留實(shí)體信息。
缺點(diǎn):需訓(xùn)練NER模型。
def entity_based_chunk(text):
    doc = nlp(text)
    return [ent.text for ent in doc.ents]12. 主題切塊(Topic-Based Chunking)
原理:使用LDA等主題模型進(jìn)行切塊。
適用場(chǎng)景:新聞、研究論文等多主題文檔。
優(yōu)點(diǎn):按主題聚合信息。
缺點(diǎn):需額外建模。
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
def topic_based_chunk(text, num_topics=3):
    sentences = text.split('. ')
    vectorizer = CountVectorizer()
    sentence_vectors = vectorizer.fit_transform(sentences)
    lda = LatentDirichletAllocation(n_components=num_topics, random_state=42)
    lda.fit(sentence_vectors)
    # 省略主題分配邏輯
    return sentences13. 頁面切塊(Page-Based Chunking)
原理:按PDF頁面切塊。
適用場(chǎng)景:PDF文檔。
優(yōu)點(diǎn):實(shí)現(xiàn)簡(jiǎn)單。
缺點(diǎn):可能斷句。
def page_based_chunk(pages):
    return pages14. 關(guān)鍵詞切塊(Keyword-Based Chunking)
原理:按關(guān)鍵詞切分。
適用場(chǎng)景:結(jié)構(gòu)清晰的文檔。
優(yōu)點(diǎn):符合文檔結(jié)構(gòu)。
缺點(diǎn):需預(yù)定義關(guān)鍵詞。
def keyword_based_chunk(text, keywords):
    chunks = []
    current_chunk = []
    for line in text.splitlines():
        if any(keyword in line for keyword in keywords):
            if current_chunk:
                chunks.append('\n'.join(current_chunk))
            current_chunk = [line]
        else:
            current_chunk.append(line)
    if current_chunk:
        chunks.append('\n'.join(current_chunk))
    return chunks15. 混合切塊(Hybrid Chunking)
原理:結(jié)合多種策略。
適用場(chǎng)景:復(fù)雜文檔。
優(yōu)點(diǎn):靈活強(qiáng)大。
缺點(diǎn):實(shí)現(xiàn)復(fù)雜。
def hybrid_chunk(text):
    paragraphs = paragraph_chunk(text)
    hybrid_chunks = []
    for paragraph in paragraphs:
        hybrid_chunks += sentence_chunk(paragraph)
    return hybrid_chunks04|不同場(chǎng)景下如何選擇Chunking策略?
場(chǎng)景類型  | 推薦策略  | 
FAQ、客服系統(tǒng)  | 句子切塊、關(guān)鍵詞切塊  | 
學(xué)術(shù)論文  | 層級(jí)切塊、語義切塊  | 
技術(shù)文檔  | 表格感知切塊、內(nèi)容感知切塊  | 
多模態(tài)文檔  | 模態(tài)感知切塊、混合切塊  | 
法律文檔  | 滑動(dòng)窗口切塊、實(shí)體感知切塊  | 
05|結(jié)語:Chunking不是“切”,是“設(shè)計(jì)”
Chunking不是簡(jiǎn)單的“把文檔切碎”,而是一種信息架構(gòu)設(shè)計(jì)。不同的切塊策略,直接決定了RAG系統(tǒng)的檢索精度、生成質(zhì)量和響應(yīng)速度。
希望這篇文章能幫你找到最適合你業(yè)務(wù)的Chunking策略。如果你正在構(gòu)建RAG系統(tǒng),不妨從這些小技巧開始,逐步優(yōu)化你的文檔處理流程。
本文轉(zhuǎn)載自??Halo咯咯?? 作者:基咯咯


















