跳到主要内容

父子分块

父子分块是一种两级层次结构的分块策略,通过创建小的子块和大的父块,实现检索精度和上下文完整性的完美平衡。

核心概念

父子分块将文档分成两个层级:

  • 子块(Child Chunks): 较小的文本片段,用于精确的语义检索
  • 父块(Parent Chunks): 较大的文本片段,包含多个子块,提供完整上下文
文档
├─ 父块 1 (1024 tokens)
│ ├─ 子块 1.1 (256 tokens) ← 用于检索
│ ├─ 子块 1.2 (256 tokens) ← 用于检索
│ ├─ 子块 1.3 (256 tokens) ← 用于检索
│ └─ 子块 1.4 (256 tokens) ← 用于检索
├─ 父块 2 (1024 tokens)
│ ├─ 子块 2.1 (256 tokens)
│ └─ 子块 2.2 (256 tokens)
...

工作原理

1. 父块如何分割?

父块是通过标题层级Token 数量两个维度进行切分的:

切分规则:

  1. 优先按标题切分

    • 根据 parent_split_level 参数确定切分层级
    • 例如: parent_split_level=2 表示在 H1 和 H2 标题处切分
    • 保证每个父块在语义上是完整的章节或段落
  2. 控制父块大小

    • 目标大小由 parent_chunk_size 控制(默认 1024 tokens)
    • 如果单个章节超过目标大小,会进一步切分
    • 如果章节过小,会合并到下一个章节
  3. 添加重叠内容

    • 相邻父块之间有 parent_chunk_overlap tokens 的重叠(默认 100 tokens)
    • 重叠区域确保跨块信息不会丢失

示例:

# 第一章 系统概述                ← 父块边界(Level 1)
## 1.1 系统架构 ← 父块边界(Level 2)
系统采用三层架构...
(约 500 tokens)

## 1.2 核心组件 ← 父块边界(Level 2)
系统包含以下核心组件...
(约 600 tokens)

# 第二章 安装指南 ← 父块边界(Level 1)
...

如果 parent_split_level=2, parent_chunk_size=1024:

  • 父块 1: "第一章 系统概述" 整章(1100 tokens,略超但保持完整)
  • 父块 2: "第二章 安装指南" 开始...

2. 子块如何获取?

子块是通过**智能分块(Smart Chunking)**方法从父块中切分出来的:

生成过程:

  1. 从父块提取内容

    • 父块已经确定边界,内容固定
  2. 应用智能分块算法

    • 使用 Markdown AST 解析父块内容
    • 识别段落、列表、表格、代码块等语义单元
    • 尽量保持语义单元的完整性
  3. 控制子块大小

    • 目标大小: chunk_token_num (默认 256 tokens)
    • 最小大小: min_chunk_tokens (默认 10 tokens)
    • 自动合并过小的片段,拆分过大的片段
  4. 建立父子关联

    • 每个子块记录其所属的父块 ID
    • 数据库中存储关联关系

示例:

父块内容(约 800 tokens):

## 1.1 系统架构

系统采用三层架构设计:

1. **展示层**: 负责用户界面展示
2. **业务层**: 处理业务逻辑
3. **数据层**: 数据持久化

### 展示层详解
展示层采用 React 框架...
(约 200 tokens)

### 业务层详解
业务层基于 Spring Boot...
(约 250 tokens)

### 数据层详解
数据层使用 PostgreSQL...
(约 180 tokens)

切分后的子块:

  • 子块 1 (256 tokens): "## 1.1 系统架构\n\n系统采用三层架构设计...\n\n### 展示层详解\n展示层采用..."
  • 子块 2 (250 tokens): "### 业务层详解\n业务层基于 Spring Boot..."
  • 子块 3 (180 tokens): "### 数据层详解\n数据层使用 PostgreSQL..."

3. 父子关系存储

