RAG 文档 Chunk 划分策略怎么选?
固定长度、语义边界、滑动窗口等方法的优缺点与适用场景
原题:在检索增强生成(RAG)系统中,文档的chunk划分策略有哪些常见方法?不同策略(如固定长度、语义边界分割、滑动窗口等)各自的优缺点及适用场景是什么?
文档处理 · 腾讯真题
回答与解析
常见分块策略对比
1. 固定长度分块
- 实现:按token数或字符数硬切分(如512 tokens)
- 优点:实现简单、Embedding批次处理高效、便于控制上下文长度
- 缺点:边界可能切断语义(如"深度学习...的优化方法"被拆开),导致检索片段不完整
- 适用:通用场景、对延迟敏感、文档结构松散时
2. 语义边界分割
- 实现:按句子(NLTK/spaCy)、段落(
\n\n)、或主题模型(如BERTopic)切分 - 优点:保留语义完整性,检索结果可读性强
- 缺点:块大小不均,可能过长(超出模型窗口)或过短(信息密度低);主题分割计算开销大
- 适用:法律合同、学术论文等结构清晰的文档
3. 滑动窗口/重叠分块
- 实现:设定块大小与滑动步长,相邻块重叠;两者都作为待测变量,由同一评测集决定
- 优点:避免边界信息丢失,保证上下文连贯性
- 缺点:存储冗余增加(~2倍),检索可能返回重复内容需去重
- 适用:对话历史、代码等强上下文依赖场景
4. 智能分块(进阶)
- Agentic分块:用LLM判断断点(如"此处是否完成一个完整论点")
- 结构化分块:针对Markdown、JSON、代码按语法树切分
选型建议
| 场景 | 推荐策略 |
|---|---|
| 快糙猛上线 | 固定长度 + 重叠 |
| 高精度问答 | 语义边界 + 滑动窗口 |
| 代码/表格 | 结构化分块 + 元数据标注 |
实际中常组合使用:先用语义边界粗分,再对过长块用滑动窗口细分。
学习建议
掌握常见chunk策略的原理与适用场景,结合实际RAG案例理解其对检索精度和生成效果的影响。
口语版讲法(约4分钟)
- 一句话定位:chunk 本质是检索精度与上下文完整性的取舍
- 固定长度 vs 语义边界:各适用什么场景,边界在哪
- 滑动窗口解决边界问题,但冗余是代价,组合策略才是常态
- 业务案例:企业 SOP 检索,语义分块 + 滑动窗口组合
- 落地风险:块大小、去重、元数据,以及一个延伸可延伸点
好,这道题问的是 Chunk 划分策略,我觉得它本质上是在考一个取舍:你如何在检索精度和上下文完整性之间做平衡。因为 RAG 的召回质量,很大程度上取决于你切出来的块是不是既独立又完整。
先说最直接的固定长度分块,按多少 token 或者字符数硬切。这个方案好处是简单、快,Embedding 批量处理效率高,而且能精确控制上下文长度。但它有个硬伤,就是边界可能把一句话或者一个逻辑单元从中间切断。举个例子,如果一篇文档在讲「深度学习的优化方法」,其中一句刚好被拦腰截断,那检索时返回的片段可能就变成了「深度学习的优化」,意思就偏了。所以它只适合文档结构松散、对语义完整性要求不高的通用场景,比如新闻聚合或者日志检索。如果你要快速上线一个 MVP,用这个没问题,但追求高精度问答就不行。
再一个就是语义边界分割,按句子、段落或者主题来切。这个能最大程度保留语义完整,检索回来的片段读起来通顺、可理解。但代价是块大小不均匀,有的块可能特别长,超出模型窗口;有的又特别短,信息密度低。而且像按主题切分,用 BERTopic 之类的模型,计算开销不小。它适合法律合同、学术论文这种结构清晰的文档,因为这些文档天然有段落和章节,切出来不会太离谱。
还有个常见的策略是滑动窗口,也叫重叠分块。它通过设定块大小和滑动步长,让相邻块有重叠。这么做的好处是彻底避免了边界信息丢失,比如一个关键概念跨了两块,重叠能保证至少有一块完整包含它。但代价也很明显,存储冗余,数据量可能翻倍,而且检索时可能返回多个高度相似的结果,需要额外去重。所以它适合对话历史、代码这类强上下文依赖的场景,比如你查一段代码,如果切断了函数定义和调用,那检索回来的就没法用。
真正落地的时候,我基本不会只用一种策略。通常是组合使用:先用语义边界粗分,保证核心块完整,然后对长度超过窗口的块,再用滑动窗口细分。举个例子,在企业 SOP 和合规文档检索里,文档结构很清晰,按章节切分后,有的章节特别长,比如「退款流程」可能包含好几页,这时候我就用滑动窗口把这一章切成几个 512 token 的块,步长设 256,这样既保证了语义边界,又控制了块大小。
这里有个坑一定要提:滑动窗口的冗余不是随便设的。步长太短,冗余太多,检索结果里全是重复信息;步长太长,重叠不够,又回到边界问题。我一般会先根据文档的平均句子长度来调,上线后监控 RAGAS 指标里的上下文精度,如果重复率太高就加大步长。另外,块大小不能超过 LLM 的上下文窗口,但也不能太小,否则信息密度低,Rerank 也救不回来。
还有一个方向我最近在关注,就是智能分块,比如用 LLM 自己判断断点,或者对 Markdown、JSON 按语法树切分。这个在代码或表格场景里效果很好,但代价是延迟和成本。如果面试官感兴趣,我可以展开讲讲结构化分块怎么跟元数据标注结合,来提升检索精度。
所以总结一下,我不会把 chunk 策略看成孤立的选择,我更倾向把它当成一个系统工程,结合文档结构、业务场景和上线指标来动态调整。没有银弹,关键是理解每种策略的代价,然后做取舍。
关键一句:智能分块(如 LLM 判断断点或语法树切分)在代码和表格场景中效果好,但延迟和成本是代价,可结合元数据标注优化。
面试官还可能这样问
- 问法 1 · 场景切入
我看你做过电商知识库问答。假设用户问'怎么申请退款',系统检索到一段文档,但那一段刚好在'退款政策'和'退货流程'之间被切断了,回答就少了一半。你觉得这种情况怎么避免?你一般怎么切文档?
- 问法 2 · 层层追问
RAG系统里文档怎么切块这个问题,你了解过哪些方法?……比如固定长度切块有什么坑?……那如果我想保证每个块语义完整,有什么更好的办法?……滑动窗口呢,什么场景下用?
- 问法 3 · 直球架构
讲一下RAG里文档分块策略的常见方法,固定长度、语义边界、滑动窗口这些,各自优缺点和适用场景。你实际项目中怎么选型?