概述
本教程将使您熟悉LangChain的文档加载器、嵌入和向量存储抽象。这些抽象旨在支持从(向量)数据库和其他来源检索数据,以便与LLM工作流程集成。对于需要检索数据作为模型推理一部分的应用程序,例如检索增强生成(RAG)或检索增强生成,它们非常重要。 在这里,我们将构建一个在PDF文档上的搜索引擎。这将使我们能够检索与输入查询相似的PDF中的段落。指南还包括在搜索引擎之上的最小化RAG实现。概念
本指南专注于文本数据的检索。我们将涵盖以下概念:安装
安装
本教程需要langchain-community 和 pypdf 包:
LangSmith
许多您使用LangChain构建的应用程序将包含多个步骤,以及多次调用LLM调用。 随着这些应用程序变得越来越复杂,能够检查您的链或智能体内部究竟发生了什么变得至关重要。 要做到这一点,最佳方式是使用LangSmith。 在您通过上述链接注册后,请确保设置环境变量以开始记录跟踪信息:1. 文档和文档加载器
LangChain 实现了一个 文档 抽象,旨在表示一个文本单元及其相关元数据。它有三个属性:page_content:表示内容的字符串;metadata:包含任意元数据的字典;id:(可选)文档的字符串标识符。
metadata 属性可以捕获有关文档来源、与其他文档的关系以及其他信息。请注意,一个单独的 Document 对象通常代表一个较大文档的一部分。
我们可以根据需要生成示例文档:
加载文档
让我们将一个PDF文件加载成一系列Document对象。这是一个示例PDF——耐克2023年的10-K文件。我们可以查阅LangChain文档了解可用的PDF文档加载器。
PyPDFLoader 在每页PDF中加载一个 Document 对象。对于每个对象,我们可以轻松访问:
- 页面的字符串内容;
- 包含文件名和页码的元数据。
分割
为了信息检索和下游问答的目的,一个页面可能是一个过于粗略的表示。我们的最终目标将是检索Document对象,这些对象能够回答输入查询,进一步拆分我们的PDF将有助于确保文档相关部分的含义不会被周围文本“冲淡”。
我们可以使用 文本分割器 来实现这个目的。在这里,我们将使用一个简单的基于字符的文本分割器。我们将把我们的文档分割成1000个字符的块,块与块之间有200个字符的重叠。重叠有助于减少将一个句子与其相关的重要上下文分开的可能性。我们使用 RecursiveCharacterTextSplitter,它将递归地使用常见的分隔符(如换行符)来分割文档,直到每个块达到适当的大小。这是通用文本用例推荐的文本分割器。
我们将 add_start_index=True 设置为保留每个分割文档在初始文档中开始的字符索引,作为元数据属性“start_index”。
2. 嵌入
向量搜索是存储和搜索非结构化数据(如非结构化文本)的一种常见方式。其基本思想是存储与文本相关联的数值向量。给定一个查询,我们可以将其嵌入为一个相同维度的向量,并使用向量相似度度量(如余弦相似度)来识别相关文本。 LangChain 支持来自 数十个提供商 的嵌入。这些模型指定了如何将文本转换为数值向量。让我们选择一个模型:3. 向量存储
LangChain 向量存储对象包含向存储中添加文本和Document对象的方法,并使用各种相似度指标查询它们。它们通常使用嵌入模型初始化,这些模型决定了文本数据如何转换为数值向量。
LangChain 包含一套 集成,支持不同的向量存储技术。一些向量存储由提供商托管(例如,各种云提供商),并需要特定的凭证才能使用;一些(如 Postgres) 在独立的基础设施中运行,可以本地运行或通过第三方运行;其他可以在内存中运行,适用于轻量级工作负载。让我们选择一个向量存储:
实例化我们的向量存储后,我们现在可以索引文档了。
VectorStore,我们就可以对其进行查询。VectorStore 包含以下查询方法:
- 同步和异步;
- 通过字符串查询和通过向量;
- 带有和没有返回相似度分数;
- 通过相似度和@[最大边际相关性][VectorStore.max_marginal_relevance_search](以平衡相似度与查询的多样性,以在检索结果中实现多样性)。
4. 检索器
LangChainVectorStore 对象不继承自 @[Runnable]。LangChain @[Retrievers] 是可运行的,因此它们实现了一套标准方法(例如,同步和异步的 invoke 和 batch 操作)。尽管我们可以从向量存储中构建检索器,但检索器也可以与数据源的非向量存储接口(例如外部API)进行交互。
我们可以自己创建一个简单版本,无需继承 Retriever。如果我们选择想要用来检索文档的方法,我们可以轻松地创建一个可运行的版本。下面我们将围绕 similarity_search 方法构建一个:
as_retriever 方法,该方法将生成一个检索器,具体为 VectorStoreRetriever。这些检索器包括特定的 search_type 和 search_kwargs 属性,用于标识要调用底层向量存储的哪些方法,以及如何参数化它们。例如,我们可以用以下方式复制上述操作:
VectorStoreRetriever 支持以下搜索类型:"similarity"(默认)、"mmr"(最大边际相关性,如上所述)和"similarity_score_threshold"。我们可以使用后者通过相似度分数来阈值化检索器输出的文档。
智能体可以轻松集成到更复杂的应用中,例如将给定问题与检索到的上下文结合成一个用于LLM的提示的检索增强生成(RAG)应用。要了解更多关于构建此类应用的信息,请查看RAG教程。