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
                │                   │
                └─────────┬─────────┘
                          │
                    【检索流程】
                    查询 → 子文档 → 父文档
相关推荐
为思念酝酿的痛4 小时前
POSIX信号量
linux·运维·服务器·后端
小羊在睡觉4 小时前
力扣84. 柱状图中最大的矩形
后端·算法·leetcode·golang·go
swipe5 小时前
Neo4j + Graph RAG 医疗知识图谱工程实践:患者教育问答真正需要的是“关系可追溯”
后端·langchain·llm
源码宝6 小时前
MES系统源码:Java8 + SpringBoot2.7 + MySQL8 + Redis,后端源码清爽易扩展
java·后端·源码·springboot·mes系统·源码二开·mes源码
金銀銅鐵6 小时前
[Java] 如何理解 class 文件中方法的 descriptor?
java·后端
村口张大爷6 小时前
05 — 分层架构与依赖倒置
后端·架构·系统架构
Jasonakeke8 小时前
SpringBoot自动配置原理揭秘
java·spring boot·后端
IT_陈寒9 小时前
Vite热更新失灵?你可能漏了这个配置
前端·人工智能·后端
uzong9 小时前
面试官:如何做好架构设计
后端·架构
Cosolar9 小时前
QwenPaw Agent 实现原理深度剖析
后端·面试·架构