RAG 系统中的 Chunking 最佳实践:从固定切块到结构化、上下文化与评估驱动

Chunking 是 RAG 数据摄取阶段的核心设计。它决定了:

  • 检索系统能找到什么;
  • Embedding 表达的是一个完整概念还是混杂主题;
  • 引用能否精确定位;
  • Reranker 和 LLM 需要处理多少上下文;
  • 系统最终的准确率、延迟和成本。

目前不存在适用于所有 RAG 系统的统一最佳 Chunk Size,也不存在一种在所有数据集上都占优的 Chunking 算法。更稳健的工程结论是:

以文档结构和语义完整性为主要切分依据,以 Token 长度作为约束,再通过真实检索与问答数据集确定最终方案。

Google Cloud 明确指出,最优 Chunking 策略没有标准答案,取决于数据和应用;2026 年的一项系统性研究也发现,Chunking 效果明显依赖检索任务、数据集和 Embedding 方法,复杂的 LLM 驱动方案不一定优于简单的结构化切分。(Google Cloud Documentation)


一、Chunking 真正解决的是什么问题

一个理想的 Chunk 应同时满足三个目标:

语义完整:
包含一个能够独立理解的事实、概念或规则

检索聚焦:
不要混入大量与查询无关的主题

上下文充分:
保留理解该事实所需的标题、限定条件和前后关系

但这些目标互相存在张力。

Chunk 太小

可能导致:

  • 主语和结论被拆开;
  • 规则和例外条件被拆开;
  • 表格数据失去表头;
  • 代词失去指代对象;
  • 检索到了局部句子,却不足以回答问题。

Chunk 太大

可能导致:

  • 一个向量同时表达多个主题;
  • 相关信息被大量无关内容稀释;
  • Rerank 和生成成本上升;
  • 引用范围过宽;
  • Embedding 丢失局部细节。

Google 的当前文档将这种权衡概括为:较小 Chunk 通常能得到更精确的向量表示,而较大 Chunk 能保留更多上下文,但也更容易遗漏局部细节或产生过于宽泛的表示。(Google Cloud Documentation)

因此,Chunking 的目标不是让所有块长度完全一致,而是:

把语义单元切成适合作为检索对象的大小。


二、当前较稳健的默认策略

对于大多数企业文档,推荐的基线流程是:

原始文件
版面和结构解析
识别标题、章节、段落、列表、表格、代码块
按自然结构边界初步切分
超长块按段落、句子或 Token 递归拆分
补充标题路径、页码、版本、ACL 等元数据
Embedding 和索引

优先级可以概括为:

文档结构边界
    >
段落与句子边界
    >
固定 Token 边界
    >
任意字符边界

Google 的布局感知 Chunking 会确保一个 Chunk 内的内容来自同一个布局实体,例如标题、子标题或列表,以提高语义一致性并减少检索噪声;Microsoft 也建议根据标题、段落、表格和页面布局等结构生成 Chunk,而不是仅按固定长度切分。(Google Cloud Documentation)


三、固定长度 Chunking 仍然有价值

固定长度 Chunking 并没有过时。

它的优点是:

  • 简单;
  • 速度快;
  • 结果可复现;
  • 容易控制索引体积;
  • 容易作为实验基线。

LangChain v1 当前仍然提供字符、Token 和递归文本 Splitter。其通用递归 Splitter 会按一组分隔符逐级拆分文本,尽可能先保留段落和句子,再满足长度限制。(Docs by LangChain)

固定窗口适合:

日志
聊天记录
连续转写文本
结构很弱的纯文本
快速原型
建立可比较的基线

它不太适合:

复杂 PDF
合同和法规
表格
代码
带多级标题的技术文档
多栏排版文档

Microsoft 的 Document Intelligence 文档也指出,固定大小切分对缺少明确语义结构的数据较有效,但不适合作为需要精确上下文和语义理解的文档的默认方案。(Microsoft Learn)


四、不同文档类型应该采用不同策略

1. Markdown、HTML、Wiki 和技术文档

优先按以下结构切分:

H1
└── H2
    └── H3
        ├── 段落
        ├── 列表
        └── 代码块

建议:

  • 不轻易跨越高层级标题;
  • 小段落可在同一章节内合并;
  • 超长章节再递归拆分;
  • 将完整标题路径附加给每个 Chunk;
  • 不要截断代码块、列表或引用块。