{
"parent_chunk": {
"id": "parent_001",
"content": "## 1.1 系统架构\n\n系统采用三层架构设计...(完整内容)",
"tokens": 800,
"page": 5,
"coordinates": [5, 50, 550, 100, 700]
},
"child_chunks": [
{
"id": "child_001",
"parent_id": "parent_001",
"content": "## 1.1 系统架构\n\n系统采用三层架构设计...",
"tokens": 256,
"coordinates": [5, 50, 550, 100, 300]
},
{
"id": "child_002",
"parent_id": "parent_001",
"content": "### 业务层详解\n业务层基于 Spring Boot...",
"tokens": 250,
"coordinates": [5, 50, 550, 300, 500]
}
]
}

检索模式

父子分块支持三种检索模式,可根据场景灵活选择:

模式 1: 仅返回父块 (retrieval_mode="parent")

工作流程:

用户查询 → 向量检索子块 → 返回子块对应的父块

特点:

  • ✅ 提供最完整的上下文
  • ✅ LLM 能看到更多相关信息
  • ⚠️ 可能包含部分无关内容
  • ⚠️ 消耗更多 Token

适用场景:

  • 需要完整背景理解的问题
  • 多步推理问题
  • 需要跨段落信息的查询

示例:

用户问题: "系统的业务层使用什么技术?"

检索到子块: "### 业务层详解\n业务层基于 Spring Boot..."

返回父块: "## 1.1 系统架构\n\n系统采用三层架构...(包含展示层、业务层、数据层的完整描述)"

模式 2: 仅返回子块 (retrieval_mode="child")

工作流程:

用户查询 → 向量检索子块 → 直接返回子块

特点:

  • ✅ 精确匹配用户查询
  • ✅ Token 消耗少
  • ⚠️ 可能缺少必要的上下文
  • ⚠️ 不适合需要背景理解的问题

适用场景:

  • 事实性查询(定义、数据、步骤)
  • 单一概念解释
  • Token 预算有限

示例:

用户问题: "业务层使用什么框架?"

检索到子块: "### 业务层详解\n业务层基于 Spring Boot..."

直接返回子块: "### 业务层详解\n业务层基于 Spring Boot...(仅该段落)"

模式 3: 同时返回父块和子块 (retrieval_mode="both")

工作流程:

用户查询 → 向量检索子块 → 返回子块 + 对应父块

特点:

  • ✅ 兼顾精度和上下文
  • ✅ LLM 可以根据需要选择信息
  • ⚠️ Token 消耗最多
  • ⚠️ 可能有冗余信息

适用场景:

  • 复杂问题需要多层次信息
  • 不确定需要多少上下文
  • Token 预算充足

示例:

用户问题: "业务层在整个系统架构中的作用?"

检索到子块: "### 业务层详解\n业务层基于 Spring Boot..."

返回:
1. 子块(精确匹配): "### 业务层详解\n业务层基于 Spring Boot..."
2. 父块(完整上下文): "## 1.1 系统架构\n\n系统采用三层架构...(三层架构完整介绍)"

配置参数

完整配置示例

{
"chunk_token_num": 256, // 子块目标大小
"min_chunk_tokens": 10, // 最小子块大小
"parent_config": {
"parent_chunk_size": 1024, // 父块目标大小
"parent_chunk_overlap": 100, // 父块之间的重叠
"retrieval_mode": "parent", // 检索模式: parent | child | both
"parent_split_level": 2 // 父块切分的标题层级
},
"enable_heading_in_content": false, // 是否在子块中包含标题层级
"enable_vision_enhancement": false, // 是否启用图片理解
"vision_description_format": "[图片描述]: {desc}",
"vision_batch_size": 3
}

参数详解

子块配置

chunk_token_num (默认: 256)

  • 子块的目标大小
  • 推荐范围: 128-512 tokens
  • 较小值(128-256): 检索更精确,但上下文少
  • 较大值(256-512): 上下文更多,但检索精度降低

