外观
RAG 的 5 种分块策略
5 chunking strategies for RAG
下面是 RAG 的典型工作流程:

由于额外提供的文档可能很大,第一步也包含分块(chunking)操作,即把一份大文档切分成更小、更易处理的片段。
这一步至关重要,因为它能确保文本符合嵌入模型的输入尺寸限制。
以下是 RAG 常用的五种分块策略:

我们来逐一了解一下!
1)固定大小分块(Fixed-size chunking)
根据预先设定好的字符数、单词数或 token 数,把文本切分成大小统一的片段。

由于直接切分可能会打断语义的连贯性,建议在相邻两个分块之间保留一定的重叠部分(上图中的蓝色部分)。
这种方法实现起来很简单。而且由于所有分块大小一致,也简化了批处理流程。
但这种做法通常会把句子(或完整的意思)从中间切断,导致重要信息很可能被分散到不同的分块里。
2)语义分块(Semantic chunking)

根据句子、段落或主题片段等有意义的单元来切分文档。
接着,为每个片段生成嵌入。
假设我们从第一个片段及其嵌入开始。
如果第一个片段的嵌入与第二个片段的嵌入余弦相似度很高,这两个片段就会合并成一个分块。
这个过程会持续下去,直到余弦相似度出现明显下降。
一旦相似度明显下降,我们就开始一个新的分块,然后重复这个过程。
输出结果大致如下:

与固定大小分块不同,这种方法保持了语言的自然流畅性,也保留了完整的意思。
由于每个分块所包含的信息更丰富,这提高了检索的准确性,进而让 LLM 生成的回答更连贯、更相关。
一个小问题是,它依赖一个阈值来判断余弦相似度是否出现了明显下降,而这个阈值在不同文档之间可能会有所不同。
3)递归分块(Recursive chunking)

首先,根据段落、章节等文档中固有的分隔符进行分块。
接着,如果某个分块的大小超过了预先设定的分块大小上限,就把它进一步切分成更小的分块;如果分块本身就符合大小限制,则不再继续切分。
输出结果大致如下:

如上图所示:
首先,我们先划定两个分块(图中紫色的两个段落)。
接着,段落 1 会被进一步切分成更小的分块。
与固定大小分块不同,这种方法同样保持了语言的自然流畅性,也保留了完整的意思。
不过,这种方法在实现和计算复杂度上会带来一些额外开销。
4)基于文档结构的分块(Document structure-based chunking)

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

不过,这种方法假定文档具有清晰的结构,而实际情况未必如此。
另外,各个分块的长度可能参差不齐,有可能超出模型的 token 限制。你可以尝试把它和递归分块结合起来使用。
5)基于 LLM 的分块(LLM-based chunking)

提示 LLM 生成语义上彼此独立、且有意义的分块。
由于 LLM 能够理解上下文和含义,而不只是依赖简单的启发式规则(前面四种方法所用的方式),这种方法能保证很高的语义准确度。
但在这里讨论的五种技术中,这是计算开销最大的一种分块方法。
此外,由于 LLM 通常有上下文窗口的限制,这一点也需要留意。
每种技术都有各自的优势和取舍。
我们观察到,语义分块在很多场景下表现都相当不错,但还是需要你自己去测试验证。
具体选择哪种方式,取决于你的内容特点、嵌入模型的能力、计算资源等因素。