
开发RAG应用的一个关键步骤是对需要检索的文档,进行分块(Chunking)预处理,将文件划分为适当大小的文本片段,以便于后续的大语言模型处理。高质量的文档分块可以帮助大语言模型更好地理解和利用检索到的知识,提高生成结果的相关性和连贯性。如果分块不当,很可能会导致上下文信息不完整、语义断裂等问题,进而严重影响RAG应用的性能体验。
1. 传统的文本分块方法
2. 基于文档结构的语义分块-
(1)元素合并:为了得到足够大小的文本块,会将多个连续的文档元素合并为一个Chunk。合并过程在满足预设最大Chunk尺寸(如字符数上限)限制的前提下,尽可能填充每个Chunk。 -
(2)超长元素分割:当单个文档元素的长度超过最大Chunk尺寸时,需要进行二次分割。分割时采用滑动窗口的方式,生成多个Chunk。为了缓解在任意位置切断元素可能带来的语义断裂问题,应该在Chunk之间引入一定的重叠(Overlap),就是在下一个Chunk的开头包含前一个Chunk的结尾部分。

3. 分块策略与可调参数
-
max_characters 硬性字符数上限 max_characters参数指定了单个Chunk的硬性字符数上限。在分块过程中,任何Chunk的字符数都不会超过该值。当单个元素的字符数超过该上限时,会对其进行二次分割,生成多个子Chunk。该参数的默认值为500。 -
new_after_n_chars 软性字符数上限 new_after_n_chars参数指定了单个Chunk的软性字符数上限。当当前Chunk的字符数已经超过该值时,即使下一个元素的字符数在硬性上限以内,也会开启一个新的Chunk。该参数可以与max_characters配合使用,设置一个"首选"的Chunk大小。 -
overlap 文本分割时的重叠字符数 overlap参数指定了在对超长元素进行文本分割时,相邻子Chunk之间的重叠字符数。引入重叠可以缓解在任意位置切断元素可能带来的语义断裂问题。该参数的默认值为0,即不引入重叠。 -
overlap_all 是否对所有块应用重叠 overlap_all参数是一个布尔值,指定是否对所有Chunk都引入重叠,而不仅仅是对超长元素分割产生的子Chunk。由于普通的Chunk都由完整的元素构成,具有清晰的语义边界,对它们引入重叠可能会"污染"Chunk的语义完整性。用户需要根据具体应用场景权衡是否启用该选项。该参数的默认值为False。
-
Basic策略:按顺序最大化填充分块 Basic策略按照元素在文档中出现的顺序,将它们依次合并到Chunk中,尽可能填充每个Chunk,同时遵守max_characters和new_after_n_chars参数的限制。 对于超过max_characters的单个元素,Basic策略会将其隔离(不与其他元素合并),并对其进行文本分割,生成多个子Chunk。 表格元素(Table)始终被隔离,不与其他元素合并。超长的表格元素会被分割为多个TableChunk。 如果指定了overlap参数,那么在对超长元素分割时,以及在overlap_all为True时的所有Chunk之间,都会引入相应的重叠。 -
By-Title策略:保留章节和页面边界 By-Title策略在Basic策略的基础上,额外考虑了章节和页面的边界。
-
章节标题检测 By-Title策略将Title元素视为章节的开始标志。在遇到Title元素时,会结束当前Chunk,开启一个新的Chunk,即使Title元素可以放入当前Chunk。这样可以保证一个Chunk不会跨越章节边界。 -
页面边界保留 By-Title策略可以通过multipage_sections参数选择是否保留页面边界。当multipage_sections为True(默认值)时,页面边界不会触发新Chunk的开启。当其为False时,位于不同页面的元素会被分配到不同的Chunk中。 -
小章节的合并 在某些文档中,partitioning过程可能会将列表项或其他短小的段落误识别为Title元素,导致生成过多过小的Chunk。By-Title策略通过combine_text_under_n_chars参数提供了缓解这一问题的机制。该参数指定了一个字符数阈值,当连续的小节的字符数总和不超过该阈值时,它们会被合并到一个Chunk中,直到充满该Chunk为止。该参数的默认值与max_characters相同,即默认允许对小节进行合并。将其设置为0会禁用小节合并功能。
4. 工程实践与分析
为了评估不同分块策略和参数对RAG任务性能的影响,我们在多个数据集上进行了实验和测试。
5. 总结-
(1)对语义完整性要求较高的任务(如问答、对话生成等),优先考虑使用By-Title策略,并适当降低max_characters和new_after_n_chars的值,以获得更细粒度、信息更完整的Chunk。 -
(2)对处理效率要求较高的任务(如大规模文本分类、信息检索等),优先考虑使用Basic策略,并适当提高max_characters和new_after_n_chars的值,以获得更长、数量更少的Chunk。 -
(3)对信息重复较为敏感的任务,谨慎使用overlap和overlap_all参数,避免引入过多冗余。 -
(4)对Chunk内信息一致性要求较高的任务,优先考虑启用multipage_sections参数,以保留页面边界信息。

