RAG 中如何设计文档切块策略?Chunk 越小越好吗?
简化版
切块要在**「检索精度」和「上下文完整性」** 之间平衡:块太大容易混入多个主题、降低匹配精度还浪费上下文;块太小会割裂语义,让答案所需证据分散、召回不全。生产中通常优先按标题、段落、语义边界切,再结合适量重叠、父子检索和真实评估确定大小。核心认知:没有脱离业务数据的万能尺寸,「统一切 500 token」只能当起点。
详细版
常见切块方式:
- 固定长度切块:简单、吞吐稳,但容易从句子/表格中间截断;
- 递归切块:依次按章节→段落→句子分隔符,在长度限制内尽量保留结构;
- 语义切块:按相邻句子向量相似度或主题变化定边界,质量好但成本高;
- 结构化切块:针对 Markdown/HTML/PDF/代码/表格用专门解析器;
- 父子切块:小块精确召回,返回包含它的大父块供模型阅读。
Chunk 大小按 token 而非字符评估,结合文档类型、Embedding 输入上限、问题粒度、Top-k、生成模型上下文预算调优。
完整版教学
一、切块为什么决定检索上限
RAG 的检索单元通常不是整份文档,而是切分后的 chunk,Embedding 会把整个 chunk 压成一个向量。这带来两难:
块太大:一个块含多主题 → 向量是"混合语义" → 查询难与其中某一小段精确匹配
块太小:把"定义/条件/结论"拆到三个块 → 每块很纯,但只召回一个无法回答问题
所以切块本质是控制检索单元的「信息密度」和「自包含程度」——既要够纯(好匹配),又要够全(能回答)。
二、不要迷信固定 token 数
「统一切 500 token」只能当起点。不同内容的最优粒度天差地别:
| 内容类型 | 合适切法 |
|---|---|
| FAQ 一问一答 | 一问一答成块,可能几十 token |
| 合同条款 | 连同标题、定义、例外一起 |
| 代码 | 保留函数/类边界,别拦腰截断 |
| 表格 | 保留表头,别按行拆散丢了列含义 |
更稳的顺序是先识别文档结构,结构单元过长时再递归细分。每个块还要带标题路径、页码、文档 ID、更新时间、权限等元数据。
三、Overlap 的作用和代价
相邻块保留重叠,能避免关键句恰好跨边界、让指代词保留前文。但不是越大越好:
Overlap 过大的副作用:
索引条目和 Embedding 成本↑
相似块占满 Top-k(挤掉其他证据)
拼接上下文出现大量重复
Recall 看似提高,信息增益却没增加
更好的做法:按句子边界重叠(而非硬切 N token),并在召回后按文档位置合并、去重相邻块。
Overlap 取多大、怎么用消融实验定值,见「RAG 切块为什么需要 overlap?如何设置?」。
四、父子检索兼顾精度和完整性
父子检索是「小块找得准、大块读得全」的经典解法:
文档 → 拆成较大父块 → 每个父块再拆成较小子块
向量匹配用【子块】(精确)→ 命中后返回【父块】或命中位置附近窗口(完整)
它适合章节结构明确的手册、合同、技术文档。但父块太大会重新引入噪声,所以仍要限长度,并按问题决定返回父块、邻居块还是原始子块。
父子分块的检索与回填、长文档和多跳问题怎么补全上下文,见「RAG 中父子分块检索怎么做?长文档和多跳问题如何补全上下文?」。
五、特殊内容处理(解析错误是隐形杀手)
- 表格:保留表头与行列关系,转结构化文本或 Markdown;
- PDF:先处理页眉页脚、双栏顺序、扫描 OCR、断行;
- 代码:按类/函数/语法树节点切;
- 对话记录:保留说话人和必要轮次;
- 图片图表:用 OCR/视觉模型/人工描述补可检索文本。
记忆钩子:解析错误会在切块前就破坏信息,不能靠调 chunk size 修复。 很多 RAG 问题的根子在「PDF 没解析好」,而非「切块参数不对」。
六、常见误区与追问
- 误区:chunk 越小越好。 太小割裂语义、证据分散召回不全;要按自包含知识点切。
- 误区:统一切 500 token 是最佳实践。 只是起点,FAQ/合同/代码/表格的最优粒度完全不同。
- 误区:Overlap 越大召回越好。 过大导致索引膨胀、重复占满 Top-k、上下文浪费。
- 误区:切块参数能修复一切。 解析错误(PDF 乱序、表格拆散)在切块前就毁了信息。
- 追问:块太大和块太小分别有什么问题? 太大→向量混合语义、匹配不准、浪费上下文;太小→证据被拆散、召回不全。
- 追问:父子检索解决什么? 子块精确匹配 + 返回父块给完整上下文,兼顾「找得准」和「读得全」。
- 追问:怎么定最优 chunk 大小? 用真实问题+相关证据的评估集,比 Recall@k、上下文精确率、答案忠实度、成本,看失败是没召回还是缺上下文。
七、加强记忆
切块像整理复习卡片:一张卡写整本书会主题模糊(块太大混合语义),只写半句话又无法理解(块太小割裂证据)。核心心法钉死:沿自然结构切出「自包含知识点」、用适量重叠(按句边界)防断句、用父子检索兼顾”找得准”和”读得全”、Overlap 过大有害、解析错误切块救不了。按 token 评估、带全元数据、用评估集选参数——没有脱离业务数据的万能尺寸。
项目实战落地
项目里怎么做的
《AI Agentic RAG高级企业知识库平台》把切分做成可以配置的「切分策略」,预置三套:
| 策略 | 片段长度 | 重叠 | 绑定的知识库 |
|---|---|---|---|
| 递归分块-通用 | 500 字 | 50 字 | 产品技术知识库(连续叙述的技术说明) |
| 递归分块-短片段 | 250 字 | 30 字 | 售后服务知识库(大量独立的问答条目) |
| 父子分块-制度手册 | 父块 1200 字、子块 300 字 | 子块间 30 字,父块间不重叠 | 公司制度知识库(条款要整条引用) |
递归分块的分隔符按「空行 → 换行 → 句号、叹号、问号 → 按字数硬切」逐级降级,尽量在段落和句子的自然断点上断开,避免出现「退款审核通过后 3 到」这种被拦腰截断的片段。
《AI企业知识库》的做法更朴素:先按空行分段,把短段落合并到 500 字以内;单个段落超过 500 字时才按固定长度滑窗切,相邻两块重叠 80 字。切片长度和重叠长度都配在知识库上,不同知识库可以用不同粒度。
《AI Agent 智慧医院智能导诊就诊系统》的医学语料是「【小标题】+ 正文段」的结构,于是直接按标题块切:每个【】标题连同它下面的正文切成一个片段,标题写进 chunk_title;只有正文超过 180 字的块,才按 180 字窗口、30 字重叠二次切,后续片段的标题带上「- 片段N」后缀。
《AI Agent岗位匹配与求职规划系统》的求职知识是一篇篇完整的求职指导文章,切分用的是最简单的固定长度:CareerKnowledgeService.splitContent 先把 \r\n 统一成 \n、去掉首尾空白,再按 700 字一个窗口往后切,不看段落和句子边界。切出的每一片带序号写进 knowledge_chunk,知识上记下切片数。
为什么这样取舍
- 策略跟着知识库走,不做全局参数。 同一个系统里,技术手册、FAQ 和制度条款的结构完全不同,用同一个片段长度必然顾此失彼。
- 语料自带结构时,直接按结构切。 医学指南、科室介绍本来就一个小标题讲一件事,按标题切出的片段主题完整,标题还能直接作为引用来源展示,比按字数切更可靠。
- 短片段策略必须配合更大的检索条数。 检索 5 段时,500 字策略给模型约 2500 字资料,250 字策略只有约 1250 字,条数不调大,答案就容易不全。
面试官还会追问
- 知识库改了切分策略之后,已经向量化的数据要怎么处理?
- 用了父子分块,检索策略里却没开「父块回填」,效果会怎样?
- 页面上显示的片段数为什么比实际切出来的记录少?
学完《AI Agentic RAG高级企业知识库平台》,上面这些追问你都会迎刃而解。