分块策略具体怎么做的
P1 · rag · 🏢 字节
1️⃣ 考察意图
面试官想考察你对 RAG 系统底层数据处理的工程化理解,而非单纯背概念。这是一道“系统设计 + 工程取舍”题,刁钻点在于:分块看似简单,但直接影响检索召回率和 LLM 生成质量。答好了能展示你从数据预处理到检索整条链路的硬实力,包括对文档结构、语义边界、长度控制、overlap 设置的权衡,以及实际落地中处理表格、代码块等特殊内容的经验。
2️⃣ 标准答
分块策略不是一刀切,而是基于文档类型和检索目标的多层设计。我采用三层策略,结合规则和语义,确保分块既保留上下文又适配 embedding 模型。
第一层:基于文档结构的规则切分
- 利用文档的天然边界(章节标题、段落、列表、表格、代码块)作为切分点。例如,用正则或解析库(如
python-docx、PyMuPDF)提取标题层级,按<h1>、<h2>等划分。 - 特殊内容处理:表格和代码块整段保留,不截断。因为截断表格会破坏行列对应关系,导致检索时语义丢失;代码块截断则可能让变量声明和调用分离,LLM 无法理解上下文。
- 工程取舍:规则切分速度快、可解释性强,但依赖文档格式一致性。对于非结构化文本(如论坛帖子),规则失效,需降级到下一层。
第二层:语义连贯性检查与合并
- 对第一层产生的 chunk 进行语义相似度计算。使用轻量级模型(如
all-MiniLM-L6-v2)或基于 token 的滑动窗口,计算相邻 chunk 的 cosine 相似度。 - 合并规则:若两个 chunk 语义相似度 > 0.85,且合并后长度不超过最大 token 限制(如 512 tokens),则合并。这能避免过短 chunk(如单句)导致检索噪声。
- 实际落地的坑:跨页内容(如 PDF 中表格跨两页)常被规则切分拆开。解法:在解析 PDF 时,先合并跨页元素(如用
pdfplumber检测表格边界),再送入第一层切分。
第三层:长度控制与 overlap 设置
- 设定 chunk 长度范围(如 256-512 tokens),基于 tokenizer(如
tiktoken或transformers的AutoTokenizer)精确计数,而非字符数。因为 embedding 模型(如text-embedding-ada-002)有最大 token 限制,超长会被截断。 - Overlap 设置:相邻 chunk 重叠 10%-20% 的 token(如 50 tokens)。这能保留上下文边界,避免关键信息(如段落首句)被切分到两个 chunk 中。例如,一个 500 token 的段落,切分为 [0:300]、[250:500] 两个 chunk,重叠 50 tokens。
- 工程取舍:overlap 越大,检索召回率越高,但存储和计算成本也线性增加。对于高精度场景(如法律文档),overlap 设为 20%;对于高吞吐场景(如实时问答),设为 10% 并配合缓存。
实际落地中的坑与解法
- 坑:Markdown 或 HTML 中的列表项被切分后,LLM 无法理解列表结构。解法:在规则切分时,将整个列表(
<ul>或<ol>)视为一个 chunk,不按列表项切分。 - 坑:中文文本的语义边界不明显(如“但是”前后语义转折)。解法:使用中文分句工具(如
jieba或spaCy)先分句,再按语义相似度合并,而非按固定字符数切分。
总结:三层策略从规则到语义再到长度控制,层层递进,平衡了速度、精度和存储成本。实际中需根据文档类型(如 PDF、HTML、纯文本)调整各层参数,并通过离线评估(如 recall@k 和 MRR)验证效果。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一层基于文档结构做规则切分,保留表格和代码块完整性;第二层用语义相似度检查相邻 chunk 连贯性,合并过短或跨页内容;第三层控制长度在 256-512 tokens,并设置 10%-20% 的 overlap。总结一句:分块不是一刀切,而是根据文档类型和检索目标,在规则、语义和长度之间做工程取舍。”
4️⃣ 高频追问 & 应对
追问 1:你如何评估分块策略的好坏?具体用什么指标?
评估分块策略的核心指标是检索召回率(recall@k)和生成质量(如 BLEU、ROUGE,或人工评分)。具体做法:构建一个测试集,包含文档和对应问题,用不同分块策略检索 top-k chunk,看问题答案是否在 chunk 中。例如,用 BM25 或 DPR 检索,计算 recall@5。另外,用 LLM 生成答案后,对比 ground truth 的语义相似度(如 BERTScore)。工程上,我还会监控 chunk 的平均长度和 overlap 比例,确保不超出 embedding 模型限制。
追问 2:如果文档是纯文本(无标题、段落),你的规则切分失效,怎么办?
降级到纯语义切分:先用分句工具(如
spaCy或nltk)将文本拆成句子,然后用滑动窗口计算相邻句子的语义相似度(如用sentence-transformers)。设定阈值(如 0.7),相似度低于阈值的点作为切分边界。同时,设置最小 chunk 长度(如 100 tokens),避免过短 chunk。这种方法不依赖文档结构,但计算成本高,适合离线预处理。对于实时场景,可先用固定 token 数切分(如 256 tokens),再通过语义检查合并。
追问 3:你的 overlap 设置如何避免信息冗余?比如同一个信息出现在多个 chunk 中,检索时会不会重复?
overlap 确实会引入冗余,但这是 trade-off:冗余提高了召回率,但增加了存储和检索成本。解法:在检索阶段,对返回的 top-k chunk 做去重,基于 chunk 的 embedding 相似度(如 cosine 距离 < 0.9 视为重复)或内容哈希(如 MinHash)。另外,在生成阶段,LLM 的 prompt 中可加入去重指令(如“忽略重复内容”)。对于高精度场景,我还会在 chunk 元数据中记录 overlap 区域,检索时只返回非重叠部分。
5️⃣ 避坑 · 常见错误答法
- ❌ 说“分块就是按固定字符数切分,比如 500 字符一个 chunk” → ✅ 正确切入:必须用 token 计数而非字符数,因为 embedding 模型和 LLM 都按 token 限制;同时需考虑语义边界,避免截断句子或段落。
- ❌ 说“overlap 越大越好,能保留所有上下文” → ✅ 正确切入:overlap 过大会导致存储膨胀和检索噪声,需根据场景平衡;实际中 10%-20% 是常见范围,并配合去重策略。
- ❌ 说“所有文档都用同一套分块参数” → ✅ 正确切入:不同文档类型(如 PDF、HTML、代码)需要不同规则,例如代码块整段保留,Markdown 列表不切分;参数需通过离线评估调优。
6️⃣ 简历呼应
- 如果你有 RAG 项目:从项目中的文档类型(如 PDF 报告、网页爬虫)切入,说明你如何针对不同格式设计规则切分,并评估了 recall@k 的提升。例如,“在处理金融 PDF 时,我通过合并跨页表格,使 recall@5 提升了 12%”。
- 如果你只做过传统 NLP:用文本分割的类比迁移,例如“传统 NLP 中的句子分割(如
spaCy分句)类似第一层规则切分,而语义连贯性检查类似文本摘要中的句子排序”。强调你理解分块对下游任务的影响。 - 如果你是校招无项目:聚焦论文复现 demo,例如“我复现了 LangChain 的
RecursiveCharacterTextSplitter,并对比了不同 chunk 大小对text-embedding-ada-002检索效果的影响,发现 256 tokens 时 recall@5 最优”。展示你对工具和评估的理解。 - "Advanced RAG: Chunking Strategies for Better Retrieval"(博客,讨论规则 vs 语义切分)
- "Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks"(论文,用于语义相似度计算)
- "LangChain Text Splitters Documentation"(工具,展示多种分块实现)
- "Evaluating Chunking Strategies for RAG Systems"(博客,含 recall@k 评估方法)
- "The Impact of Chunk Size on Retrieval Quality in RAG"(论文,分析 token 长度与检索效果关系)