LangChain v1 提供专门的 HTML、JSON 和代码 Splitter,反映了一个重要原则:不同数据格式应使用理解其结构的 Splitter,而不是全部转换成纯文本后统一切割。(Docs by LangChain)

一个 Chunk 的索引文本可以是:

文档:退款管理手册
章节:订单处理 > 退款条件 > 超过 30 天的订单

超过 30 天的订单只有在……

标题路径可以补充正文局部片段中缺失的语境。


2. PDF、办公文档和扫描件

复杂文档的第一步通常不是 Chunking,而是正确解析版面

需要恢复:

  • 阅读顺序;
  • 标题层级;
  • 段落;
  • 页码;
  • 列表;
  • 表格;
  • 图片和说明;
  • 多栏布局;
  • 脚注和页眉页脚。

直接把 PDF 抽成一长串文本再按 500 字符切割,可能造成:

左右栏内容交叉
表头和数据分离
章节标题丢失
页眉页脚反复进入索引

Google 当前的布局解析与布局感知 Chunking,以及 Microsoft 的文档布局方案,都把恢复文档结构作为高质量 RAG 摄取的重要步骤。(Google Cloud Documentation)

页码应主要作为:

引用定位
来源展示
审计元数据

而不是默认的语义切分边界,因为一个句子、表格或章节可能跨页。


3. 合同、法规和制度文件

优先按正式逻辑结构切分:

定义
附件

关键原则:

  • 主规则和例外条件不要分离;
  • 子项必须保留所属条款标题;
  • 条款编号应进入 metadata;
  • 定义条款与引用定义的条款应能关联;
  • 超长条款可按子款拆分,但要重复必要父级语境。

例如不应把下面两句拆成彼此无关的 Chunk:

员工可以申请远程办公。
但处理机密数据的岗位除外。

否则检索第一句后,系统可能产生错误答案。


4. 表格

表格中的单个值通常不能独立理解。

700

没有检索价值。

更适合索引为:

表格:高度人才年薪积分
年龄区间:35~39 岁
年薪:700 万日元
积分:25 分

实践中可以:

  • 小表格整体保存;
  • 大表格按逻辑行组切分;
  • 每个子块重复表名、列名和单位;
  • 保留原始 Markdown、HTML 或结构化 JSON;
  • 可额外生成文字描述,但不应完全替代原始数据。

5. 代码

代码应按语法结构而不是任意 Token 切分:

模块
函数
方法
接口
配置块

一个代码 Chunk 通常应附带:

repository
file_path
language
class_name
function_name
signature
docstring
imports

即使函数过长需要拆分,也应该保留函数名、所属类和文件路径。


五、Chunk Size 应该设置多少

没有通用最佳值,但可以设置实验起点。

短事实、FAQ、定义:
约 200~400 tokens

一般企业文档:
约 400~800 tokens

长规则、分析型内容:
约 800~1,200 tokens

这些数字不是行业标准,只是用于建立候选实验。

一个有代表性的产品默认值是 OpenAI Vector Store 当前的自动 Chunking:

最大 Chunk:800 tokens
Overlap:400 tokens

OpenAI 同时允许使用静态策略自行设置 Chunk Size 和 Overlap。这个默认值只能理解为其托管 File Search 的产品默认配置,而不能证明 800/400 对所有 RAG 系统都最优。(OpenAI Developers)

确定 Chunk Size 时应考虑:

  • 用户问题通常需要多大范围的证据;
  • 文档中一个完整语义单元有多长;
  • Embedding 模型的输入限制和长文本表现;
  • 是否使用 Reranker;
  • 最终上下文预算;
  • 索引数量、延迟和成本;
  • 是否存在大量跨段落问题。

六、Overlap 应谨慎使用

Overlap 用来避免重要信息恰好跨越切分边界。

但机械增加大量重叠会产生:

  • 重复向量;
  • 索引膨胀;
  • 多个高度相似结果;
  • LLM 上下文重复;
  • Reranker 成本上升;
  • 引用重复。

比较务实的起点是:

固定窗口:
约 10%~20% overlap

结构化 Chunk:
通常不需要统一 overlap

特殊边界:
复制上一句、标题、条款编号或必要定义

注意,OpenAI 托管 File Search 当前自动策略采用 50% 重叠,但这属于具体托管产品的默认行为;自建系统不应直接把它当成通用行业规范。(OpenAI Developers)

