在 RAG(检索增强生成)系统中,分块(Chunking) 是决定检索质量的关键步骤。分块策略主要影响两个核心指标:检索的精确度(返回的内容是否相关)和召回率(相关的内容是否被返回)。

以下是主流且实用的分块策略,按从简单到复杂的顺序排列:

一、 固定大小分块

这是最基础、最常用的策略。

  • 原理:忽略句子边界、段落结构,单纯按照固定的 Token 数(如 256、512)进行切割,通常会设置一个重叠区域(Overlap)来避免上下文断裂。

  • 优点:实现简单,计算速度快,便于向量化。

  • 缺点:容易切断句子或段落,破坏语义完整性(比如把一个完整的“如果...那么...”逻辑切断);难以适应不同文档的异构结构。

  • 适用场景:处理结构统一、语义相对独立的文本(如日志、代码片段),或作为基线对比其他策略。

二、 基于句子的分块

以自然语言边界作为分割依据。

  • 原理:使用 NLP 工具(如 spaCyNLTK)或简单的标点符号(句号、感叹号)将文本分割成句子,再将若干句子组合成一个块。

  • 变体

    • 单句块:每个块是一个句子。检索粒度最细,但可能丢失上下文。

    • 滑动窗口:将 N 个句子组成一个块,步长为 1(类似 LLM 的滑动窗口),保证相邻块之间的连贯性。

  • 优点:保持了基本的语法单元完整性。

  • 缺点:难以处理长句子(如果某句话很长,可能导致向量表征不准确),且无法捕捉段落级的主题变化。

三、 基于文档结构的分块

利用 Markdown、HTML、PDF 等格式中天然的层级结构进行分割。

  • 原理:按照标题、段落、列表项、代码块等结构进行切割。

  • 高级技巧层级元数据保留。在分块时,将父级标题(如“第三章 方法论 > 3.1 数据采集”)作为元数据附加到每一个子块中。这样在检索时,即使匹配的是正文中的一句话,系统也能知道它属于哪个大章节。

  • 优点:保留了文档的逻辑结构和上下文,检索结果通常更具可解释性。

  • 缺点:依赖文档格式的规范性;PDF 解析时结构识别容易出错。

四、 语义分块

利用模型理解文本的语义变化来决定分割点,而非依赖固定的字符数。

  • 原理

    1. 将文档拆分为句子。

    2. 计算相邻句子的嵌入向量(Embedding)。

    3. 计算句子之间的余弦相似度。

    4. 当相似度出现显著下降(表示话题转变)时,在此处切分。

  • 优点:生成的块在语义上是独立的,非常有利于处理话题多变的长文档,能显著提高检索的相关性。

  • 缺点:需要额外的模型推理成本;阈值(相似度下降多少算转折)需要根据具体语料调试。

五、 上下文增强型分块

