RAG 系列(十二):高级分块策略——Parent-Child 与 Contextual Retrieval

分块的两难困境

RAG 系统里有一个经典矛盾:

  • Chunk 太小:向量匹配精准,但返回给 LLM 的内容是片段,缺乏上下文,无法完整回答问题
  • Chunk 太大:内容完整,但语义太分散,embedding 质量下降,检索命中率降低

这不是调参能解决的问题,而是 Naive 分块的结构性缺陷。

小块适合检索,大块适合生成------这两个需求本来就是矛盾的,用同一个尺寸的 chunk 同时满足两者,必然顾此失彼。

本篇介绍两种突破这一困境的方案:

  1. Parent-Child Chunking:用小块做检索,命中后返回对应的大块
  2. Contextual Retrieval(Anthropic 方案):给每个 Chunk 加上文档上下文描述,让 embedding 更"聪明"

Parent-Child Chunking

核心思路

erlang 复制代码
索引阶段:
  父文档(800字)→ 存储在 docstore(InMemoryStore)
  ↓ 切割
  子 Chunk(200字)→ 存入向量库

检索阶段:
  query → 向量检索匹配子 Chunk(精准)
  → 找到子 Chunk 对应的父文档
  → 返回父文档给 LLM(完整)

检索用的是小 chunk,LLM 拿到的是大 chunk。两个需求,各自最优,互不干扰。

代码实现

LangChain 的 ParentDocumentRetriever 封装了这个逻辑:

python 复制代码
from langchain_classic.retrievers import ParentDocumentRetriever
from langchain_classic.storage import InMemoryStore
from langchain_text_splitters import RecursiveCharacterTextSplitter

child_splitter = RecursiveCharacterTextSplitter(
    chunk_size=200,    # 小块:用于向量检索
    chunk_overlap=20,
)
parent_splitter = RecursiveCharacterTextSplitter(
    chunk_size=800,    # 大块:命中后返回给 LLM
    chunk_overlap=50,
)

vectorstore = Chroma(collection_name="parent_child", embedding_function=embeddings)
store = InMemoryStore()   # 存储父文档的 docstore

retriever = ParentDocumentRetriever(
    vectorstore=vectorstore,
    docstore=store,
    child_splitter=child_splitter,
    parent_splitter=parent_splitter,
    search_kwargs={"k": 4},
)
retriever.add_documents(parent_docs)

调用时和普通 retriever 完全一样,框架自动处理子→父的映射:

python 复制代码
docs = retriever.invoke("中文场景用哪个 Embedding 模型?")
# 返回的是 800 字的父文档,而不是 200 字的子 chunk

Contextual Retrieval

核心思路

Anthropic 在 2024 年发布的 Contextual Retrieval 方案,解决的是另一个问题:Chunk 孤立后丢失了它在文档中的位置信息

举个例子。假设文档里有这样一段:

"该方法与前文提到的方式相比,准确率提升了 12%。"

切成 chunk 之后,"前文提到的方式"是什么完全丢失了。向量 embedding 只看到这一段,完全不知道上下文,语义严重缺失。

Contextual Retrieval 的做法:用 LLM 为每个 Chunk 生成一段上下文描述,拼接到 chunk 前面,再做 embedding:

arduino 复制代码
原始 Chunk:
"该方法与前文提到的方式相比,准确率提升了 12%。"

加上上下文描述后:
"本段描述的是 RAG 混合检索策略与传统向量检索的性能对比,属于文章的实验结果部分。

该方法与前文提到的方式相比,准确率提升了 12%。"

embedding 看到的信息更完整,检索质量自然更高。

Prompt 设计

python 复制代码
CONTEXT_PROMPT = ChatPromptTemplate.from_messages([
    ("system", "你是一个文档分析助手。"),
    ("human",
     "以下是一篇完整文档:\n\n<document>\n{doc_content}\n</document>\n\n"
     "以下是文档中的一个片段:\n\n<chunk>\n{chunk_content}\n</chunk>\n\n"
     "请用 1-2 句话概括这个片段在整篇文档中的作用和背景,"
     "帮助理解该片段的含义。只输出描述文字,不要加任何前缀。"),
])

代码实现

python 复制代码
context_chain = CONTEXT_PROMPT | llm | StrOutputParser()

docs = []
for item in raw_data:
    full_content = f"标题:{item['title']}\n{item['content']}"
    chunks = splitter.split_text(full_content)
    for chunk in chunks:
        # 为每个 chunk 生成上下文描述
        context_desc = context_chain.invoke({
            "doc_content": full_content,
            "chunk_content": chunk,
        })
        # 拼接后作为实际 embedding 内容
        enriched_content = f"{context_desc}\n\n{chunk}"
        docs.append(Document(page_content=enriched_content, ...))

注意: 每个 chunk 需要单独调用一次 LLM,索引阶段成本比 Naive 高。知识库 8 篇文档约 30-40 个 chunk,开销可接受;超大知识库需要考虑批量处理和成本控制。


实验设计

复用知识库(8 篇 RAG 技术文档)和测试集(8 条问题),对比三种策略:

策略 检索单元 返回给 LLM
Naive Chunking 512 字 chunk 512 字 chunk
Parent-Child 200 字子 chunk(检索) 800 字父文档
Contextual Retrieval 512 字 + 上下文描述(检索) 512 字 + 上下文描述

核心关注指标:context_recall(完整信息是否被召回)和 context_precision(排序是否准确)。


实验结果

diff 复制代码
======================================================================
  RAGAS 指标对比(三种分块策略)
======================================================================

  指标                    Naive     Parent-Child    Contextual
  ────────────────────────────────────────────────────────────
  context_recall          0.625        0.875 ◀        0.875 ◀
  context_precision       0.583        0.938 ◀        0.736
  faithfulness            0.846        0.969 ◀        0.981 ◀
  answer_relevancy        0.406        0.454          0.480 ◀
======================================================================

数字解读:

  • context_recall:Naive 0.625 → Parent-Child / Contextual 均达 0.875(+0.250) 最显著的提升。Naive 分块时,一个完整的概念被切成多个小 chunk,top-4 未必能把所有相关 chunk 都捞出来;Parent-Child 返回大块,信息更完整;Contextual Retrieval 的语义增强让检索更精准,也达到相同效果。

  • context_precision:Naive 0.583 → Parent-Child 0.938(+0.355) Parent-Child 的排序质量提升极为显著。原因:小块 embedding 语义更聚焦,相关文档能稳定排在前面;Contextual Retrieval 也有提升(0.736),但不如 Parent-Child 明显。

  • faithfulness:Naive 0.846 → Parent-Child 0.969 / Contextual 0.981 上下文质量改善后,LLM 幻觉率随之下降。三个核心指标的联动效应再次印证:排序和召回的改善会传递到生成质量上。

  • answer_relevancy:三者相近,Contextual 略优(0.480 vs Naive 0.406) 回答直接性有小幅改善,整体变化不大。


两种方案的适用场景

维度 Parent-Child Contextual Retrieval
解决的问题 小块检索 vs 大块返回的矛盾 Chunk 孤立导致语义缺失
索引成本 低(只需多存一份父文档) 高(每个 chunk 调用一次 LLM)
查询延迟 与 Naive 相同 与 Naive 相同(成本在索引阶段)
效果优势 context_precision 提升更显著 对语义复杂文档效果更好
适合场景 通用场景,知识库体量任意 文档逻辑性强、段落间依赖多
不适合场景 文档本身没有层级结构 超大知识库(索引成本高)

实用建议:

  • 大多数场景先试 Parent-Child,成本低,提升明显
  • 文档类型为技术手册、学术论文、长篇报告等,段落间依赖强,可以叠加 Contextual Retrieval
  • 两者也可以组合:Parent-Child + Contextual(子 chunk 加上上下文描述),效果会更好,但索引成本更高

完整代码

代码已开源:

github.com/chendongqi/...

核心文件:

  • advanced_chunking.py --- 三种分块策略的完整对比实验

运行方式:

bash 复制代码
git clone https://github.com/chendongqi/llm-in-action
cd 12-advanced-chunking
cp .env.example .env   # 填入 Embedding API Key 和 LLM API Key
pip install -r requirements.txt
python advanced_chunking.py

小结

本文通过代码实验对比了三种分块策略:

  1. Naive Chunking------简单直接,但小块检索和大块生成的矛盾无法解决,context_recall 只有 0.625
  2. Parent-Child------用小块检索、大块返回,context_recall 和 context_precision 双双大幅提升,是最具性价比的升级方案
  3. Contextual Retrieval------LLM 为每个 chunk 生成上下文描述,从 embedding 层面提升语义质量,对逻辑密集型文档效果尤佳

核心结论:分块不只是切割,更是信息组织策略。检索时需要什么(精准匹配),生成时需要什么(完整上下文),这两个问题要分开回答,而不是强行用同一个 chunk 大小折中。


参考资料

相关推荐
百胜软件@百胜软件1 小时前
对话益珲丨2026战略重塑:百胜E3C中台不做“记账工具”,要做品牌增长的“合伙人”
人工智能·零售数字化·数智中台·珠宝行业
极欧互联1 小时前
2026素材网站推荐排行 商用/自媒体/影视后期专用
大数据·人工智能·媒体
GOWIN革文品牌咨询1 小时前
机器人企业品牌语言体系怎么搭建:一句话定位、产品逻辑与解决方案表达
人工智能·机器人
techdashen1 小时前
Unweight:Cloudflare 如何在不损失精度的情况下把大模型压缩 22%
网络·人工智能
前端不太难1 小时前
AI 能力如何变成鸿蒙 App 的基础设施
人工智能·状态模式·harmonyos
龙山云仓1 小时前
无忧智脑-让企业拥抱智能,让管理回归简单
人工智能·深度学习·机器学习
2501_933329551 小时前
Infoseek数字公关AI中台技术解析:基于DeepSeek+NLP的全网舆情监测与智能处置系统
人工智能·架构·数据库开发
QFIUNE1 小时前
【文献阅读】化学空间边缘的分子深度学习
论文阅读·人工智能·笔记·深度学习
新新学长搞科研1 小时前
【最新】2026年能源方向学术会议征稿/交流资讯
人工智能·功能测试·计算机视觉·自动化·能源·新能源·材料工程