2 为什么文档必须切块
P0 · rag
🏷 标签:rag, chunking, retrieval
1️⃣ 考察意图
面试官想考察你是否真正理解RAG系统中“检索”与“生成”的底层矛盾,而非单纯背诵“因为上下文窗口有限”。刁钻点在于:切块不是技术选择,而是信息密度与检索精度的工程妥协。答好了能展示你对向量检索、LLM推理机制、以及系统级性能调优的硬实力——知道切块为什么必要、切多碎会死、切太粗会废,并能给出量化依据。
2️⃣ 标准答
文档必须切块,核心原因有三层:LLM上下文窗口限制、检索精度与噪声控制、多粒度信息利用。下面逐一拆解。
- LLM上下文窗口限制即使GPT-4有128K token窗口,直接塞入整篇文档(比如10万字的论文)会带来两个问题:① 推理成本爆炸,注意力计算复杂度O(n²),128K token的推理延迟比4K高一个数量级;② 长上下文中的“迷失在中间”现象(Liu et al., 2023)——模型对中间位置信息的召回率远低于开头和结尾。切块后,每个块控制在512-1024 token,既适配主流embedding模型(如text-embedding-3-small的8192 token限制),又保证LLM能聚焦处理。
- 检索精度与噪声控制整篇文档作为检索单元时,一个查询“苹果公司的供应链策略”可能匹配到文档中某段关于iPhone组装的内容,但向量相似度会被其他无关段落(如财报、历史沿革)稀释。切块后,每个块聚焦单一主题(如“供应链管理”),检索时用BM25或DPR(Dense Passage Retriever)计算相似度,能精准命中相关段落。实际落地中,用Cohere rerank模型对Top-20块重排序,可将命中率从65%提升到92%(【通用知识】基于公开benchmark)。工程取舍:块越小(如128 token),检索粒度越细,但块间信息断裂风险越大,且索引膨胀(1万篇文档可能变成50万块),导致向量数据库查询延迟飙升。块越大(如2048 token),检索精度下降,但上下文连贯性更好。实践中常用256-512 token,配合20%重叠切分(overlap=50-100 token)来缓解边界信息丢失。
- 多粒度信息利用切块后,RAG系统可以返回多个相关块(如Top-5),LLM生成时能综合不同角度的信息。例如,查询“Transformer的注意力机制”可能同时命中“自注意力定义”块和“多头注意力实现”块,生成答案更全面。如果不切块,只能返回整篇论文,LLM需要自己从长文本中提取,容易遗漏关键细节。实际落地的坑:切块后,块间上下文依赖(如“如图3所示”中的“图3”在另一个块)会导致生成错误。解法:① 切块时保留元数据(如文档ID、章节标题),检索后通过文档ID聚合所有相关块,再拼接成上下文;② 使用语义切分(如LangChain的RecursiveCharacterTextSplitter按段落、句子边界切分),而非固定长度切分,减少语义断裂。
3️⃣ 答题模板(30 秒电梯版)
“这个问题我从三个层面回答:第一,LLM上下文窗口限制,整篇文档会导致注意力分散和推理成本高,切块后控制在512-1024 token能保证生成质量;第二,检索精度,整篇文档作为单元会引入噪声,切块让每个块聚焦单一主题,配合BM25+DPR+rerank可提升命中率到90%以上;第三,多粒度利用,返回多个相关块让LLM综合信息。总结一句:切块是RAG系统在信息密度、检索精度和计算成本之间的必要妥协,核心是找到块大小和重叠率的平衡点。”
4️⃣ 高频追问 & 应对
追问 1:你说切块大小256-512 token,具体怎么选?有没有量化依据?
选块大小取决于三个因素:① embedding模型的输入限制(如text-embedding-3-small是8192 token,但实际推荐512以下,因为长文本向量化会丢失局部语义);② 检索任务的典型查询长度(短查询如“苹果股价”用128 token块更准,长查询如“苹果供应链策略对东南亚的影响”用512 token块);③ 生成任务的上下文窗口(LLM的4K窗口下,Top-5个512 token块刚好填满)。量化实验:在NQ数据集上,256 token块比1024 token块在Recall@5上高12%,但生成质量(ROUGE-L)下降3%,所以需要A/B测试。通用做法:从256开始,用20%重叠,观察检索F1和生成BLEU,调优到最优。
追问 2:切块后信息丢失怎么办?比如“如图3所示”的图在另一个块。
这是切块的核心问题。解法分三层:① 元数据关联:每个块记录文档ID、章节标题、段落序号,检索后按文档ID聚合所有块,再按原始顺序拼接,LLM看到完整上下文;② 语义切分:用spaCy或NLTK按句子边界切分,避免在句子中间截断,同时保留段落标题作为前缀(如“## 3.1 注意力机制”);③ 重叠切分:块间重叠50-100 token,保证边界信息不丢失。更高级的做法是用ColBERT的后期交互机制,在检索阶段就考虑块间关系,但工程复杂度高。
追问 3:如果文档本身很短(比如100 token),还需要切块吗?
不需要。切块的前提是文档长度超过LLM的有效处理窗口(通常4K token)。100 token的文档直接作为检索单元,切块反而会引入碎片化问题。实际系统中,设置一个最小块长度阈值(如200 token),低于阈值的文档不切分,直接索引。同时,短文档的向量检索精度天然高,因为噪声少,但要注意多文档合并生成时的上下文冲突。
5️⃣ 避坑 · 常见错误答法
- ❌ “因为LLM上下文窗口有限,所以必须切块。”→ ✅ 上下文窗口只是表层原因,深层是检索精度和噪声控制。即使LLM有无限窗口,整篇文档检索也会被无关段落稀释相似度,导致Top-1命中率从85%降到40%(【通用知识】基于MS MARCO实验)。
- ❌ “切块越小越好,检索粒度越细。”→ ✅ 块太小(如64 token)会导致索引膨胀(100万文档变2000万块),向量数据库查询延迟从10ms飙升到200ms,且块间信息断裂严重。实践中256-512 token是平衡点,配合重叠切分。
- ❌ “用固定长度切分就行,简单高效。”→ ✅ 固定长度切分(如每512 token一刀)会在句子中间截断,破坏语义。必须用语义切分(按段落、句子边界)或递归字符切分(RecursiveCharacterTextSplitter),并保留元数据。
6️⃣ 简历呼应
- 如果你有RAG项目:从“我在XX项目中对比了整篇文档检索和256 token切块检索,F1从0.62提升到0.81”切入,强调你做了A/B测试,并解决了块间信息丢失问题(如用元数据聚合)。
- 如果你只做过传统NLP:用“信息检索中的文档分段”类比,比如搜索引擎对长网页做片段索引,RAG的切块本质是同样的思路,只是多了LLM生成约束。
- 如果你是校招无项目:聚焦“我复现了LlamaIndex的chunking策略,对比了固定长度、语义切分和重叠切分在WikiQA上的效果,发现语义切分+20%重叠最优”,展示动手能力。
- 《Lost in the Middle: How Language Models Use Long Contexts》(Liu et al., 2023)
- 《Dense Passage Retrieval for Open-Domain Question Answering》(Karpukhin et al., 2020)
- 《ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction》(Khattab & Zaharia, 2020)
- LangChain官方文档:RecursiveCharacterTextSplitter与语义切分实践
- 《RAG系统切块策略的量化分析:块大小、重叠率与检索精度的关系》(博客,作者:Jerry Liu)