AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


使用LangChain建立检索增强生成(RAG)系统
发布日期:2024-11-12 13:27:01 浏览次数: 1573 来源:PyTorch研习社



LLM 支持的最强大的应用程序之一是复杂的问答 (Q&A) 聊天机器人。这些应用程序可以回答有关特定源信息的问题。这些应用程序使用一种称为检索增强生成 (RAG) 的技术。


本教程将展示如何基于文本数据源构建一个简单的问答应用程序。在此过程中,我们将介绍典型的问答架构。



什么是 RAG? 




RAG是一种通过附加数据增强 LLM 知识的技术。


LLM 可以推理广泛的主题,但它们的知识仅限于在训练它们的特定时间点之前的公共数据。如果你想构建能够推理私有数据或模型截止日期后引入的数据的 AI 应用程序,则需要使用模型所需的特定信息来增强模型的知识。将适当的信息引入和插入模型提示的过程称为检索增强生成Retrieval Augmented Generation


LangChain 有许多组件旨在帮助构建问答应用程序,以及更普遍的 RAG 应用程序。


注意:这里我们专注于非结构化数据的问答。如果你对结构化数据的 RAG 感兴趣,我将在后续介绍关于通过 SQL 数据进行问答的教程。


典型的 RAG 应用程序有两个主要组件:

  • 索引:从源中提取数据并对其进行索引的管道。这通常是离线进行的。

  • 检索和生成:实际的 RAG 链,它在运行时接受用户查询并从索引中检索相关数据,然后将其传递给模型。


从原始数据到答案的最常见完整序列如下所示:


索引

  1. 加载:首先,我们需要加载数据。这是通过文档加载器完成的。

  2. 拆分:文本拆分器将大型文档拆分成较小的块。这对于索引数据和将其传递到模型中都很有用,因为大块更难搜索,并且不适合模型的有限上下文窗口。

  3. 存储:我们需要某个地方来存储和索引我们的拆分,以便以后可以搜索它们。这通常使用 VectorStore 和 Embeddings 模型来完成。



检索和生成

4. 检索:给定用户输入,使用检索器从存储中检索相关文本块。

5. 生成:ChatModel/LLM 使用包含问题和检索到的数据的提示生成答案。





一些准备工作




首先我们需要设定一下 LLM:


然后我们还需要 embedding model,即嵌入模型:


为了节约成本,我使用了 BGE 系列的开源模型。


接下来我还使用了 Qdrant 向量数据库,你可以参考《Qdrant:使用Rust编写的开源向量数据库&向量搜索引擎》一文简单了解一下。


接下来,我们将按照上面的步骤来学习如何使用 LangChain 搭建一个 RAG 系统。



索引:加载




LangChain 本身提供的 DocumentLoader 不多,我们可以选择社区贡献的 PDF DocumentLoader


可以看到,我们得到了 Document 对象的列表。Document 对象包含 page_content (str) 和元数据 (dict) :


docs 列表的长度就表示 PDF 文档的页数。可以理解为每页一个 Document 对象。


LangChain 官方提供了很多集成的 DocumentLoader:

https://python.langchain.com/docs/integrations/document_loaders/




索引:拆分




许多 LLM 的上下文窗口只有 8-32k。即使现在有超长上下文窗口的 LLM,但是模型也很难在几千字甚至几万字的文档输入中找到信息。


为了解决这个问题,我们将文档拆分成块以进行嵌入和向量存储。这应该有助于我们在运行时仅检索与文章中最相关的部分。


在这种情况下,我们将 Document 对象拆分成 1000 个字符的块,块之间有 200 个字符的重叠。重叠有助于减轻将语句与与其相关的重要上下文分离的可能性。我们使用 RecursiveCharacterTextSplitter,它将使用常用分隔符(如换行符)递归拆分文档,直到每个块的大小合适。这是针对一般文本用例的推荐文本拆分器。


我们设置 add_start_index=True,以便每个拆分文档在初始文档中开始的字符索引保留为元数据属性“start_index”。




索引:存储




现在我们需要索引 13 个文本块,以便我们可以在运行时搜索它们。最常见的方法是使用嵌入模型生成每个文本块内容的嵌入向量,并将这些嵌入向量插入到向量数据库中。当我们想要搜索我们的文本块时,我们首先生成查询的嵌入向量,然后执行某种“相似性”搜索,以识别与我们的查询嵌入向量最相似的文本嵌入向量。最简单的相似性度量是余弦相似性。


初始化完成 vector_store 之后,我们就可以将文本块及其嵌入向量拆入向量数据库中了:


每个文本块都会有一个 ID 关联。




检索和生成:检索




现在让我们编写实际的应用程序逻辑。我们想要创建一个简单的应用程序,它接受用户问题,搜索与该问题相关的文档,将检索到的文档和初始问题传递给模型,并返回答案。


首先,我们需要定义搜索文档的逻辑。LangChain 定义了一个 Retriever 接口,它包装了一个索引,可以根据字符串查询返回相关文档。


最常见的 Retriever 类型是 VectorStoreRetriever,它使用向量存储的相似性搜索功能来促进检索。任何 VectorStore 都可以通过 VectorStore.as_retriever() 轻松转换为 Retriever:




检索和生成:生成




让我们将所有内容放在一起形成一个链,该链接收问题、检索相关文档、构建提示、将其传递到模型并解析输出。


LangChain提供了:

  • create_stuff_documents_chain 指定了将检索到的上下文输入到提示模板和 LLM 中的方法。

  • create_retrieval_chain 添加检索步骤并通过链传播检索到的上下文,并将其与最终答案一起提供。它具有输入键 input,并在其输出中包含输入、上下文和答案。



在问答应用中,向用户展示用于生成答案的来源通常很重要:


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询