更干净的方案通常是:

补充结构化上下文,而不是大量复制相邻正文。


七、Parent–Child 和多粒度检索

检索单位与最终提供给 LLM 的上下文单位不一定相同。

可以建立两级结构:

Parent:
完整章节、完整条款或较大语义单元

Child:
用于 Embedding 和精确检索的小块

查询过程:

检索 Child
定位命中的细粒度内容
根据需要扩展 Parent 或相邻 Chunk
Rerank
发送给 LLM

这种方案兼顾:

  • 小块的检索精度;
  • 大块的上下文完整性;
  • 精确引用;
  • 多段证据组合。

但不能每次都无条件返回整个父文档。应该根据:

  • Parent 长度;
  • 问题类型;
  • 命中位置;
  • 是否需要多段证据;

动态扩展上下文。


八、Contextual Retrieval:给 Chunk 补充文档级语境

Anthropic 提出的 Contextual Retrieval,会在索引前为每个 Chunk 生成一段简短的上下文说明,然后将:

上下文说明 + 原始 Chunk

用于 Embedding 和 BM25 索引。

例如,原始 Chunk 是:

该产品的收入同比增长 3%。

补充后可能变成:

该段来自某公司 2023 年第二季度财报,
讨论该季度产品收入变化。

该产品的收入同比增长 3%。

这样可以降低短 Chunk 脱离全文后产生歧义的风险。Anthropic 在其内部实验中报告,Contextual Embeddings 与 Contextual BM25 组合降低了检索失败率,配合 Reranking 后改善更明显;但这些数字来自厂商自己的数据集和配置,不能直接推断到所有项目。(Anthropic)

其代价包括:

  • 摄取阶段增加 LLM 调用;
  • 索引文本增长;
  • 重建成本提高;
  • 自动生成的上下文可能出错;
  • 评估和调试复杂度上升。

因此更适合:

Chunk 脱离全文后经常产生歧义
文档中大量使用代词和局部引用
检索数据集证明普通结构切分不足
能够接受更高摄取成本

而不应默认应用于所有文档。


九、Late Chunking:先保留全文语境,再产生 Chunk 向量

传统方式是:

先切块
→ 每个 Chunk 单独 Embedding

Late Chunking 则是:

先让长上下文 Embedding 模型处理更长文本
→ 再从模型输出中聚合各 Chunk 表示

其目标是让较小 Chunk 的向量仍然保留全文上下文。原始论文报告该方法可改善部分检索任务,并且不要求为每个 Chunk 额外生成文本说明。(arXiv)

但它也有实际限制:

  • 需要兼容的长上下文 Embedding 模型;
  • 实现和推理流程更复杂;
  • 很长的文档仍需分段;
  • 不同检索任务上的收益并不一致。

2026 年一项系统性比较发现,Contextualized Chunking 对标准跨语料检索可能有帮助,但在文档内检索中可能退化;简单的段落或固定长度结构化方案在部分任务上反而更好。(arXiv)

因此,Late Chunking 应被视为高级候选方案,而不是新一代默认标准。


十、Semantic 和 LLM-guided Chunking

Semantic Chunking 会根据句子向量变化或主题转换来寻找边界;LLM-guided Chunking 则让模型判断哪些内容应该保持在一起。

潜在优点:

  • 能发现没有显式标题的主题边界;
  • 对长篇自由文本可能更自然;
  • 有机会减少语义被机械截断的问题。

潜在缺点:

  • 摄取成本更高;
  • 结果可能不稳定;
  • 对模型和阈值敏感;
  • 难以复现;
  • 不一定优于段落和结构切分。

一项系统性研究的一个重要结论是:复杂方法并非普遍占优。对于标准跨文档检索,简单的结构化方法在多组测试中具有很强竞争力,而不同任务可能偏好完全不同的方案。(arXiv)

因此推荐顺序是:

结构感知切分
递归句子 / Token 切分
Parent–Child 或上下文扩展
Contextual Retrieval / Late Chunking
Semantic 或 LLM-guided Chunking

每一步都应由评估结果证明其必要性。


十一、每个 Chunk 应保存哪些数据

企业级 Chunk 不应该只有:

{
  "text": "...",
  "vector": [...]
}

建议至少保存:

