70%的RAG性能与分块有关

RAG(检索增强生成)管道在很大程度上依赖于你如何分割文档(分块)。在这篇文章中,我将介绍RAG工作流程,突出分块在其中的作用,然后深入探讨固定、递归、语义、基于结构和后期分块技术,包括定义、权衡和伪代码,以便你能采用适合自己用例的方法。

检索增强生成(RAG)工作流程(高级)

以下是标准流程:

按回车键或点击以查看全尺寸图像

  1. 文档摄取与分块 处理大型文档(PDF、HTML、原始文本)→ 分割("分块")→ 计算嵌入向量 → 在向量DB中建立索引。

  2. 查询 / 检索 用户查询 → 嵌入查询 → 检索最接近的前 k 个块(通过余弦相似度)

  3. 增强 / 提示构建将检索到的文本块(加上元数据)注入到大语言模型提示中,通常会使用模板和过滤器。

  4. 生成 大语言模型(LLM)基于检索到的上下文和模型先验生成答案。

由于生成器只能看到你提供给它的内容,因此你的检索质量起着主导作用。如果文本块格式错误或不相关,即使是最好的大语言模型也无法挽救。这就是为什么很多人说检索增强生成(RAG)大约70%在于检索,30%在于生成。

在我们深入探讨技巧之前,先来了解一下为什么良好的组块化是必不可少的:

  • 嵌入和大语言模型(LLM)有上下文窗口限制;你不能直接处理大型文档。

  • 文本块需要语义连贯。如果在句子中间或想法中间进行分割,嵌入结果将产生噪声或具有误导性。

  • 如果你的数据块太大,系统可能会遗漏细粒度的相关信息。

  • 相反,如果数据块太小或重叠过多,就会存储冗余内容,浪费计算/存储资源。

让我们来探索五种突出的组块技术,从最简单到最先进。

1. 固定分块

将文本分割成大小相等的块(按标记、单词或字符),块之间通常有重叠。

它是您的RAG项目的良好起点,在文档结构未知时是不错的基线,或者适用于统一/枯燥的文本(日志、纯文本)。

实现代码示例:

ini 复制代码
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. 递归分块

首先在高层次边界(例如段落或章节)处进行分割。如果分割后的块仍然太大(超过限制),则递归地进一步分割(例如按句子),直到所有块都在限制范围内。

适用于半结构化文档(包含章节、段落),在这类文档中,你既希望保留语义边界,又要限制篇幅。

它尽可能保留逻辑单元(段落),避免跨越不自然的界限,并且你会得到一组适合内容变化的混合尺寸

递归分块示例(LangChain)

ini 复制代码
from langchain.text_splitter import RecursiveCharacterTextSplitter

# Sample text
text = """
Input text Placeholder...
"""

# Define a RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(
    chunk_size=200,           # target size of each chunk
    chunk_overlap=50,         # overlap between chunks for context continuity
    separators=["\n\n", "\n", " ", ""]  # order of recursive splitting
)

# Split the text
chunks = text_splitter.split_text(text)

# Display results
for i, chunk in enumerate(chunks, 1):
    print(f"Chunk {i}:\n{chunk}\n{'-'*40}")

这样可以确保在你嵌入和稍后检索文本块时,不会在边界处丢失重要的上下文信息。

3.语义分块

按语义转换对文本进行分段。使用嵌入(例如句子嵌入)来确定一个段落的结束位置和下一个段落的起始位置。如果相邻的段落非常相似,则将它们合并;当相似度降低时,则进行分割。

当检索精度至关重要时(法律文本、科学文章、支持文档)效果最佳,但你需要留意嵌入和相似度计算成本,同时定义阈值(相似度下降)需要仔细调整

实现代码示例

ini 复制代码
from sentence_transformers import SentenceTransformer, util

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

