技术资讯
RAG应用中文本分块策略排行榜:十大高效方案提升检索增强生成效果
摘要
检索增强生成中,文档分块策略影响语义完整性与检索效果。传统方法依赖标点或固定长度
# 检索增强生成中的文档分块:策略、参数与工程实践
检索增强生成,简称RAG,已经成为大语言模型应用开发中绕不开的一项技术。它的思路其实很直接:当用户提出一个问题时,系统不是让大模型凭空作答,而是先从专门搭建的外部知识库中检索出相关信息,把这些信息作为“参考资料”连同问题一起交给模型,最终生成更准确、更贴合业务场景的回复。
听起来简单,但真正落地的时候,一个最容易被忽视、却又至关重要的环节就浮出水面了——文档分块。你手头有一堆文档要喂给RAG系统,怎么切?切多大块?切不好会怎么样?这些问题处理不当,轻则语义断裂,重则直接拉垮整个应用的体验。
先说说为什么分块这么关键。开发RAG应用,第一步往往是对文档做预处理,也就是所谓的“分块”。目的是把文档切成大小合适的文本片段,方便后续模型检索和处理。一块高质量的文本片段,应该是一个相对完整的语义单元——它包含的信息足够让模型理解上下文,而不是把一句话劈成两半,或者把两个不相干的话题硬塞到一起。分块做得不好,上下文信息不完整、语义断裂的问题就会接踵而来,检索出来的内容牛头不对马嘴,生成的结果自然也就没法看。
## 传统的文本分块方法
在自然语言处理这个领域,文本分块算是基本功了。传统方法主要依赖文本的格式和结构特征,比如标点符号、换行符之类的东西。常见的做法有这么几种:
- **基于标点符号的分块**:根据句号、问号、感叹号这些标点符号,把文本切成一个个句子。
- **基于换行符的分块**:根据换行符,把文本切成段落或者列表项。
- **固定长度的滑动窗口**:设定一个固定的字符数或者单词数,用这个窗口在文本上滑动,生成一系列重叠或不重叠的文本块。
这些方法的优点在于实现简单、上手快。但问题也很明显——它们几乎不考虑文本的语义结构。一个完整的语义单元可能横跨好几个句子,也可能被一个句号拦腰斩断。一刀切下去,信息丢了,语义连贯性也没了。
## 基于文档结构的语义分块
### 利用文档元素进行分块
HTML、PDF、Word这些文件格式,其实自带了很多结构和布局信息。标题、正文、表格、列表——这些东西不仅仅是视觉上的排版,它们还反映了文档的语义层次。
换句话说,一份文档天然就由一系列“文档元素”构成:一个标题代表一个章节的开始,一段正文承载一个完整的知识点,一张表格表达一组结构化的数据。在分块的时候,预处理程序应该尽量保留这些元素的完整性,不让一个完整的语义单元被切成两半。
### 两个关键机制:元素合并与超长元素分割
在实际的分块过程中,预处理管道需要处理两种常见的情况:
第一个是**元素合并**。一个单独的文档元素往往太小了,撑不起一个合适大小的Chunk。比如一个简短的段落只有几十个字,直接作为一个Chunk显然太单薄。这时候就需要把连续的几个元素合并到一起,组成一个更大的文本块。这个过程遵循一个基本原则:在不超过最大Chunk尺寸(比如字符数上限)的前提下,尽可能多地往里面填内容。
第二个是**超长元素分割**。反过来,有些元素实在太长了——比如一篇几千字的正文,或者一张巨长的表格。单个元素的长度已经超过了最大Chunk尺寸,这时候就必须把它切开。切割的方式通常采用滑动窗口,把长元素分成多个Chunk。但问题来了——在任意位置切断元素,很容易把语义关系打断。解决方案是引入重叠机制,让下一个Chunk的开头包含前一个Chunk的结尾部分。这样一来,即使模型检索到边界区域,也能拿到足够的上下文信息。
### 输出三种类型的Chunk
经过分块预处理,最终输出的Chunk有三种类型:
- **CompositeElement**:这是最常见的类型,由多个文档元素合并而成。
- **Table**:由单个表格元素直接构成的Chunk。
- **TableChunk**:超长表格被分割后生成的子表Chunk。
每个Chunk都继承了原始元素的属性信息(比如来源、位置、格式标签等),同时还会保留构成它的原始元素列表。这样做的意义在于:后续如果需要对检索结果进行追溯,可以很方便地根据元数据找到原始文档中的对应位置。