{
  "chunk_id": "doc-123-v4-c08",
  "document_id": "doc-123",
  "document_version": 4,
  "parent_id": "section-12",
  "content": "...",
  "title": "育儿休业制度",
  "section_path": [
    "人事制度",
    "休假制度",
    "育儿休业"
  ],
  "page_start": 8,
  "page_end": 9,
  "chunk_index": 8,
  "token_count": 542,
  "source_uri": "...",
  "tenant_id": "...",
  "allowed_roles": ["employee"],
  "content_hash": "...",
  "effective_from": "2026-04-01"
}

Microsoft 的 Chunk Enrichment 指南也建议使用标题、摘要、关键词、实体和其他 metadata 扩充检索记录,以支持过滤、搜索和结果解释。(Microsoft Learn)

重要字段通常包括:

文档和版本
父子关系
章节路径
页码
顺序
ACL
租户
生效时间
内容哈希
解析器版本
Chunking 策略版本
Embedding 模型版本

这样才能支持:

  • 精确引用;
  • 权限过滤;
  • 重新索引;
  • 文档更新;
  • A/B 测试;
  • 问题追踪。

十二、Chunking 必须通过评估确定

最佳实践不是选择一个听起来高级的算法,而是建立可重复实验。

至少比较:

A:固定 400 tokens
B:固定 800 tokens + overlap
C:结构感知切分
D:结构切分 + Parent–Child
E:Contextual Retrieval
F:Late 或 Semantic Chunking

检索指标

Recall@K
Precision@K
MRR
nDCG@K
Hit Rate

最终问答指标

Answer Correctness
Groundedness
Citation Correctness
Completeness
拒答准确率

工程指标

Chunk 数量
索引体积
摄取成本
检索延迟
Rerank 延迟
LLM Context Token
每个成功回答的成本

还应按查询类型拆分分析:

短事实查询
跨段落查询
表格查询
精确编号查询
多文档查询
无答案查询
多语言查询

Google 的 RAG 评估建议也强调,应把检索和生成分别诊断,而不是只看最终回答,因为相同的最终错误可能分别来自 Chunking、Retriever、Reranker 或生成模型。(Google Cloud)


十三、一套务实的生产基线

对大多数企业知识库,可以从以下方案开始:

1. 使用布局感知解析器恢复文档结构
2. 按标题、章节、段落、列表、表格和代码块切分
3. 不跨越高层级章节边界
4. 超长块按句子和 Token 递归拆分
5. 使用 Token 而不是字符作为最终长度约束
6. 初始测试 400、600、800 tokens 等多个档位
7. 只在必要位置使用少量 overlap
8. 为每块补充标题路径、页码、版本、来源和 ACL
9. 保留 parent_id、chunk_index 和邻接关系
10. 用真实查询集比较 Dense、Hybrid、Rerank 后的表现
11. 只有基线不足时,再引入 Contextual 或 Late Chunking
12. 将 Chunking 策略和版本写入索引 metadata

OpenAI 的 800-token 托管默认值、LangChain 的递归 Splitter、Google 和 Microsoft 的布局感知方案、Anthropic 的 Contextual Retrieval,以及 Late Chunking 研究,实际上代表的是不同层级的解决方案:

OpenAI:
托管检索产品的可用默认配置

LangChain:
通用实现工具和可组合 Splitter

Google / Microsoft:
文档结构与企业摄取工程

Anthropic:
为局部 Chunk 补充全文语境

研究论文:
探索新的上下文化 Embedding 和分段方法

它们并不互相排斥,也没有任何一家给出了适用于所有系统的唯一答案。


结论

结合前述资料,一套较稳健的 RAG Chunking 实践可以概括为:

先恢复和尊重文档结构,再按语义单元切分;使用 Token 上限约束块大小,通过标题、元数据和 Parent–Child 关系保留上下文,并用真实 Evaluation Dataset 决定 Chunk Size、Overlap 和高级策略。

固定长度 Chunking 仍然是重要基线;结构化 Chunking 通常是企业文档更可靠的默认选择;Contextual Retrieval、Late Chunking 和 LLM-guided Chunking 提供了有价值的新方向,但都不是无条件升级。

最终应避免的是:

看到某个平台默认 800 tokens
→ 直接复制到所有文档
→ 不区分 PDF、合同、表格和代码
→ 不做检索评估
→ 将其称为最佳实践

真正的最佳实践不是某个固定参数,而是:

可解释的切分策略、可重建的索引、分文档类型处理,以及由数据驱动的持续评估。