先这样答
RAG 的父子索引是一种分层切分与检索策略。在构建索引时,将文档切分为两层或多层结构——底层是句子或小段落级别的子块,负责检索命中;上层是段落或章节级别的父块,负责提供完整的上下文。向量数据库中只存储子块的向量,当用户提问命中某个子块时,系统会通过映射关系找到其对应的父块,并将父块的内容送入提示词交给大模型。
这种机制主要解决检索与生成在文本粒度需求上的矛盾。小块文本语义集中,参与向量计算时命中准确率高,但直接将小块交给大模型会导致上下文不全,例如代词指代不明、前置限定条件丢失或论证过程被切断。父块保留了完整的论述背景,通过检索小块并返回大块,既保证了召回精度,又保留了完整的论述过程,保证了最终的生成质量。
与常规的重叠窗口切分相比,父子索引避免了 token 冗余。重叠切分虽然能缓解内容切断,但缺乏层级概念,如果相邻的切片同时被命中,同一段内容会被重复放入上下文。父子索引机制下,一份父块只进一次提示词,去重效率更高。
在代价方面,这种设计会让索引的存储与维护成本翻倍,需要维护两层的映射关系。由于返回的是大块,父块的 token 开销大于小块,系统需要重新分配上下文预算。此外,层级切分对文档本身的结构有要求,如果语料结构混乱,父子边界就很难准确划分。在面试官面前可以总结说,父子索引是用存储和处理成本换取生成质量。
面试官会怎么追问
- 「普通的 chunk overlap 也能缓解上下文切断,为什么要专门做一层父子索引?」 常规的重叠窗口虽然能缓解切断问题,但没有层级概念,会导致 token 冗余。当相邻的小块同时被检索命中时,重叠部分会被重复送入大模型的上下文。父子索引通过映射机制,可以去重并确保一份父块只进一次提示词,提高了上下文空间的利用效率。
- 「设计这种两层或者多层的索引,在工程落地时有什么代价?」 主要是存储和计算开销增加,需要存储子块向量并维护映射关系,存储量会翻倍。其次是 token 消耗增加,返回大块会占用更多的上下文预算,需要重新评估和截断。最后是数据处理成本,层级切分依赖文档原有的结构,如果是非结构化的散乱语料,很难制定准确的父子边界规则。
- 「如果文档本身结构很乱,无法提取清晰的父子层级,怎么应用这种思想?」 可以降级使用句子窗口策略,这是父子索引的轻量版实现。切分时以句子为单位进行向量化和检索,命中后在原文中向前后各扩展固定数量的句子,将拼合后的窗口文本作为大块返回给大模型,这样不需要预先解析复杂的文档结构。
回答的坑
- 错误认为父子索引中父块和子块都需要进行向量化检索,正确方向是明确指出只有小块进入向量库参与相似度计算,大块仅作为键值对存储用于文本召回。
- 回答时只强调检索精度的变化而忽略了生成端的需求,正确方向是点明检索与生成存在的粒度矛盾,解释返回大块是为了解决上下文缺失、指代不明等生成阶段的问题。
同系列的题
—— 本题完 ——