min_chunk_tokens (默认: 10)

  • 最小子块大小
  • 小于此值的块会被合并或丢弃
  • 避免产生无意义的碎片

父块配置

parent_chunk_size (默认: 1024)

  • 父块的目标大小
  • 推荐范围: 512-2048 tokens
  • 通常设置为子块的 4-8 倍
  • 过小: 上下文不足
  • 过大: Token 消耗大,可能超出 LLM 限制

parent_chunk_overlap (默认: 100)

  • 相邻父块之间的重叠区域
  • 推荐: 父块大小的 5-10%
  • 作用: 避免重要信息被切分到两个父块边界

parent_split_level (默认: 2)

  • 父块按哪些标题层级切分
  • Level 1: 仅 H1
  • Level 2: H1 和 H2 (推荐)
  • Level 3: H1、H2、H3

retrieval_mode (默认: "parent")

  • parent: 返回父块
  • child: 返回子块
  • both: 返回父块和子块

产品使用指南

1. 在 KnowFlow 中配置

步骤 1: 创建知识库

  1. 登录 KnowFlow 系统
  2. 点击"创建知识库"
  3. 填写知识库名称和描述

步骤 2: 选择分块策略

  1. 在知识库设置中,找到"分块方法"
  2. 选择"父子分块(Parent-Child)"
  3. 点击"高级配置"

步骤 3: 配置参数

![父子分块配置界面示意]

基础配置:

子块大小: 256 tokens
最小块大小: 10 tokens

父块配置:

父块大小: 1024 tokens
父块重叠: 100 tokens
分割层级: Level 2 (H1 和 H2)
检索模式: 返回父块

高级选项:

□ 包含父标题
□ 启用图片理解

步骤 4: 上传文档

  1. 点击"上传文档"
  2. 选择 PDF、DOCX 或 Markdown 文件
  3. 等待解析完成

步骤 5: 预览分块效果

  1. 在文档列表中点击文档名称
  2. 查看"分块预览"
  3. 检查父块和子块的大小和内容
  4. 如不满意,调整参数后重新解析

2. 调试和优化

检查分块质量

父块检查:

  • 每个父块是否语义完整?
  • 父块大小是否合理(800-1500 tokens)?
  • 父块之间的重叠是否有效?

子块检查:

  • 子块是否保持了段落/列表的完整性?
  • 子块大小是否均匀(200-300 tokens)?
  • 是否有过小的子块(<50 tokens)?

常见问题和调整

问题 1: 父块过大(>2000 tokens)

原因: 单个章节内容太长,且没有子标题

解决方案:

{
"parent_split_level": 3, // 增加切分层级
"parent_chunk_size": 1536 // 适当增加父块大小上限
}

问题 2: 父块过小(<500 tokens)

原因: 文档标题层级过细

解决方案:

{
"parent_split_level": 1, // 减少切分层级,仅在 H1 切分
"parent_chunk_size": 2048 // 增加父块大小
}

问题 3: 子块不均匀

原因: 文档中有大表格或代码块

解决方案:

{
"chunk_token_num": 512, // 增加子块大小
"min_chunk_tokens": 50 // 提高最小块大小
}

问题 4: 检索返回结果不精确

尝试:

{
"retrieval_mode": "child" // 改为返回子块
}

问题 5: 检索返回结果上下文不足

尝试:

{
"retrieval_mode": "both", // 同时返回父块和子块
"parent_chunk_size": 1536 // 增加父块大小
}

3. 最佳实践

推荐配置模板

通用文档(推荐):

{
"chunk_token_num": 256,
"min_chunk_tokens": 10,
"parent_config": {
"parent_chunk_size": 1024,
"parent_chunk_overlap": 100,
"retrieval_mode": "parent",
"parent_split_level": 2
}
}

长文档/书籍:

