在构建一个高效的检索增强生成(RAG)系统时,一个常常被忽视但至关重要的环节是分块(Chunking)。这个过程是将大型文档切分成小块,以便 LLM 可以轻松地检索和理解。如果分块策略不当,即使拥有最先进的语言模型和向量数据库,你的 RAG 系统也可能表现不佳。
本文将深入探讨为什么分块如此重要,以及如何通过几种核心策略来优化它。
什么是词块
将词块视为 RAG 系统中知识的原子单元 。每个词块应该:
- 语义完整 :包含单独来看有意义的连贯信息。
- 语境丰富 :包含足够的周围环境,无需外部参考即可理解。
- 最佳尺寸 :足够大以具有意义,足够小以便精确检索。
- 边界感知 :尊重句子、段落和章节等自然语言结构。
这些要求经常相互冲突。语义完整的块可能太大,无法进行精确检索。大小合适的块可能会在边界处丢失关键上下文。这时,不同的分块策略就派上用场了。每种方法都有各自的优缺点,最佳选择取决于您的具体用例、文档类型和检索需求。
分块策略
下面由浅入深,介绍不同的分块策略:
固定大小分块(简单基线)
固定大小分块将文档拆分为预定大小的块,通常以以下方式测量:
- 字符数 (例如,每块 1000 个字符)
- 令牌数量 (例如,每块 256 个令牌)
- 字数统计 (例如,每段 200 个字)
重叠参数在这里至关重要。如果没有重叠,您可能会丢失跨越块边界的信息。重叠率为 20% 时,可以确保相邻块之间有一定的连续性。
固定大小分块策略几乎不适用于任何场景,仅在有限计算资源的情况。固定大小分块适用的场景:
- 有统一、简单的文档(博客、文章、小说)
- 处理速度至关重要
- 存储和计算资源严重有限
语义分块
语义分块代表着思维的根本性转变。语义分块不再根据大小限制任意切割文本,而是根据语义和文档结构识别自然断点。语义分块需要更多的计算资源,但能带来更好的结果。
核心见解:文档具有固有的语义边界,可以指导分块决策。
语义分块的工作原理:
- 句子分割 :将文档分解成单个句子
- 嵌入生成 :为每个句子创建向量表示
- 相似度分析 :测量相邻句子之间的语义相似度
- 边界检测 :在相似度低于阈值的地方创建块边界
- 组块 :将连续相似的句子组合成连贯的组块
高级语义技术:
- 主题建模集成 :使用基于 LDA 或 BERT 的主题模型来识别主题边界
- 层次聚类 :在分块之前按语义相似度对句子进行分组
- 实体连续性 :确保命名实体及其引用保持在同一块内
- 话语标记 :使用语言线索(但是、此外、总之)来识别界限
语义分块适用于很多场景:
- 文档质量差异很大
- 上下文保存很重要
- 准确性比速度更重要
分层文档分块
对于具有嵌套结构的复杂文档(例如技术手册、法律合同或学术论文),分层分块可以保留文档的组织逻辑。这种方法认识到文档不是平面文本,而是具有章节、小节和逻辑层次的结构化知识。
分层分块的主要优点:
- 上下文继承 :每个块都知道它在文档层次结构中的位置
- 元数据保存 :维护章节标题、级别和关系
- 结构感知检索 :您可以按不同的粒度进行检索(部分与小节)
- 交叉引用处理 :对其他部分的引用仍然有意义
对于 200 页的技术手册,分层分块可能会创建:
- 15 个章节级块(高级概述)
- 127 个部分级块(详细解释)
- 340 个子节级块(具体程序)
在检索过程中,系统可以将查询与适当的细节级别进行匹配,并提供分层上下文。
如果出现以下情况,则实施分层分块:
- 文件结构清晰(手册、报告、学术论文)
- 用户需要不同程度的细节
- 交叉引用很常见
- 文档格式结构良好
滑动窗口分块(重叠优化器)
传统的组块方法会创建离散的、不重叠的组块。但是,如果最重要的信息恰好落在组块边界上,该怎么办呢?滑动窗口分块通过创建重叠块解决了这个问题,确保没有信息被遗漏。
当 window_size=1000、stride=800 时,可获得 200 个字符的重叠(20%)。此重叠可确保:
- 关键句子没有被拆分成多个部分
- 上下文在相邻块之间自然流动
- 检索有多次机会找到相关信息
自适应滑动窗口
高级实现根据内容密度调整窗口大小和步幅:
- 常见问题解答文档 :问题和答案受益于重叠的上下文
- 法律文件 :精确的语言界限至关重要
- 技术程序 :步骤参考先前的操作
- 叙事内容 :故事连续性至关重要
大模型分块
使用大语言模型进行递归分块: 最新的进展是使用 LLM 本身进行分块决策。
多模态分块
对于包含图像、表格和混合内容的文档。
基于查询模式的动态分块
最先进的系统根据文档的实际查询方式来调整分块。