首页 > 教程攻略 > ai资讯 >大模型RAG问答中的文档分段策略回顾:兼并看LumberChunker动态分块思想

大模型RAG问答中的文档分段策略回顾:兼并看LumberChunker动态分块思想

来源:互联网 时间:2026-08-13 14:15:19

今天是2024年6月27日,星期四,北京,天气晴。

大模型RAG问答中的文档分段策略回顾:兼并看LumberChunker动态分块思想

今天咱们来深入聊聊RAG里一个很关键的问题——文档分段。先快速过一遍现有的几种主流分段思路,再重点看看基于大模型做动态分块的新方案,也就是LumberChunker。这个话题挺有意思,值得花点时间拆解清楚。

问题1:文档分段的现有几个思路回顾

昨天聊过句子分段,今天把段落级的分段方法也一并理一理。目前业界已经有好几套方案了,下图来自一篇不错的博客(Mastering RAG: Advanced Chunking Techniques),一张表就把各自优劣势说清楚了:

1、递归分块

:按照段落分隔符、新行、空格、单个字符这样的层级顺序往下切,Langchain的RecursiveCharacterTextSplitter函数就是典型实现。本质上是先按最大的分隔符(比如段落)分割,如果块还是太大,再按下一级分隔符递归切割,直到满足长度要求。简单粗暴,但容易把语义连贯的内容拦腰截断。

2、语义分块

:先用OpenAI的text-ada-embedding-002把每个段落块嵌入成向量,然后计算相邻块嵌入之间的距离。如果距离超过某个阈值,就认为这里发生了语义切换,在此处设断点。关键在于阈值怎么定——设大了可能漏分,设小了又容易过度分割。一旦断点确定,文本就被切成语义相对独立的块。这个方法的好处是能捕捉到内容主题的自然变化,但阈值调参是个头疼事。具体实现可以参考GitHub上的semantic-split项目。

3、命题分块

:这已经是在拿大模型做切分了。思路来自论文《Dense X Retrieval》,核心是把文本送入ChatGPT等大模型,让模型生成"命题"(proposition)——也就是最小且自包含的信息单元,每个命题表达一个独立的事实或观点。关键在prompt的设计,得告诉模型要拆到什么粒度。检索时,这些命题会作为混合来源参与召回。相比前两种方法,它更精细,但代价就是需要调用大模型,速度和成本都上去了。

问题2:基于大模型进行动态分块的LumberChunker思想

针对长篇叙事文本,最近有一篇新工作值得关注——《LumberChunker: Long-Form Narrative Document Segmentation》。它提出了一种利用LLM动态分割长篇叙事文档的方法,让每个块在语义上独立、连贯,又与相邻块有所区别。直接说几个重点。

1、实现思想

核心逻辑很简单:不再固定块大小,而是让块的大小随着内容的语义自然变化。具体流程分三步走:

第一步

:把文档按段落分割,每个段落分配一个唯一的递增ID。

第二步

:把连续的段落逐个追加成一个组(Gi),直到组的总token数超过预定义的阈值θ。这个θ是经验值——太小会把相关段落拆开,太大又可能超出模型上下文窗口、影响推理精度。实验表明,当θ=550时效果最佳,DCG@k得分最高。

第三步

:把这个段落组Gi喂给LLM(比如Gemini 1.0-Pro),让它找出组里"与前文内容显著不同"的某个特定段落——这个段落就是上一个块的结束点,也是下一个块的起点。然后重复这个过程,循环切分整个文档。

来看prompt的设计细节:

``` You are an expert text analyzer. Given the following sequence of consecutive paragraphs (delimited by markers), identify the paragraph where a significant topic shift occurs compared to the content before it. Output the paragraph ID. ```

文档就是这样一圈一圈地被切成语义块的。每个新的Gi+1组的起始点,就是上一次迭代中识别出的那个"转折段落"。

2、实现效果

为了验证效果,作者构建了一个新基准测试——GutenQA,从Project Gutenberg上的100本叙事书籍中手动提取了3000对问答数据。RAG的设计框架也有不少可借鉴之处:

查询路由与文档集成

:每个查询先进一个检测器,看是否涉及人名或事件。如果检测到了,就用BM25检索前3个最相关的块;如果没检测到(检测器偶尔会漏),就退一步检索单个文档作为兜底。同时再通过密集检索(dense embedding)取前15个块,用来捕获BM25可能漏掉的深层语义关系。然后检查BM25结果和密集检索结果是否有重叠,删除重叠文档避免冗余。最后把BM25排名最高的文档放在检索列表最前面,第二和第三的放末尾——形成混合策略。

文档重排序与重排名

:检索到的块被集成到ChatGPT(gpt-3.5-turbo)的上下文窗口中。如果上下文超过6个块,就从中间点开始反转块的顺序——这么做是为了对抗"中间丢失"问题(模型对长上下文中间位置内容的记忆衰减,呈现U形性能曲线)。然后让ChatGPT根据这些块与查询的相关性,从高到低重新排序。

最终答案生成

:最后一步只保留排序后的前5个文档用于生成答案。模型从这5个顶级文档里综合信息,输出连贯且上下文准确的回答。

实验结果很亮眼——LumberChunker在检索性能上比所有竞争基线高出7.37%(DCG@20指标),并且当集成到RAG流程中时,比Gemini 1.5 Pro等方案更有效。

3、方案评价

当然,缺点也很明显。作者自己也坦承:LumberChunker需要调用LLM,比传统方法更昂贵、更慢。而且它是为叙事文本设计的——那些结构松散、依赖语义理解的长篇内容。如果换到法律合同这种高度结构化的文本,LumberChunker就有点杀鸡用牛刀了,反而可能过于复杂。

代码已在GitHub开源,感兴趣可以自行参考。