LangChain Parent Document Retriever (父文档检索器)

LangChain Parent Document Retriever (父文档检索器) 学习总结


知识要点

1️⃣ 这是什么

父文档检索器是 LangChain 中用于平衡检索精度和上下文完整性的高级检索器。 它通过将文档分成两个层级来解决 RAG 系统中的核心矛盾:

  • 小文档块:检索更精准,但上下文信息不足
  • 大文档块:上下文完整,但检索不够精准

父文档检索器通过"存储小块,检索大块"的策略,实现了两者的平衡。

工作原理:

  1. 将文档分成小块(子文档),用于向量检索
  2. 将文档分成大块(父文档),用于返回完整上下文
  3. 检索时先找到匹配的子文档,然后返回对应的父文档

2️⃣ 有什么用

主要用途:

  • 需要高精度检索同时保留完整上下文的场景
  • 长文档的智能检索(如技术文档、法律文书)
  • 构建需要提供详细信息的问答系统
  • 解决 RAG 应用中检索粒度与上下文的矛盾
  • 电商产品详情、API 文档等结构化内容的检索

3️⃣ 示例代码

模式一:仅子分割器(原始文档作为父文档)

python 复制代码
import dotenv
import weaviate
from langchain_classic.retrievers import ParentDocumentRetriever
from langchain_classic.storage import LocalFileStore
from langchain_community.document_loaders import UnstructuredFileLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_weaviate import WeaviateVectorStore
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
from weaviate.auth import AuthApiKey

dotenv.load_dotenv()

# 1. 加载文档
loaders = [
    UnstructuredFileLoader("./电商产品数据.txt"),
    UnstructuredFileLoader("./项目API文档.md"),
]
docs = []
for loader in loaders:
    docs.extend(loader.load())

# 2. 仅创建子分割器
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,
    chunk_overlap=50,
)

# 3. 创建向量数据库与文档存储
vector_store = WeaviateVectorStore(
    client=weaviate.connect_to_wcs(
        cluster_url="your-cluster-url",
        auth_credentials=AuthApiKey("your-api-key"),
    ),
    index_name="ParentDocument",
    text_key="text",
    embedding=QianfanEmbeddingsEndpoint(),
)
byte_store = LocalFileStore("./parent-document")

# 4. 创建父文档检索器
retriever = ParentDocumentRetriever(
    vectorstore=vector_store,
    byte_store=byte_store,
    child_splitter=text_splitter,
)

# 5. 添加文档
retriever.add_documents(docs, ids=None)

# 6. 检索并返回内容
search_docs = retriever.invoke("分享关于LLMOps的一些应用配置")
print(search_docs)

模式二:父子分割器(推荐)

python 复制代码
import dotenv
import weaviate
from langchain_classic.retrievers import ParentDocumentRetriever
from langchain_classic.storage import InMemoryStore
from langchain_community.document_loaders import UnstructuredFileLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_weaviate import WeaviateVectorStore
from langchain_community.embeddings import QianfanEmbeddingsEndpoint
from weaviate.auth import AuthApiKey

dotenv.load_dotenv()

# 1. 加载文档
loaders = [
    UnstructuredFileLoader("./电商产品数据.txt"),
    UnstructuredFileLoader("./项目API文档.md"),
]
docs = []
for loader in loaders:
    docs.extend(loader.load())

# 2. 创建父子分割器
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)

# 3. 创建向量数据库与文档存储
vector_store = WeaviateVectorStore(
    client=weaviate.connect_to_wcs(
        cluster_url="your-cluster-url",
        auth_credentials=AuthApiKey("your-api-key"),
    ),
    index_name="ParentDocument",
    text_key="text",
    embedding=QianfanEmbeddingsEndpoint(),
)
store = InMemoryStore()

# 4. 创建父文档检索器
retriever = ParentDocumentRetriever(
    vectorstore=vector_store,
    byte_store=store,
    parent_splitter=parent_splitter,
    child_splitter=child_splitter,
)

# 5. 添加文档
retriever.add_documents(docs, ids=None)

# 6. 检索并返回内容
search_docs = retriever.invoke("分享关于LLMOps的一些应用配置")
print(search_docs)

4️⃣ 流程图

text 复制代码
┌─────────────────────────────────────────────────────────┐
│                      原始文档                            │
└─────────────────────────────────────────────────────────┘
                          │
                ┌─────────┴─────────┐
                │                   │
          【父分割器】          【子分割器】
        chunk_size=2000      chunk_size=500
                │                   │
                ▼                   ▼
        ┌───────────┐         ┌───────────┐
        │ 父文档块   │         │ 子文档块   │
        │ (大块)    │◄────────│ (小块)    │
        └───────────┘  关联    └───────────┘
                │                   │
         byte_store          vector_store
                │                   │
                └─────────┬─────────┘
                          │
                    【检索流程】
                    查询 → 子文档 → 父文档
相关推荐
爱勇宝1 小时前
深扒 Anthropic 1680 位工程师简历:应届生几乎没机会,AI 公司最缺的不是博士
前端·后端·程序员
AskHarries1 小时前
工具失败时怎么办:重试、回滚、人工确认和风险提示
后端·程序员
苏三说技术3 小时前
Claude Code从失控到起飞,只用了这些技巧
后端
长栎4 小时前
写 for 循环写了十年,你却从没用过迭代器模式最狠的那一面
后端
LiaCode4 小时前
Redis 在生产项目的使用
前端·后端
用户559822481224 小时前
Docker Compose Down 导致容器数据误删——ext4 日志恢复全记录
后端
LiaCode4 小时前
一天学完 redis 的爽翻版核心知识总结
前端·后端
大刚测试开发实战4 小时前
如何内网穿透访问本地私有化部署的TestHub
前端·后端·github
xiaodaoluanzha4 小时前
迄今為止,最簡單的編程語言 Nolang
前端·后端
Csvn4 小时前
Docker 容器管理入门 — 从镜像到容器编排
后端