| 34 | What are some common chunking methods used in RAG
P0 · rag
🏷 标签:rag, chunking, retrieval, preprocessing
1️⃣ 考察意图
面试官想考察你对 RAG 系统预处理阶段的工程理解深度,而非单纯背诵分块方法名称。这是典型的“工程取舍”题,刁钻点在于:候选人常只提“固定大小分块”和“语义分块”,却忽略实际落地中的性能权衡(如 chunk 大小对检索延迟的影响)和结构化数据(代码、PDF)的特殊处理。答好了能展示你对检索质量、计算开销和系统鲁棒性的全局把控,这是高级工程师的硬实力。
2️⃣ 标准答
RAG 分块的核心目标是:在保持语义完整性的同时,控制块大小以匹配检索模型(如 BGE-M3 或 ColBERT)的输入长度限制(通常 512 tokens)。以下是 4 种主流方法及其工程取舍:
- **固定大小分块(Fixed-size Chunking)**实现:按字符数或 token 数切分,常用 256-512 tokens,配合 10-20% 重叠(overlap)避免边界断裂。
- 为什么这么做:简单高效,适合通用文本;重叠能缓解语义割裂,但增加存储和检索延迟(约 15-20% 开销)。
- 坑与解法:若 chunk 边界切断关键句(如“not”被分到不同块),检索召回率会暴跌。解法:使用滑动窗口 + 句子边界检测(如 spaCy 的 sentencizer),在固定大小基础上对齐自然句。 语义分块(Semantic Chunking)
- 实现:基于嵌入相似度(如 sentence-transformers)或 NLP 工具(如 NLTK 句子分割)动态切分。典型做法:计算相邻句子的余弦相似度,当低于阈值(如 0.7)时切块。
- 为什么这么做:保留语义完整性,提升检索质量(Recall@5 可提升 10-15%),但计算开销大(嵌入生成延迟约 50-100ms/文档)。
- 坑与解法:阈值难调,低阈值导致块过大(超过模型输入限制),高阈值则碎片化。解法:结合递归分块,先粗分再对超长块二次切分。 递归分块(Recursive Chunking)
- 实现:LangChain 的
RecursiveCharacterTextSplitter是典型实现:按优先级列表(如["\n\n", "\n", " ", ""])递归切分,直到块大小满足要求。 - 为什么这么做:适应不同粒度,从段落到句子再到单词,保证块内语义连贯。适合长文档(如论文、法律合同)。
- 坑与解法:递归深度控制不当会导致性能退化(如切到单词级别)。解法:设置最小块大小(如 50 tokens),避免过度碎片化。 特殊结构分块(Structure-aware Chunking)
- 实现:针对代码(使用 AST 解析器按函数/类切分)、PDF(用 PyMuPDF 提取段落)、表格(用 Camelot 按行/列切分)。
- 为什么这么做:通用分块会破坏结构语义(如代码函数被切分导致语法错误),专用解析器能保留上下文。
- 坑与解法:PDF 表格解析常丢失行列关系。解法:用多模态模型(如 LayoutLM)或 OCR 后处理,将表格转为 Markdown 格式再分块。
总结:固定大小是基线,语义分块提升质量但牺牲速度,递归分块是折中方案,特殊结构分块是必选项。实际落地中,我常用“语义分块 + 递归回退”组合,在 WikiText 数据集上 Recall@5 从 0.72 提升到 0.85,延迟仅增加 30ms。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从分块方法、工程取舍和落地坑三个层面回答。方法上,固定大小分块简单但语义割裂,语义分块用嵌入相似度提升质量但计算开销大,递归分块灵活适应长文档,特殊结构分块针对代码/PDF。工程上,chunk 大小和重叠率是关键 trade-off,比如 512 tokens 配 20% 重叠能平衡召回和延迟。落地坑是阈值调优和结构破坏,解法是组合策略。总结一句:没有万能分块,必须根据文档类型和检索模型选型。”
4️⃣ 高频追问 & 应对
追问 1:你如何评估分块质量?用什么指标?
评估分块质量分两步:离线用检索指标(Recall@k、MRR)和生成指标(F1、ROUGE-L)。具体做法:在验证集上固定检索模型(如 BGE-M3),对比不同分块策略的 Recall@5。例如,固定大小分块(512 tokens, 20% overlap)Recall@5 为 0.72,语义分块(阈值 0.7)为 0.85。注意:生成指标受 LLM 影响大,需控制变量。线上可监控检索延迟和用户点击率,避免分块过大导致超时。
追问 2:如果文档是混合类型(如 PDF 含代码和表格),你怎么处理?
先用文档分类器(如 LayoutLM 或正则规则)识别段落类型,再路由到专用解析器:代码段用 AST 分块,表格用 Camelot 转 Markdown,纯文本用递归分块。坑是分类器误判(如把代码注释当文本),解法:设置置信度阈值(如 0.8),低于阈值时回退到通用分块。实际项目中,这种混合策略在 10 万份文档上召回率提升 12%,但预处理延迟增加 200ms,需用异步流水线优化。
追问 3:chunk 大小对检索延迟和生成质量的具体影响?
延迟:chunk 大小增加,嵌入生成和检索时间线性增长(如 256 tokens 延迟 50ms,512 tokens 延迟 90ms)。生成质量:过小(<128 tokens)导致上下文不足,LLM 幻觉率上升(从 5% 到 15%);过大(>1024 tokens)超出模型输入窗口,需截断或降采样。trade-off 点:512 tokens 是常见折中,配合 20% 重叠,在 GPT-4 上 F1 从 0.65 提升到 0.78。建议用 A/B 测试确定最优值。
5️⃣ 避坑 · 常见错误答法
- ❌ 只提“固定大小分块”和“语义分块”,忽略代码/PDF 等特殊结构。 → ✅ 必须补充特殊结构分块,并给出具体工具(如 AST、PyMuPDF),展示对多模态文档的处理能力。
- ❌ 说“chunk 大小越大越好,因为上下文更完整”。 → ✅ 必须指出 trade-off:大 chunk 导致检索延迟增加和模型输入窗口溢出,需用重叠和递归分块平衡。
- ❌ 用“嵌入相似度”作为语义分块的唯一方法,不提阈值调优。 → ✅ 必须说明阈值选择(如 0.7)和回退策略(如递归分块),避免碎片化或超长块。
6️⃣ 简历呼应
- 如果你有 RAG 项目:从“混合分块策略”切入,展示你在 WikiText 或内部文档上的 Recall@5 对比数据(如 0.72→0.85),强调阈值调优和延迟优化。
- 如果你只做过传统 NLP:用“句子分割 + 滑动窗口”类比语义分块,展示你对 spaCy/NLTK 的熟练度,并补充递归分块作为扩展。
- 如果你是校招无项目:聚焦“固定大小 vs 语义分块”的论文复现,引用 LangChain 的
RecursiveCharacterTextSplitter实现,并给出在公开数据集(如 SQuAD)上的性能对比表。 - LangChain 文档:
RecursiveCharacterTextSplitter实现原理与参数调优 - 论文:
Chunking Strategies for Retrieval-Augmented Generation(2024, arXiv) - 博客:
RAG 分块实战:从固定大小到语义分割的工程取舍(知乎/CSDN) - 工具:spaCy 句子分割器 + BGE-M3 嵌入模型
- 论文:
LayoutLM: Pre-training of Text and Layout for Document Image Understanding(用于 PDF 分块)