{
"chunk_token_num": 256,
"min_chunk_tokens": 20,
"parent_config": {
"parent_chunk_size": 2048,
"parent_chunk_overlap": 200,
"retrieval_mode": "parent",
"parent_split_level": 1
}
}

技术文档(需要精确检索):

{
"chunk_token_num": 128,
"min_chunk_tokens": 10,
"parent_config": {
"parent_chunk_size": 768,
"parent_chunk_overlap": 50,
"retrieval_mode": "child",
"parent_split_level": 3
}
}

法律文档(需要完整上下文):

{
"chunk_token_num": 256,
"min_chunk_tokens": 20,
"parent_config": {
"parent_chunk_size": 1536,
"parent_chunk_overlap": 150,
"retrieval_mode": "both",
"parent_split_level": 2
},
"enable_heading_in_content": true
}

使用场景

适合的场景

技术文档和用户手册

  • 需要精确定位具体步骤
  • 同时需要了解整体流程
  • 示例: API 文档、安装指南

学术论文和研究报告

  • 需要精确引用某个论点
  • 需要理解论点的完整论证过程
  • 示例: 学术文献、专利文档

法律文档和合同

  • 需要精确定位某个条款
  • 需要理解条款的完整语境
  • 示例: 法律法规、合同协议

多层级结构化内容

  • 文档有清晰的章节层级
  • 每个章节相对独立但又相互关联
  • 示例: 教材、操作手册

不适合的场景

扁平结构文档

  • 没有标题层级
  • 使用智能分块或正则分块更合适

简短文档(<5 页)

  • 文档本身已经很短
  • 不需要复杂的层级结构

实时性要求高

  • 父子分块处理速度较慢
  • 建议使用智能分块或标题分块

存储空间有限

  • 父子分块占用约 1.5-2 倍存储空间
  • 建议使用其他分块策略

技术原理(简要说明)

算法流程

1. PDF 解析

2. 提取 Markdown 内容

3. 父块生成
├─ 按标题层级切分
├─ 控制块大小
└─ 添加重叠区域

4. 子块生成
├─ 对每个父块应用智能分块
├─ 维护父子关联
└─ 向量化子块

5. 存储到数据库
├─ 父块表
├─ 子块表
└─ 关联关系表

检索流程

用户查询

向量化查询文本

在子块向量库中检索 (相似度匹配)

获取 Top-K 子块

根据 retrieval_mode 决定:
├─ parent: 通过关联表获取父块
├─ child: 直接使用子块
└─ both: 获取父块 + 子块

返回结果给 LLM

存储开销

假设文档大小为 X tokens:

  • 智能分块: ~X tokens 存储
  • 父子分块: ~1.8X tokens 存储
    • 父块: X tokens
    • 子块: X tokens
    • 重叠部分: ~0.1X tokens
    • 关联信息: ~0.05X tokens

常见问题

1. 父块和子块的大小比例如何设置?

推荐比例: 1:4 到 1:8

parent_chunk_size = chunk_token_num × 4 ~ 8

示例:

  • 子块 256, 父块 1024 (1:4)
  • 子块 256, 父块 2048 (1:8)

2. 什么时候使用哪种检索模式?

检索模式使用场景Token 消耗
parent需要完整上下文、多步推理
child事实查询、定义解释
both复杂问题、不确定上下文需求最高

3. 父子分块比智能分块慢多少?

大约慢 1.5-2 倍:

  • 需要两次分块(父块 + 子块)
  • 需要建立和存储关联关系
  • 向量化的数据量更大

4. 如何减少存储空间占用?

  1. 减小 parent_chunk_overlap
  2. 使用 retrieval_mode="child" (可以不存储父块向量)
  3. 增大 min_chunk_tokens 过滤小块

5. 父子分块适合所有文档吗?

不适合:

  • 扁平结构文档(无标题层级)
  • 非常短的文档(<10 页)
  • 实时性要求高的场景

相关资源