ParentDocumentRetriever 通过 分层检索 方式,解决了传统向量搜索容易导致的上下文缺失问题。
它特别适用于长文档处理,能够提高问答系统的检索质量。

在构建基于大语言模型(LLM)的问答系统时,信息检索的准确性和上下文完整性至关重要。

普通的向量检索通常会将文档拆分成较小的片段,并通过相似度搜索找到与用户查询匹配的部分。但这种方法有一个明显的缺点:检索结果往往只是文档的某个片段,容易导致信息不完整,影响最终的答案质量。

这就会碰到一个矛盾:

  • 较小的内容块在检索中提供高精度,将用户查询的具体细节与针对性、相关的内容相匹配。这减少了噪音和无关信息,提高了响应的准确性。

  • 较大的信息块提供了全面的背景,对于需要更广泛理解或本质上复杂的查询是必需的。这些信息块虽然不够精确,但通过涵盖更广泛的信息范围,可以提供更丰富的见解。

主要挑战在于平衡 **详细详细、具体信息(较小块)和更广泛上下文理解(较大块)**的需求。

ParentDocumentRetriever 是 LangChain 提供的一种 分层检索 方式,能够在 子文档中检索,但最终返回完整的 父文档,从而保证上下文的完整性。

这在长文档处理(如法律文件、研究论文、技术文档)等场景下尤为重要。

1. ParentDocumentRetriever 的核心原理

普通的向量数据库检索通常是基于 句子小段文本 进行索引的。这意味着当用户查询时,返回的内容通常是多个小块,而这些片段往往缺乏整体上下文。

例如,在一本书的检索中,普通的向量搜索可能会返回某个段落,但如果该段落依赖于前后的内容,单独提供这一段就可能让用户难以理解。

ParentDocumentRetriever 采用了两级索引的方法。首先,它将长文档拆分成较大的 父文档(Parent Documents),然后再进一步拆分为较小的 子文档(Child Documents),并将子文档存入向量数据库。

第一级:专注于提取更小、更精确的片段,直接针对查询的具体内容。这确保了回应的相关性和针对性。

第二级:专注这些片段所来源的更大父文档。此步骤提供了额外的背景和深度,丰富了响应,提供了更广泛的视角,以支持详细信息。

当用户查询时,检索器先在子文档中搜索相关内容,并根据匹配的子文档找到其对应的父文档,最终返回完整的父文档。

这种方式可以保证用户获得完整的上下文信息,避免答案不连贯的问题。

13-11-13-43-24a538e4f1b08f4f4f6c1b0afcab861f-c34ed3-2

这一方法的最大优势在于,它结合了 小文档的精准搜索长文档的完整上下文,既保证了检索的精确度,又避免了因内容过短而导致的信息缺失。

在实际应用中,ParentDocumentRetriever 可以与 RAG(Retrieval-Augmented Generation) 结合,实现高质量的问答系统。

结合大语言模型基于检索结果生成答案。

检索到的完整父文档会作为上下文输入给 LLM,从而提高答案的准确性。

img

2. ParentDocumentRetriever 的使用

首先,需要加载文档。这里使用 TextLoader 读取一个文本文件,例如 example.txt

"""
Python 3.13
LangChain 0.3
"""
import os

OPENAI_API_KEY = 'hk-iwtbie4a91e427'# 设置OpenAI API密钥
os.environ['OpenAI_API_KEY'] = OPENAI_API_KEY  # 将API密钥设置为环境变量


from langchain.retrievers import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain_chroma import Chroma
from langchain_community.document_loaders import TextLoader
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter

loaders = [
    TextLoader(file_path="../data/西游记1.txt", encoding='utf-8'),
    TextLoader(file_path="../data/西游记2.txt", encoding='utf-8')
]
docs = []
for loader in loaders:
    docs.extend(loader.load())

在加载文档后,接下来需要对文档进行拆分。ParentDocumentRetriever 采用两级拆分方式,因此首先创建 父文档拆分器,然后创建 子文档拆分器

# 创建OpenAI嵌入实例
embeddings = OpenAIEmbeddings(model="text-embedding-3-large", base_url="https://api.openai-hk.com/v1")


# 这个文本分割器用于创建父文档
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000)
# 此文本分割器用于创建子文档。创建比父文档更小的文档。
child_splitter = RecursiveCharacterTextSplitter(chunk_size=400)