## 分块策略与可调参数
### 常用的可调参数
要控制分块预处理管道的行为,有几个关键参数需要关注:
- **max_characters**:硬性字符数上限。任何Chunk的字符数都不能超过这个值。当单个元素超过这个上限时,会触发二次分割。默认通常是500个字符。
- **new_after_n_chars**:软性字符数上限。当当前Chunk的字符数已经超过这个值时,即使下一个元素放进来还不会超过硬性上限,也会强制开启一个新的Chunk。说白了,这个参数决定了你“希望”Chunk多长,而max_characters决定了“绝对不能超过多长”。
- **overlap**:文本分割时的重叠字符数。只对超长元素切割时产生的子Chunk起作用。默认值为0,即不重叠。
- **overlap_all**:是否对所有Chunk都应用重叠,而不仅仅是超长元素切割出来的子Chunk。普通Chunk通常由完整的元素构成,语义边界本来就清晰。硬加重叠反而可能污染这种完整性,所以默认是关闭的。是否开启,需要根据具体场景权衡。
### Basic策略与By-Title策略
预处理管道通常提供两种分块策略。
**Basic策略**:按顺序最大化填充分块。简单粗暴——按照元素在文档中间出现的顺序,一个一个往Chunk里塞,直到塞不下为止。对于超长元素,会单独隔离出来做切割。表格元素始终被隔离,不与其他元素合并。超长表格会被分成多个TableChunk。
**By-Title策略**:保留章节和页面边界。这个策略在Basic的基础上加入了对文档结构的尊重。它会把标题元素视为章节的开始标志——遇到标题,强制结束当前Chunk,开启一个新Chunk。这样就能保证一个Chunk不会跨越章节边界。
页面边界的处理也是一个选项。通过`multipage_sections`参数可以选择是否保留页面边界。默认情况下,页面边界不会触发新Chunk(即跨页内容可以合并)。如果将其设为False,位于不同页面的元素会被分到不同的Chunk中。
还有一个值得注意的机制:小章节的合并。有时候,分区处理程序会把列表项或者短段落误识别为标题,结果生成了一堆又小又碎的Chunk。`combine_text_under_n_chars`参数就是用来处理这个问题的——当连续几个章节的字符数总和不超过某个阈值时,它们会被合并到一个Chunk里。默认值跟max_characters相同,设为0则禁用合并功能。
## 工程实践与分析
为了搞清楚不同策略和参数到底怎么影响实际效果,我们在多个数据集上做了实验。
### 不同策略下Chunk的特点对比
先说结论:Basic和By-Title两种策略,在几个维度上表现差异明显。
**语义完整性**:By-Title策略在章节和页面边界上更加完整。Basic策略可能把跨越边界的內容合并到一起,导致语义断裂。
**信息重叠**:使用overlap参数时,By-Title策略在章节和页面边界处产生的重叠信息更自然,不会引入过多冗余。Basic策略在任意位置引入的重叠,有时会导致部分Chunk包含大量重复信息。
**Chunk长度分布**:By-Title策略生成的Chunk长度分布更不均衡——章节边界处容易产生较短的Chunk。Basic策略生成的Chunk长度更均匀,更接近设定的目标长度。
**元信息保留**:By-Title策略更多地保留了原始元素的边界,Chunk中元信息的丢失相对更少,后续从metadata中恢复原始内容也更容易。
### 参数对下游任务性能的影响
进一步评估了不同参数对RAG模型在下游任务中的表现。
**max_characters和new_after_n_chars**:较大的值可以产生更长的Chunk,数量更少,处理效率更高。但过长的Chunk可能超过语言模型的最大输入长度,导致部分信息被截断。较小的值产生更细粒度的Chunk,信息保存更完整,但处理开销也更大。
**overlap和overlap_all**:适度的重叠可以缓解Chunk边界处的语义断裂问题,提升模型表现。但过多重叠会引入冗余信息,降低效率。overlap_all的效果在不同任务上差异很大,有些任务上性能提升,有些任务上反而变差。
**multipage_sections和combine_text_under_n_chars(By-Title策略)**:保留页面边界有助于减少Chunk内的信息不一致问题,但可能产生过多过短的Chunk。启用小节合并可以缓解这个问题,但可能导致部分边界信息丢失。
实践经验告诉我们一个朴素的道理:不同的任务对分块策略和参数的敏感程度完全不同。没有放之四海而皆准的最优配置,必须根据实际需求反复调试。
## 总结
文档分块策略在RAG任务中扮演着一个看似基础、实则关键的角SE。合理的分块能让模型更好地理解检索到的知识,提高生成结果的相关性、连贯性和信息完整性。不同的策略和参数会导致不同特点的Chunk,进而影响模型在下游任务中的表现。
从工程实践来看,不存在全局最优的分块策略和参数组合。在实际应用中,只能根据具体任务的特点和需求,权衡不同配置带来的效果差异。
下面是一些经验法则:
- **对语义完整性要求较高的任务**(比如问答、对话生成),优先考虑By-Title策略,适当降低max_characters和new_after_n_chars的值,以获得更细粒度、信息更完整的Chunk。
- **对处理效率要求较高的任务**(比如大规模文本分类、信息检索),优先考虑Basic策略,适当提高max_characters和new_after_n_chars的值,以获得更长、数量更少的Chunk。
- **对信息重复较为敏感的任务**,谨慎使用overlap和overlap_all参数,避免引入过多冗余。
- **对Chunk内信息一致性要求较高的任务**,优先考虑启用multipage_sections参数,保留页面边界信息。
最后,文档分块策略的设计和实现是RAG应用开发中数据工程团队的重要工作。数据工程师需要充分理解业务场景和技术需求,在策略选择和参数调优上反复试验,才能找到性能与效果的最佳平衡点。
来源:互联网
免责声明
本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。