标题分块
标题分块是一种严格按照文档标题层级进行切分的分块策略。它完全遵循文档的逻辑结构,不考虑块大小限制,确保每个块都是语义完整的章节或段落。
核心概念
标题分块的核心思想是:用标题作为分块边界。
- 每个块从一个标题开始,到下一个同级或更高级标题结束
- 不会主动合并小块或拆分大块
- 完全保留文档的原始结构
文档结构 → 分块结果
# 第一章 概述 [块 1 开始]
## 1.1 背景
内容A...
## 1.2 目标 [块 2 开始] (如果 split_level=2)
内容B...
# 第二章 详细说明 [块 3 开始]
## 2.1 功能介绍
内容C...
工作原理
1. 标题层级识别
标题分块首先需要识别文档中的所有标题及其层级:
Markdown 标题层级:
# 一级标题 (H1) ← Level 1
## 二级标题 (H2) ← Level 2
### 三级标题 (H3) ← Level 3
#### 四级标题 (H4) ← Level 4
##### 五级标题 (H5) ← Level 5
###### 六级标题 (H6) ← Level 6
层级结构示例:
H1: 第一章
H2: 1.1 节
H3: 1.1.1 小节
H3: 1.1.2 小节
H2: 1.2 节
H1: 第二章
H2: 2.1 节
2. 按层级切分
根据 split_level 参数决定在哪些层级切分文档:
split_level = 1 (仅 H1)
只在一级标题处切分,每个块包含完整的章。
示例文档:
# 第一章 系统概述
## 1.1 系统架构
内容 A (300 tokens)
## 1.2 核心组件
内容 B (500 tokens)
### 1.2.1 前端组件
内容 C (200 tokens)
# 第二章 安装指南
## 2.1 环境准备
内容 D (400 tokens)
切分结果:
块 1 (1000+ tokens):
# 第一章 系统概述
## 1.1 系统架构
内容 A
## 1.2 核心组件
内容 B
### 1.2.1 前端组件
内容 C
块 2 (400+ tokens):
# 第二章 安装指南
## 2.1 环境准备
内容 D
特点:
- ✅ 块数量最少
- ✅ 保留完整章节
- ⚠️ 块大小差异可能很大
split_level = 2 (H1 和 H2) (推荐)
在一级和二级标题处切分。
切分结果:
块 1 (300 tokens):
## 1.1 系统架构
内容 A
块 2 (700 tokens):
## 1.2 核心组件
内容 B
### 1.2.1 前端组件
内容 C
块 3 (400 tokens):
## 2.1 环境准备
内容 D
特点:
- ✅ 平衡块数量和块大小
- ✅ 适合大多数结构化文档
- ✅ 检索粒度适中
split_level = 3 (H1、H2 和 H3)
在一、二、三级标题处切分,粒度最细。
切分结果:
块 1 (300 tokens):
## 1.1 系统架构
内容 A
块 2 (500 tokens):
## 1.2 核心组件
内容 B
块 3 (200 tokens):
### 1.2.1 前端组件
内容 C
块 4 (400 tokens):
## 2.1 环境准备
内容 D
特点:
- ✅ 切分粒度最细
- ✅ 每个块更聚焦
- ⚠️ 可能产生过小的块
- ⚠️ 块数量多,存储和检索成本高
3. 切分规则详解
规则 1: 严格按标题边界切分
每个块的开始必须是一个标题,结束于下一个同级或更高级标题之前。
## 2.1 安装步骤 ← 块 N 开始
第一步: 下载安装包
第二步: 解压文件
第三步: 运行安装程序
## 2.2 配置说明 ← 块 N 结束, 块 N+1 开始
配置文件位于...
规则 2: 子标题跟随父标题
较低级别的标题和内容归属于最近的切分边界标题。
## 2.1 安装步骤 ← 块 N 开始 (split_level=2)
### 2.1.1 下载 ← 归属于块 N
内容...
### 2.1.2 安装 ← 仍归属于块 N
内容...
## 2.2 配置说明 ← 块 N+1 开始
规则 3: 无标题内容处理
文档开头如果有内容但没有标题,会被归入第一个标题的块,或单独成为一个块。
这是文档的前言部分,没有标题。 ← 归入块 1 或单独成块
# 第一章 概述 ← 块 1 开始
内容...
规则 4: 不控制块大小
这是标题分块与其他策略的最大区别:
- ❌ 不会因为块太大而拆分
- ❌ 不会因为块太小而合并
- ✅ 完全尊重文档的逻辑结构
## 2.1 详细的技术说明
(假设这里有 5000 tokens 的内容)
→ 这整个 2.1 节会作为一个 5000 tokens 的块,不会被拆分
4. 元数据保留
每个块会保留标题的元数据信息:
{
"chunk_id": "chunk_001",
"content": "## 2.1 安装步骤\n\n第一步: 下载安装包...",
"metadata": {
"heading": "2.1 安装步骤",
"heading_level": 2,
"parent_heading": "第二章 安装指南",
"heading_hierarchy": ["第二章 安装指南", "2.1 安装步骤"],
"page": 10,
"coordinates": [10, 50, 550, 100, 400]
}
}
配置参数
完整配置示例
{
"chunk_token_num": 256, // 参考值,不强制执行
"min_chunk_tokens": 10, // 参考值,不强制执行
"split_level": 2, // 切分的标题层级 (1-6)
"include_metadata": true, // 是否包含标题元数据
"enable_heading_in_content": false, // 是否在内容中包含标题层级
"enable_vision_enhancement": false, // 是否启用图片理解
"vision_description_format": "[图片描述]: {desc}",
"vision_batch_size": 3
}
参数详解
split_level (默认: 2)
作用: 决定在哪些标题层级处切分文档
取值: 1-6
推荐设置:
- Level 1: 适合章节明确且完整的长文档(书籍)
- Level 2: 适合大多数技术文档和用户手册 (推荐)
- Level 3: 适合结构细致的文档(详细规范)
- Level 4+: 很少使用,过于细分
如何选择:
检查文档结构:
- 主要内容在 H1 下 → split_level = 1
- 主要内容在 H2 下 → split_level = 2 (最常见)
- 主要内容在 H3 下 → split_level = 3
chunk_token_num 和 min_chunk_tokens
重要: 这两个参数在标题分块中不起作用,仅作为参考。
标题分块不会:
- ❌ 合并小于
min_chunk_tokens的块 - ❌ 拆分大于
chunk_token_num的块
这两个参数仅用于:
- 统计块大小分布
- 在 UI 中显示参考值
- 与其他策略保持接口一致
include_metadata (默认: true)
是否在返回结果中包含标题的元数据。
// include_metadata = true
{
"content": "## 2.1 安装步骤\n...",
"metadata": {
"heading": "2.1 安装步骤",
"heading_level": 2,
"parent_heading": "第二章 安装指南"
}
}
// include_metadata = false
{
"content": "## 2.1 安装步骤\n..."
}
何时启用:
- ✅ 需要在 UI 中显示标题层级
- ✅ 需要基于标题过滤搜索结果
- ✅ 需要生成文档目录
- ❌ 纯文本检索,不需要元数据
enable_heading_in_content (默认: false)
是否将标题层级路径添加到内容开头。
# 第二章 安装指南
## 2.1 环境准备
### 2.1.1 硬件要求
服务器需要满足以下硬件要求...
enable_heading_in_content = false (默认):
内容: "服务器需要满足以下硬件要求..."
enable_heading_in_content = true:
内容: "# 第二章 安装指南 > ## 2.1 环境准备 > ### 2.1.1 硬件要求 > 服务器需要满足以下硬件要求..."
何时启用:
- ✅ 文档层级深(4 层以上)
- ✅ 块需要独立理解上下文
- ✅ 多文档混合检索
- ❌ 标题已经包含在内容中
- ❌ 想减少 Token 消耗
产品使用指南
1. 在 KnowFlow 中配置
步骤 1: 选择分块策略
- 创建或编辑知识库
- 在"分块方法"中选择"标题分块(Title-based)"
- 点击"配置"按钮
步骤 2: 设置分割层级
检查文档结构:
在配置前,先查看文档的标题结构:
# 第一章 ← H1 (主章节)
## 1.1 节 ← H2 (主要内容层级) ★ 通常在这里切分
### 1.1.1 点 ← H3 (详细说明)
#### 细节 ← H4 (很少切分到这里)
设置 split_level:
- 文档主要内容在 H2 → 设置
split_level=2(推荐) - 文档主要内容在 H1 → 设置
split_level=1 - 需要细粒度切分 → 设置
split_level=3
步骤 3: 可选配置
高级选项:
☑ 包含标题元数据
☐ 在内容中包含父标题
☐ 启用图片理解
步骤 4: 上传文档并预览
- 上传 PDF 或 Markdown 文档
- 等待解析完成
- 点击"分块预览"
- 检查切分效果
2. 验证分块效果
检查清单
✓ 块边界是否合理?
- 每个块都从标题开始
- 块之间没有遗漏内容
- 没有标题被切分到两个块
✓ 块大小分布是否合理?
- 大部分块在 200-1000 tokens
- 没有特别大的块(>3000 tokens)
- 没有特别小的块(<50 tokens)
✓ 块内容是否语义完整?
- 每个块都是一个完整的主题
- 没有句子被截断
- 表格和列表保持完整
常见问题处理
问题 1: 有些块特别大(>2000 tokens)
原因: 该章节内容很长且没有子标题
解决方案:
选项 A: 增加切分层级
{
"split_level": 3 // 从 2 改为 3,在 H3 处也切分
}
选项 B: 修改文档,添加子标题
## 2.1 详细说明
(原来 2000 tokens 的内容)
↓ 改为 ↓
## 2.1 详细说明
### 2.1.1 基本概念
(700 tokens)
### 2.1.2 实现方法
(800 tokens)
### 2.1.3 注意事项
(500 tokens)
选项 C: 改用智能分块
{
"chunking_strategy": "smart" // 智能分块会自动控制大小
}
问题 2: 有很多小块(<100 tokens)
原因: 文档标题层级过细,每个小节内容较少
解决方案:
选项 A: 减少切分层级
{
"split_level": 1 // 从 2 改为 1,减少切分粒度
}
选项 B: 使用父子分块
{
"chunking_strategy": "parent_child", // 自动处理小块
"parent_config": {
"parent_split_level": 2
}
}
问题 3: 有的块没有标题
原因: 文档开头有内容但没有标题
解决方案:
在文档开头添加标题:
原文档:
这是前言部分...
↓ 改为 ↓
# 前言
这是前言部分...
或者接受这个块,它会被单独处理。
3. 最佳实践
推荐配置模板
技术文档/用户手册(推荐):
{
"split_level": 2,
"include_metadata": true,
"enable_heading_in_content": false
}
书籍/长文档:
{
"split_level": 1,
"include_metadata": true,
"enable_heading_in_content": true
}
详细规范/API 文档:
{
"split_level": 3,
"include_metadata": true,
"enable_heading_in_content": false
}
多文档混合检索:
{
"split_level": 2,
"include_metadata": true,
"enable_heading_in_content": true // 帮助区分不同文档
}
文档结构建议
为了更好地使用标题分块,建议文档遵循以下结构:
✓ 良好的标题结构:
# 第一章 系统概述 (H1: 主章节)
## 1.1 系统架构 (H2: 主要主题) ← 推荐切分层级
### 1.1.1 前端架构 (H3: 详细说明)
### 1.1.2 后端架构 (H3: 详细说明)
## 1.2 核心特性 (H2: 主要主题)
### 1.2.1 功能特性 (H3: 详细说明)
✗ 不良的标题结构:
# 标题 1
内容很少...
# 标题 2
内容很少...
# 标题 3
内容非常多,没有子标题...
改进建议:
# 标题 1
## 1.1 详细说明
合并后的内容...
# 标题 2
## 2.1 详细说明
合并后的内容...
# 标题 3
## 3.1 第一部分
内容...
## 3.2 第二部分
内容...
使用场景
适合的场景
✅ 结构化技术文档
- 有清晰的章节层级
- 每个章节内容相对独立
- 示例: 产品手册、API 文档、技术规范
✅ 书籍和长文档
- 明确的章节划分
- 用户需要按章节浏览和检索
- 示例: 教材、电子书、培训资料
✅ 标准和规范文档
- 条款和章节编号明确
- 需要精确引用某个章节
- 示例: ISO 标准、行业规范、政策文件
✅ 用户需要结构化导航
- 知识库需要提供目录导航
- 用户习惯按章节查找信息
- 示例: 在线文档、帮助中心
不适合的场景
❌ 扁平结构或无标题文档
- 没有标题或标题层级不清晰
- 建议使用智能分块或正则分块
❌ 标题层级不均衡
- 有的章节很长,有的章节很短
- 会产生大小差异极大的块
- 建议使用智能分块或父子分块
❌ 需要严格控制块大小
- 需要每个块大小相近
- 建议使用智能分块
❌ 实时生成内容
- 内容没有固定的标题结构
- 建议使用正则分块
与其他策略的对比
标题分块 vs 智能分块
| 特性 | 标题分块 | 智能分块 |
|---|---|---|
| 块边界 | 严格按标题 | 灵活,保持语义完整 |
| 块大小 | 不可控,可能差异大 | 可控,相对均匀 |
| 处理速度 | 快 | 中等 |
| 适用文档 | 结构化强 | 通用 |
| 保留结构 | 完美 | 较好 |
选择建议:
- 文档有清晰标题且层级均衡 → 标题分块
- 文档标题不规范或无标题 → 智能分块
标题分块 vs 父子分块
| 特性 | 标题分块 | 父子分块 |
|---|---|---|
| 存储空间 | 小 | 大(约 2 倍) |
| 检索精度 | 较低(块可能很大) | 高(通过子块) |
| 上下文完整性 | 高 | 高(通过父块) |
| 处理速度 | 快 | 慢 |
| 配置复杂度 | 简单 | 较复杂 |
选择建议:
- 简单场景,重视结构 → 标题分块
- 复杂检索需求,兼顾精度和上下文 → 父子分块
标题分块 vs 正则分块
| 特性 | 标题分块 | 正则分块 |
|---|---|---|
| 灵活性 | 低(必须有标题) | 高(任意模式) |
| 语义完整性 | 高 | 低(取决于模式) |
| 配置难度 | 简单 | 需要正则表达式知识 |
| 处理速度 | 快 | 最快 |
选择建议:
- 标准 Markdown/HTML 文档 → 标题分块
- 特殊格式或纯文本 → 正则分块
技术原理(简要说明)
算法流程
1. PDF 解析
↓
2. 提取 Markdown 格式内容
↓
3. 解析标题结构
├─ 识别所有标题
├─ 确定标题层级(H1-H6)
└─ 构建标题树
↓
4. 按 split_level 切分
├─ 遍历标题树
├─ 在指定层级创建块边界
└─ 将内容归入对应块
↓
5. 生成块元数据
├─ 标题文本
├─ 标题层级
├─ 父标题路径
└─ 页码和坐标
↓
6. 存储到数据库
└─ 向量化块内容
标题识别方法
KnowFlow 支持多种标题识别方式:
1. Markdown 标题:
# H1 标题
## H2 标题
### H3 标题
2. HTML 标题:
<h1>H1 标题</h1>
<h2>H2 标题</h2>
<h3>H3 标题</h3>
3. PDF 标题(通过解析器识别):
- 字体大小
- 字体粗细
- 编号模式(1. 1.1 1.1.1)
常见问题
1. chunk_token_num 参数不起作用?
答: 这是正常的。标题分块不控制块大小,该参数仅作参考。
2. 如何控制块的大小?
答: 标题分块不支持直接控制块大小。可以:
- 调整
split_level改变切分粒度 - 修改文档标题结构
- 改用智能分块或父子分块
3. 有的块特别大,会影响检索吗?
答: 可能会。解决方案:
- 增加
split_level使切分更细 - 使用父子分块(子块检索,返回父块)
- 增加检索返回的块数量(Top-K)
4. 文档开头没有标题的内容会怎样?
答: 这些内容会:
- 单独成为一个块,或
- 归入第一个标题的块
建议在文档开头添加标题。
5. 可以混合使用不同层级切分吗?
答: 不可以。split_level 是全局参数。但可以:
- 为不同知识库设置不同的
split_level - 使用父子分块,它的父块和子块使用不同层级
6. 标题编号会影响切分吗?
答: 不会。以下标题被视为相同层级:
## 1.1 标题 A ← H2
## 标题 B ← H2
## (三) 标题 C ← H2