def semantic_chunk(text, sentence_list, sim_threshold=0.7):
    embeddings = model.encode(sentence_list)
    chunks = []
    current = [sentence_list[0]]
    for i in range(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. 基于结构的分块

使用文档的固有结构,如标题、副标题、HTML标签、表格、列表项等,作为自然的分块边界。 例如,每个章节或标题成为一个分块(或进一步递归分块)。 最适合HTML页面、技术文档、类似维基百科的内容或任何带有语义标记的内容。

根据我的个人经验,这种策略能取得最佳效果,尤其是与递归分块结合使用时。

然而,它需要解析和理解文档格式,对于大篇幅内容可能会超出令牌限制,因此可能需要采用递归拆分的混合方法。

实施提示

  • 使用 HTML / Markdown / PDF 结构库进行解析

  • 使用章节 /

    等作为块根

  • 如果一个部分太大,则回退到递归拆分

  • 对于表格/图像,要么将它们视为单独的部分,要么对其进行总结

5. 延迟分块(又称动态/查询时分块)

定义

延迟分块意味着将文档的分割方式推迟到查询时。不是预先将所有内容分割,而是存储较大的片段或整个文档。当查询到来时,只有相关的片段才会被动态分割(或过滤)。这样做的目的是在嵌入过程中保留完整的上下文,只在必要时进行分解。

Weaviate

将延迟分块描述为"

颠倒嵌入和分块的传统顺序

"。

  1. 首先使用长上下文模型嵌入整个文档(或大段内容)。

  2. 然后进行合并并创建分块嵌入(基于标记跨度或边界线索)。

概念流程

  1. 在索引中存储大段内容或整个文档。

  2. 查询时,检索1 - 2个顶级片段。

  3. 在这些内容中,围绕与查询匹配的部分动态分割(例如语义分割或重叠分割)成细粒度的片段。

  4. 过滤或排序块以提供给生成器。

按回车键或点击以查看全尺寸图像

这种方法类似于编程中的延迟绑定,直到有更多上下文时再进行处理。

用例

  • 大文档集(技术报告、长篇内容),其中段落间的上下文关系很重要。

  • 在**文档内容经常变化的系统中,**避免完全重新分块可以节省时间。

  • 高风险或对精度敏感的检索增强生成(RAG)应用(法律、医疗、监管领域),在这些应用中,对代词或指代的误解可能代价高昂。

这听起来很高级,但也有代价。嵌入整个文档(或大篇幅内容)的计算成本很高,可能需要具有长标记限制的模型。 它还会增加查询时的成本,包括计算成本和潜在的延迟。

相关推荐
yaocheng的ai分身10 小时前
超越分类:AI agent如何大规模改进Shopify的产品分类学
llm·agent
重铸码农荣光11 小时前
用 n8n 工作流自动化生成科技新闻速览:从 RSS 聚合到 AIGC 的效率革命
agent
kailp11 小时前
OpenAI发布AI浏览器Atlas:探索下一代网页交互新可能
人工智能·大模型·云计算·aigc·算力
Mintopia12 小时前
🤖 算法偏见修正:WebAI模型的公平性优化技术
前端·javascript·aigc
墨风如雪1 天前
OpenAI重磅发布ChatGPT Atlas:告别传统浏览器的AI新纪元!
aigc
win4r1 天前
🚀DeepSeek又放大招!这个OCR模型让文档识别效率倍增!本地部署+客观实测DeepSeek-OCR!OCR识别准确率97%,支持100+语言,每天处理3
llm·aigc·deepseek
王中阳Go1 天前
挑战一周用 AI 开发商业化项目!4 大痛点反思 + 新手专属提示词分享
后端·aigc·openai
win4r1 天前
🚀彻底改写浏览器自动化!ChatGPT Atlas浏览器深度评测:Agent模式自动操作网页太疯狂!跨网页理解+长文秒懂+图片识别,论文工作流被改写!看完你会
chatgpt·aigc·openai
算家计算1 天前
OpenAI推出首款浏览器,能否撼动全球超30亿用户的Chrome?
人工智能·openai·资讯