父子切片是什么
父子块策略把文档切成两级:小块用于向量检索,定位精度高;命中后返回它所属的大块给模型,语境完整。它是缓解「切片太小丢语境、切片太大检索不准」这对矛盾的常见做法,代价是需要在向量库之外再维护一份父块存储。
基本信息
| 检索粒度 | 子块,通常几百字以内 |
|---|---|
| 生成粒度 | 父块,通常为子块的四到五倍 |
| 存储要求 | 父块存 KV 或数据库,需持久化 |
| 返回策略 | 命中子块后按父块标识取回父块 |
父子检索器配置
父子检索器配置
from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain_text_splitters import RecursiveCharacterTextSplitter
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=400)
store = InMemoryStore()
retriever = ParentDocumentRetriever(
vectorstore=vectorstore, docstore=store,
child_splitter=child_splitter, parent_splitter=parent_splitter,
)
retriever.add_documents(documents)使用要点
- 父块要持久化:内存存储只适合原型,重启后父块丢失就取不回上下文
- 父子比例要有节制:父块过大时会一次带进大量无关内容
- 多个子块命中同一父块时要去重,否则上下文被同一父块重复占用
- 子块携带父块标识,元数据要保证可追溯
- 父块内容也要计入 token 预算,否则容易超限
大小块配置参考
| 层级 | 长度参考 | 作用 |
|---|---|---|
| 子块 | 200 到 500 字或数百 token | 向量检索与相似度判断 |
| 父块 | 子块的四到五倍 | 提供完整语境给生成 |
| 顶层文档 | 整篇或整章 | 需要跨节汇总时使用 |
常见问题
- 父子关系配反:父块小于子块,检索与生成两头受损
- 父块未落盘:服务重启后命中子块却取不到父块内容
- 同一父块被多次带回:缺少去重导致预算被浪费
- 父块过长:生成端被无关内容干扰,答案反而更差
生产环境要把父块存储换成持久化方案(KV 存储或关系库),避免重启后父块丢失,同时便于按文档维度做批量清理。
评测怎么做
- 分别统计子块命中率与最终答案完整性,确认两级粒度各自发挥了作用
- 对比纯单层切分方案,验证父子结构带来的增益是否覆盖额外复杂度
- 观察返回的父块长度分布,过长时需要在进入上下文前再截断
- 记录同一问题命中的父块数量,过多说明父块划分过粗