文档切分策略
3229 字约 11 分钟
domain/aiai/rag
2026-07-24
文档切分(Chunking)是 RAG 系统中最关键但最常被忽视的预处理步骤。同样的嵌入模型、同样的向量数据库,仅换分块策略,检索召回率就能相差 9% 以上。
一句话解释
将长文档切分为语义完整、大小适中的片段(Chunk),作为检索和向量化的基本单位,分块策略直接决定 RAG 检索质量的上限。
核心问题
为什么分块策略如此重要?
- 检索粒度矛盾:块太大 → 信息被"平均化",精确率低;块太小 → 丢失上下文,召回率低
- 语义完整性:切在句子中间 vs 切在段落边界,对检索效果的差异超过 10%
- 跨块信息丢失:关键信息正好落在两个块的边界上,任何一个块都无法完整检索到
- 文档类型差异:Markdown 有天然结构,PDF 没有,代码有函数边界,表格有行列结构——一刀切是最差的策略
基础概念
Chunk:文档被切分后的片段,是检索和向量化的基本单位。
Chunk Size:每个 chunk 的 token 或字符数量。中文文档建议 300-800 字起步,之后根据任务调整。
Chunk Overlap:相邻 chunk 之间的重叠部分,避免边界信息丢失。推荐 10%-20%。
语义切分(Semantic Chunking):基于 embedding 相似度检测语义断点,在主题变化处切分。
递归字符切分(Recursive Character Text Splitter):递归按分隔符优先级切分,优先保持大结构完整。LangChain 默认策略。
Metadata:chunk 的附加信息(来源、页码、标题层级等),是检索精度的重要提升手段。
五大切分策略详解
1. Fixed-Size Chunking(固定大小分块)
算法:按预设的固定长度单位(字符数、词数或 Token 数)机械式切分,完全不考虑语义结构。
核心流程:每隔 N 个 Token 切一刀,搭配 10%-20% 的 overlap。
优点:实现极简,开发速度快;高可预测性,所有块大小统一;对任意文本通用。
缺点:上下文碎片化,常在句子中间强制切割;对语义结构不敏感,同一主题可能被切到两个块中。
适用场景:快速原型验证、RAG 系统性能基线测试、结构不统一的文本。
参数建议(中文):chunk_size 300-800 字,若嵌入模型最佳输入为 512/1024 tokens,可折算为约 350/700 中文字符起步。
2. Semantic Chunking(语义分块)
算法:基于文本语义相似性进行分段。
核心流程:
- 句子分割:将文本分解为独立句子
- 嵌入生成:对每个句子生成向量嵌入
- 相似性分析:计算相邻句子嵌入的余弦相似度,检测语义断点
- 块形成:在断点处分组形成语义连贯的块
优点:语义连贯性最好,每个块包含独立完整的想法;能检测到段落分隔符无法体现的隐含主题变化。
缺点:计算成本高(需对所有句子做嵌入);相似度阈值需要针对具体领域调优。
适用场景:学术论文、法律文件、长篇叙事、密集非结构化文本。
注意:语义分块不一定总是优于简单方法。有实验显示 Naive 分块对答案的表示得分 0.95,Semantic 为 0.88,需要根据场景评估。
3. Recursive Chunking(递归分块)
算法:使用按优先级排列的分隔符列表,自上而下递归切分。先尝试高优先级分隔符,若块仍过大,则递归应用下一级分隔符,直至满足大小限制。
分隔符优先级(中文文档建议):
- 章节/标题:
^#{1,6}\s(Markdown 标题)、^\d+(\.\d+)*\s(编号标题) - 段落:
\n\n - 换行:
\n - 空格:
- 字符级兜底
优点:在"保持语义边界"和"控制块大小"之间取得稳健平衡;对大多数文本即插即用,是可靠的默认选择。
缺点:分隔符配置不当会导致块粒度失衡;对表格、代码等极度格式化文本效果一般。
适用场景:非结构化文本、文章、博客、研究论文。通常作为第一选择。
参数建议:chunk_size 400-800 字符,chunk_overlap 10%-20%。
4. Hierarchical Chunking(分层/多粒度分块)
算法:构建多层次块结构,典型实现为父子分块(Parent-Child Chunking):
- 子块(Small Chunks):用于精确向量检索匹配(如 175 tokens)
- 父块(Parent Chunks):检索时返回包含子块及其上下文的大块(如 512 tokens),确保 LLM 获得足够上下文
层级结构:
文档 (Document)
├── 章节 (Section) → 粗粒度上下文
│ ├── 段落 (Paragraph) → 中粒度
│ │ ├── 句子 (Sentence) → 细粒度检索优点:同时兼顾检索精度(小子块)和生成上下文完整性(大父块);可利用文档自然层级。
缺点:实现复杂度高;存储开销大(需维护多层映射关系);检索后需要额外聚合步骤。
适用场景:结构化文档(技术文档、手册)、需要精确检索但又要保留上下文的应用。
5. Agentic Chunking(智能体分块)
算法:AI Agent 动态分析整个文档(结构、密度、内容),自主决定使用哪种分块策略或策略组合。
工作流程:文档分析 → 策略选择 → 执行分块 → 质量验证 → 调整。
优点:最智能,能针对不同文档区域自适应选择策略;处理异构文档效果最佳。
缺点:计算成本最高,速度最慢;需要 LLM 调用,延迟和费用显著增加;在部分高价值异构文档场景可能带来显著收益,但通常也会带来明显的调用成本/延迟上升(常见在 2-3 倍区间,需用评估指标验证 ROI)。
适用场景:高价值异构文档、非结构化文本(客服对话)、主题反复横跳的内容(技术沙龙实录)。
注意:Agentic Chunking 目前仍处于早期阶段,实际效果受 Agent 质量影响较大,需谨慎评估投入产出比。
五大策略对比总结
| 策略 | 检索精度 | 上下文完整性 | 实现复杂度 | 计算成本 | 最佳场景 |
|---|---|---|---|---|---|
| Fixed-Size | ★★☆ | ★★☆ | ★☆☆ | ★☆☆ | 快速原型、基线测试 |
| Semantic | ★★★★ | ★★★★ | ★★★ | ★★★ | 学术论文、法律文件 |
| Recursive | ★★★ | ★★★ | ★★☆ | ★★☆ | 通用文本,默认首选 |
| Hierarchical | ★★★★ | ★★★★★ | ★★★★ | ★★★ | 结构化文档、技术手册 |
| Agentic | ★★★★★ | ★★★★★ | ★★★★★ | ★★★★★ | 高价值异构文档 |
Overlap 窗口的数学直觉
为什么 Overlap 有效
分块重叠的核心作用是在相邻块之间保留部分重复文本,确保跨越块边界的关键信息至少完整出现在一个块中。
文档: [1..................................................N]
Chunk 1: [1..................512]
Chunk 2: [385.................896] ← overlap 128
Chunk 3: [769.............1280]给定步长 step = chunk_size - overlap,若一段关键信息长度为 L,只要 L ≤ chunk_size - step + overlap,该信息至少在一个完整块中出现的概率为 1。当 overlap 增加时,步长减小,边界"盲区"缩小。
Overlap 的最优比例
- 10%-20% 是最推荐的合理范围
- 超过 20%-25% 通常不推荐,索引体积和检索开销显著上升
- 超过 30% 几乎确定对性能起负作用
Overlap 的隐性成本
给定 chunk_size = S,overlap = O,文档长度 L 远大于 S 时:
- 索引膨胀率 = S / (S - O):S=512, O=128(25%),膨胀率 = 1.33,即索引比文档大 33%
- 嵌入 Token 总量 = N × S,而非文档长度 L
- 检索时重复 chunk 在向量空间中泛滥,top-k 缺乏多样性
- 重复文本挤占 LLM 上下文窗口
缓解策略:检索后使用 MMR(最大边际相关性)去重、每文档 top-k 设上限(如最多 2 个块)、按相似度阈值聚类去重。
分块粒度与检索质量的关系
| 块粒度 | Recall(召回率) | Precision(精确率) | 说明 |
|---|---|---|---|
| 大块(>1000 tokens) | ★★★★ | ★★☆ | 上下文丰富但信息密度低,嵌入被"平均化" |
| 中块(256-512 tokens) | ★★★ | ★★★ | 最佳平衡点,大多数场景推荐 |
| 小块(<128 tokens) | ★★☆ | ★★★★ | 精确但缺乏上下文,容易"只命中词不命中义" |
大块问题:多个主题混合在一个块中 → 嵌入向量是多个语义的"平均" → 对任何单一主题的相似度都不高。
小块问题:嵌入精确捕获单一语义 → 对匹配查询的相似度很高 → 但丢失了上下文关联 → 召回率下降。
过度切割:太小的块无法通过"独立阅读测试"——如果一个片段单独阅读时不完整,对 LLM 也无意义。
不同文档类型的切分策略
| 文档类型 | 推荐策略 | 关键要点 |
|---|---|---|
| Markdown | 递归分块 + 标题层级 | 按 # 标题拆分,metadata 注入面包屑路径 |
| 先转 Markdown 再分块 | 使用 Docling/MinerU 转换,OCR 处理扫描页 | |
| 代码 | 按函数/类拆分 | 使用 AST 解析器,保留函数签名 + docstring |
| 表格 | 保持原子性 | 不切割表格内部,将上下文说明与表格合并 |
| 对话记录 | 按对话轮次 | 保留多轮上下文,避免单轮对话被孤立 |
| 学术论文 | 按章节 + 语义 | 摘要独立成块,方法和结果按子章节切分 |
与 Metadata 设计的协同
Metadata 是分块策略的"另一半",两者协同才能最大化 RAG 效果。
关键 Metadata 字段:
source_document:来源文档路径breadcrumbs:章节面包屑路径(如[技术文档 > API 参考 > 认证接口])chunk_index:块在文档中的位置page_number:页码(PDF 场景)document_type:文档类型parent_chunk_id:父子分块中的父块引用
协同模式:
- 上下文注入:在块文本前添加面包屑路径,使嵌入向量包含位置信息
- 过滤增强:检索时利用 metadata 过滤(如只检索特定章节)
- 检索后扩展:利用
chunk_index检索相邻块,自动扩展上下文窗口
详细见 Metadata设计。
2024-2026 前沿创新
- Late Chunking(后期分块):先对整个文档做嵌入,再在查询时对检索到的文档进行分块。保留完整文档的上下文信息,避免嵌入时丢失跨块关系。在柏林示例中相似度从 0.708 提升到 0.825,提升约 16.5%。
- Proposition-Based Chunking(命题式分块):使用 LLM 将文本分解为原子命题,每个命题是一个独立的事实陈述。每个块的信息密度极高,消除了冗余和歧义。
- Meta-Chunking(元分块):动态组合细粒度和粗粒度文本分块,通过元策略在检索时自适应选择最优粒度。
- Multi-Vector / ColBERT 风格:为每个 Token 生成独立向量,检索时进行延迟交互精细化匹配,从根本上解决了分块粒度选择的两难问题。
实践建议
- 从递归分块开始:作为默认策略,对大多数文本效果好且成本适中
- Overlap 不要超过 20%:超过后边际收益递减,成本急剧上升
- 不同文档类型用不同策略:制度文档、FAQ、表格、代码不能一刀切
- Metadata 与分块同步设计:面包屑路径、父级标题、文档类型是必填字段
- 用指标说话:通过 Recall@k、nDCG、MRR 量化评估分块效果
- 版本管理一切:语料库快照、分块参数、嵌入模型、评估套件都需要版本控制
常见误区
- 固定长度一刀切:忽视文档结构和语义边界
- 重叠过大:导致信息冗余和检索重复,索引膨胀
- 不保留元数据:丢失 chunk 的来源和上下文信息
- 忽视特殊格式:代码、表格、公式需要特殊处理——表格不应被切碎
- 不验证切分效果:切分后不检查 chunk 质量,不跑评估指标
- 以为语义分块一定更好:实际对比中语义分块不一定优于递归分块
进阶方向
- 自适应切分(根据内容密度动态调整)
- 多粒度切分(同时维护不同大小的 chunk,按查询类型选择)
- 语义边界检测(更精准的断点判断)
- 跨文档关联切分
- 动态切分策略选择
- 切分质量评估指标(Recall@k、nDCG、MRR)
推荐资料
- LangChain Text Splitter - https://python.langchain.com/docs/how_to/#text-splitters
- LlamaIndex Node Parser - https://docs.llamaindex.ai/en/stable/module_guides/loading/node_parsers/
- Semantic Chunking - https://python.langchain.com/docs/how_to/semantic-chunker/
- Chunking Strategies for RAG - https://www.pinecone.io/learn/chunking-strategies/