为了解决“块太小导致上下文丢失”与“块太大导致检索噪声”的矛盾,这类策略采用父子索引上下文召回的方式。

  • 原理(典型实现如 LlamaIndex 的 HierarchicalNodeParser

    • 父块:较大的窗口(如整个段落或章节),不用于检索,仅用于提供给 LLM 作为上下文。

    • 子块:较小的粒度(如单个句子),用于向量检索。

    • 流程:检索时先找到匹配的子块,但返回给 LLM 时,自动将其关联的父块(包含更多上下文)一并提交。

  • 优点:既保证了检索的精确度(向量相似度匹配准确),又保证了生成的完整度(LLM 能看到完整的上下文)。

  • 适用场景:问答类任务中,答案往往需要结合前后文才能完整理解。

六、 特殊数据类型的分块策略

1. 代码分块
  • 策略:不能按字符切,必须依赖语法树(AST,抽象语法树)。

  • 做法:以函数、类为单位进行切分。将导入语句作为元数据保留。检索时,如果命中函数内部,应返回整个函数定义。

2. 表格分块
  • 策略:直接向量化 Markdown 表格效果较差。

  • 做法

    • 文本化:将表格转为自然语言描述(如“这张表展示了 2023 年各季度销售额,第一季度为...”)。

    • 检索增强:检索时尝试返回整张表,或者将表头(Schema)与单元格分开检索。

七、 如何选择分块策略?

在选择时,通常需要结合以下三个维度进行权衡:

  1. 文档性质

    • 如果文档是长篇小说:语义分块 + 父子分块更适合,避免截断剧情。

    • 如果文档是技术手册/法律条文:结构分块(按标题)是最佳选择,因为用户通常会问“关于第 X 条...”。

    • 如果文档是问答对(Q&A):固定大小分块容易将问题和答案切散,建议保持一对一的块。

  2. 下游任务

    • 事实性问答:倾向于小块(提高精确度,减少噪声)。

    • 摘要生成:倾向于大块(保证信息不遗漏,获取完整逻辑)。

  3. 模型上下文窗口

    • 随着现代 LLM 上下文窗口越来越大(如 1M Token),虽然可以塞进整本书,但检索质量依然重要。即使是长上下文,检索出高度相关的 Top-K 块(而非全量数据)仍能显著降低幻觉,提升响应速度。

八、实战方案

在实际工程落地中,没有绝对的“最佳”策略。一个常见的生产级基线是:

采用“父子分块” + “重叠滑动窗口” + “保留文档结构元数据”的组合方案,目的是在检索粒度上下文完整性之间找到平衡

8.1、 文字流程

整个流程可以分为索引构建检索与增强两个阶段。

阶段1:索引构建(预处理)
  1. 文档结构解析与元数据提取

    • 首先,解析原始文档(如PDF、Word、HTML),识别其结构:标题、段落、表格、列表、页眉页脚等。

    • 提取结构元数据,例如:章节编号、标题层级、所在页码、表格标题等。这些元数据会与文本内容绑定。

  2. 父子分块

    • 父块:按文档的结构边界(如整个段落、小节)进行切分,保留完整的语义单元。父块通常较大(例如512-1024 tokens),用于提供完整上下文

      父块切分规则:
      1. 优先按标题层级切分(如 H2 或 H3 级别)
      2. 如果某个章节超过 1000 tokens,再按段落切分
      3. 避免切分时打断“一是...二是...”这类并列结构
    • 子块:将父块进一步细分为更小的单元(例如256-512 tokens),用于检索。子块之间会存在重叠。

      子块切分规则:
      1.切分点:。!?… 等句末标点
      2.目标:累积句子直到接近 250 tokens
  3. 重叠滑动窗口(应用于子块切分)

    • 在将父块切分为子块时,不采用简单的硬切分,而是使用滑动窗口。

    • 例如:窗口大小256 tokens,步长128 tokens。这样相邻的两个子块会有128 tokens的重叠部分。

    • 这种设计能保证被切分到边界的关键信息(如一句话的前半段在一个子块,后半段在下一个子块)至少在一个子块中是完整的。

  4. 向量化与存储

    • 子块进行向量化(Embedding),存入向量数据库。向量中会关联父块的ID和所有结构元数据。

    • 同时,将父块的内容、结构元数据、子块ID列表存入文档存储库(如对象存储或关系型数据库)。

阶段2:检索与增强(查询时)
  1. 检索(基于子块)

    • 用户输入问题 QQ。

    • 系统将 QQ 转为向量,在向量数据库中检索最相似的 KK 个子块(通常 KK 设为较大值,如10-20)。

    • 这一步利用小粒度获得高召回率,精准定位到相关片段。

  2. 上下文扩展与重组

    • 获取检索到的子块后,系统通过子块中存储的父块ID,拉取对应的完整父块内容。

    • 去重与合并:如果多个子块属于同一个父块,只保留一个父块,避免重复。

    • 利用重叠窗口:在拼接最终上下文时,由于子块在切分时有重叠,系统可以智能地去重重叠部分,或者利用重叠来验证信息的连贯性。

    • 结构信息注入:将父块附带的元数据(如“这段内容来自第三章第二节”)以文本形式注入到Prompt中。

  3. 生成

    • 将重组后的上下文(以父块为主体,带有结构标签)与用户问题 QQ 一起发送给大语言模型,生成最终答案。


8.2、 好处

这套组合方案之所以被广泛采用,是因为它同时解决了RAG中的几个核心痛点:

1. 解决“大块丢失细节,小块丢失上下文”的矛盾
  • 单独用父块(大块):检索时容易出现“低分辨率”问题,相似度计算不够精准,容易混入噪声。

  • 单独用子块(小块):检索到的片段可能缺乏背景,导致大模型“断章取义”。

  • 组合效果检索用子块(精准命中),上下文用父块(完整理解)。这既保证了检索的精准度,又保证了生成阶段有足够的背景信息来消除歧义。

2. 避免边界截断导致的语义丢失
  • 重叠滑动窗口解决了传统固定长度切分(Chunking)的“边界效应”问题。

  • 当信息恰好位于两个子块的交界处时,如果没有重叠,检索时可能两个子块都包含一半信息,导致相似度得分都不高,从而漏掉关键信息。重叠窗口确保关键句至少在一个子块中是完整的。

3. 增强大模型对复杂文档的理解能力
  • 保留文档结构元数据相当于给大模型提供了一张“地图”。

  • 当大模型知道当前引用的内容属于“第3章的总结”或“附录”时,它能更好地判断内容的权重和定位。对于需要依据章节逻辑回答问题(如“根据第二章,作者提出了哪三个观点?”)的场景,这种结构信息至关重要。

4. 提升召回率与准确率的平衡
  • 子块检索可以设置较高的召回数量(高 KK 值),尽可能多地把相关片段捞回来。

  • 通过父块聚合,将检索结果合并为较少的几个完整文档单元,有效减少了输入给大模型的噪音,降低了大模型在长上下文中“迷失”的概率,同时控制了输入Token的长度(避免重复的相似片段)。

5. 支持更复杂的检索后处理策略
  • 这种结构支持层次化重排:先通过子块快速筛选(如ANN检索),再用父块内容进行精细重排(Reranking)。

  • 也支持上下文增强:如果一个子块被命中,系统可以自动将其相邻的子块(利用滑动窗口的连续性)或整个父块都带上,实现“按需扩展上下文”。


8.3、 总结

这套组合方案的本质是多粒度表征结构化处理的结合:

  • 父子分块:解耦了检索单元与生成单元,让“找”和“读”使用不同粒度的信息。

  • 重叠滑动窗口:在切分层面做补偿,确保信息在离散化过程中不丢失连续性。

  • 保留文档结构元数据:在语义理解层面提供方位感,让大模型像人类看文档目录一样理解内容。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