微信扫码
与创始人交个朋友
我要投稿
LLM 支持的最强大的应用程序之一是复杂的问答 (Q&A) 聊天机器人。这些应用程序可以回答有关特定源信息的问题。这些应用程序使用一种称为检索增强生成 (RAG) 的技术。
本教程将展示如何基于文本数据源构建一个简单的问答应用程序。在此过程中,我们将介绍典型的问答架构。
什么是 RAG?
RAG是一种通过附加数据增强 LLM 知识的技术。
LLM 可以推理广泛的主题,但它们的知识仅限于在训练它们的特定时间点之前的公共数据。如果你想构建能够推理私有数据或模型截止日期后引入的数据的 AI 应用程序,则需要使用模型所需的特定信息来增强模型的知识。将适当的信息引入和插入模型提示的过程称为检索增强生成(Retrieval Augmented Generation)。
LangChain 有许多组件旨在帮助构建问答应用程序,以及更普遍的 RAG 应用程序。
注意:这里我们专注于非结构化数据的问答。如果你对结构化数据的 RAG 感兴趣,我将在后续介绍关于通过 SQL 数据进行问答的教程。
典型的 RAG 应用程序有两个主要组件:
索引:从源中提取数据并对其进行索引的管道。这通常是离线进行的。
检索和生成:实际的 RAG 链,它在运行时接受用户查询并从索引中检索相关数据,然后将其传递给模型。
从原始数据到答案的最常见完整序列如下所示:
索引
加载:首先,我们需要加载数据。这是通过文档加载器完成的。
拆分:文本拆分器将大型文档拆分成较小的块。这对于索引数据和将其传递到模型中都很有用,因为大块更难搜索,并且不适合模型的有限上下文窗口。
存储:我们需要某个地方来存储和索引我们的拆分,以便以后可以搜索它们。这通常使用 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+中大型企业
2024-11-13
只需8步,手把手教你用LangGraph创建AI智能体
2024-11-13
使用 LangChain 建立一个会话式的 RAG Agent 系统
2024-11-12
一文深度了解Agent智能体以及认知架构
2024-11-11
Qwen-Agent 核心点说明
2024-11-11
吴恩达分享五个AI趋势,重点谈了多AI代理的美好前景
2024-11-11
使用 LangChain 构建一个 Agent(智能体/代理)
2024-11-10
使用 LangChain 构建一个有记忆的聊天机器人
2024-11-06
聊聊从 0-1 搭建垂类Agent平台的总结与思考
2024-08-18
2024-04-08
2024-06-03
2024-04-08
2024-04-17
2024-06-24
2024-04-12
2024-07-01
2024-04-10
2024-04-11
2024-10-30
2024-10-11
2024-08-18
2024-08-16
2024-08-04
2024-07-29
2024-07-28
2024-07-27