Skip to content

RAG 的 5 种分块策略

5 chunking strategies for RAG

下面是 RAG 的典型工作流程:

rag p118 2

由于额外提供的文档可能很大,第一步也包含分块(chunking)操作,即把一份大文档切分成更小、更易处理的片段。

这一步至关重要,因为它能确保文本符合嵌入模型的输入尺寸限制。

以下是 RAG 常用的五种分块策略:

rag p119 1

我们来逐一了解一下!

1)固定大小分块(Fixed-size chunking)

根据预先设定好的字符数、单词数或 token 数,把文本切分成大小统一的片段。

rag p120 1

由于直接切分可能会打断语义的连贯性,建议在相邻两个分块之间保留一定的重叠部分(上图中的蓝色部分)。

这种方法实现起来很简单。而且由于所有分块大小一致,也简化了批处理流程。

但这种做法通常会把句子(或完整的意思)从中间切断,导致重要信息很可能被分散到不同的分块里。

2)语义分块(Semantic chunking)

rag p120 2

根据句子、段落或主题片段等有意义的单元来切分文档。

接着,为每个片段生成嵌入。

假设我们从第一个片段及其嵌入开始。

如果第一个片段的嵌入与第二个片段的嵌入余弦相似度很高,这两个片段就会合并成一个分块。

这个过程会持续下去,直到余弦相似度出现明显下降。

一旦相似度明显下降,我们就开始一个新的分块,然后重复这个过程。

输出结果大致如下:

rag p121 1

与固定大小分块不同,这种方法保持了语言的自然流畅性,也保留了完整的意思。

由于每个分块所包含的信息更丰富,这提高了检索的准确性,进而让 LLM 生成的回答更连贯、更相关。

一个小问题是,它依赖一个阈值来判断余弦相似度是否出现了明显下降,而这个阈值在不同文档之间可能会有所不同。

3)递归分块(Recursive chunking)

rag p121 2

首先,根据段落、章节等文档中固有的分隔符进行分块。

接着,如果某个分块的大小超过了预先设定的分块大小上限,就把它进一步切分成更小的分块;如果分块本身就符合大小限制,则不再继续切分。

输出结果大致如下:

rag p122 1

如上图所示:

首先,我们先划定两个分块(图中紫色的两个段落)。

接着,段落 1 会被进一步切分成更小的分块。

与固定大小分块不同,这种方法同样保持了语言的自然流畅性,也保留了完整的意思。

不过,这种方法在实现和计算复杂度上会带来一些额外开销。

4)基于文档结构的分块(Document structure-based chunking)

rag p122 2

这种方法利用文档中固有的结构——比如标题、章节或段落——来确定分块边界。这样一来,分块就能与文档的逻辑段落对齐,保持结构上的完整性。

输出结果大致如下:

rag p123 1

不过,这种方法假定文档具有清晰的结构,而实际情况未必如此。

另外,各个分块的长度可能参差不齐,有可能超出模型的 token 限制。你可以尝试把它和递归分块结合起来使用。

5)基于 LLM 的分块(LLM-based chunking)

rag p123 2

提示 LLM 生成语义上彼此独立、且有意义的分块。

由于 LLM 能够理解上下文和含义,而不只是依赖简单的启发式规则(前面四种方法所用的方式),这种方法能保证很高的语义准确度。

但在这里讨论的五种技术中,这是计算开销最大的一种分块方法。

此外,由于 LLM 通常有上下文窗口的限制,这一点也需要留意。

每种技术都有各自的优势和取舍。

我们观察到,语义分块在很多场景下表现都相当不错,但还是需要你自己去测试验证。

具体选择哪种方式,取决于你的内容特点、嵌入模型的能力、计算资源等因素。

本站内容仅供学习交流,版权归原作者所有。