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
                │                   │
                └─────────┬─────────┘
                          │
                    【检索流程】
                    查询 → 子文档 → 父文档
相关推荐
zzzll11112 小时前
SpringBoot 入门与实践指南
java·spring boot·后端
newerp3 小时前
Go :结构体嵌入、sort.Interface 与 io.Reader/Writer
后端
SamDeepThinking3 小时前
如何维持缓存的一致性?
后端·面试·程序员
泡海椒3 小时前
还在手动把 Postman 和浏览器的 curl 转成 Java 代码?这个框架让你一键粘贴直接用
后端
用户8181870627463 小时前
第13章 死锁诊断实战
后端
枫叶V3 小时前
Prompt Injection 防不住怎么办?从 Source-Sink 模型设计 Agent 安全边界
后端·agent
用户8181870627463 小时前
第14章 线程池 RejectedExecutionException 与拒绝策略源码
后端
Leo2823 小时前
LangGraph:把 Agent 从“会回答”推进到“可控执行”的工程架构
后端
铁皮饭盒4 小时前
网页端OCR, 加载6mb大小模型, 又快又准, 百度这次真香
前端·后端
程序员-Benothing4 小时前
Java集合:List实现类深度对比
java·开发语言·后端·面试·list