接下来,需要创建向量数据库,用于存储子文档的嵌入向量。这里使用 Chroma 作为向量数据库,并使用 OpenAIEmbeddings 进行文本嵌入。

# 用于索引子块的vectorstore
vectorstore = Chroma(
    collection_name="split_parents", embedding_function=embeddings
)
# 父文档的存储层
store = InMemoryStore()

创建 ParentDocumentRetriever 时,需要提供 vectorstore,并指定文档拆分策略。

# 检索小块内容,然后检索它们的父文档。
retriever = ParentDocumentRetriever(
    vectorstore=vectorstore,              # 用于存储小块及其嵌入向量的基础向量存储
    docstore=store,                       # 父文档的存储接口
    child_splitter=child_splitter,        # 用于创建子文档的文本分割器。
    parent_splitter=parent_splitter,      # 用于创建父文档的文本分离器
)
# 将文档添加到 docstore 和 vectorstore.
print("开始处理文档")
retriever.add_documents(docs)

此时,向量数据库已经存储了子文档的嵌入向量,而 ParentDocumentRetriever 也已经准备就绪,可以进行查询。

# 从向量库直接查询关键字,返回小块
sub_docs = vectorstore.similarity_search("赤脚大罗仙")
print(sub_docs)
print("================================")
print("子文档:")
print(sub_docs[0].page_content)
print()

# 从检索器查询相同的关键字,返回父文档
retrieved_docs = retriever.invoke("赤脚大罗仙")

print("父文档:")
print(retrieved_docs[0].page_content)

当用户输入查询时,检索器会在子文档中找到最匹配的内容,然后返回完整的父文档,确保答案的上下文完整。

3. 查询结果

screenshot (10)

4. 应用场景

在实际应用中,ParentDocumentRetriever 适用于各种长文档的处理需求。

例如,在 法律文档分析 中,法律条款往往很长,单独匹配一两个段落可能导致理解不完整,因此可以使用 ParentDocumentRetriever 返回完整的法条,提高法律咨询系统的可靠性。

企业内部知识库 场景下,员工手册、产品文档等往往包含大量信息,用户的查询可能与多个部分相关。使用 ParentDocumentRetriever,可以确保用户获取的内容完整,而不会因为返回碎片化信息而造成困惑。

技术文档,如 API 文档或开发手册,往往结构复杂,多个部分之间有逻辑关联。普通的向量搜索可能只返回部分代码示例或单个 API 说明,但 ParentDocumentRetriever 能够返回完整的上下文,提高开发者的阅读体验。

五. 总结

ParentDocumentRetriever 通过 分层检索 方式,解决了传统向量搜索容易导致的上下文缺失问题。

它特别适用于长文档处理,能够提高问答系统的检索质量。

结合 RAG,它可以与 LLM 进行无缝集成,实现更智能的知识检索和问答。对于希望优化向量搜索质量的开发者来说,它是一个不可或缺的工具。


六. 如何系统学习掌握AI大模型?

AI大模型作为人工智能领域的重要技术突破,正成为推动各行各业创新和转型的关键力量。抓住AI大模型的风口,掌握AI大模型的知识和技能将变得越来越重要。

学习AI大模型是一个系统的过程,需要从基础开始,逐步深入到更高级的技术。

这里给大家精心整理了一份全面的AI大模型学习资源,包括:AI大模型全套学习路线图(从入门到实战)、精品AI大模型学习书籍手册、视频教程、实战学习、面试题等,资料免费分享

1. 成长路线图&学习规划

要学习一门新的技术,作为新手一定要先学习成长路线图方向不对,努力白费

这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。可以说是最科学最系统的学习成长路线。
在这里插入图片描述

2. 大模型经典PDF书籍

书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础(书籍含电子版PDF)

在这里插入图片描述

3. 大模型视频教程

对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识

在这里插入图片描述

4. 2024行业报告

行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

在这里插入图片描述

5. 大模型项目实战

学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

在这里插入图片描述

6. 大模型面试题

面试不仅是技术的较量,更需要充分的准备。

在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

在这里插入图片描述

全套的AI大模型学习资源已经整理打包,有需要的小伙伴可以微信扫描下方CSDN官方认证二维码,免费领取【保证100%免费

Logo

中国智能体开发者社区,聚焦智能体与大模型开发,提供前沿资讯、实用工具链、开源项目及行业案例。通过技术沙龙、开发者大赛等活动,促进经验交流与协作,助力开发者快速构建创新智能应用。

更多推荐