大型 AI 模型能够处理各种主题的文本生成,但模型知识只能基于它们训练的公开可用数据。 如果要构建可以使用私有数据或实时数据进行推理的 AI 应用程序,则需要使用特定信息来增强模型的知识。 检索增强生成 (RAG) 用于检索相关信息并将其插入到模型的输入中。
在本文中,我们将介绍如何使用Langchain开发一个简单的RAG Q&A应用程序。 我们将依次介绍一个典型的问答架构,讨论相关的langchain组件,并展示如何跟踪和理解我们的应用程序。RAG是一种将检索和生成相结合的技术,它允许大型模型在生成文本时利用额外的数据源,从而提高生成的质量和准确性。 RAG的基本流程如下:
首先,给定用户的输入(例如问题或主题),RAG 会从数据源(例如网页、文档或数据库记录)中检索与之相关的一段文本。 这些文本片段称为上下文。 然后,RAG 将用户的输入和检索到的上下文拼接成一个完整的输入,该输入将传递给大型模型,例如 GPT。 此输入通常包含指导模型如何生成所需输出的提示,例如答案或摘要。 最后,RAG 从大型模型的输出中提取或格式化所需的信息,并将其返回给用户。 LangChain是一个专注于大规模应用开发的平台,它提供了一系列的组件和工具,帮助您轻松构建RAG应用。 LangChain提供了以下组件来帮助您构建RAG应用:
DocumentLoader:数据加载器是从数据源加载数据并将其转换为文档对象的对象。 文档对象包含两个属性:page content(str) 和 metadata(dict)。 页面内容是文档的文本内容,元数据是文档的元数据,如标题、作者、日期等。 DocumentsPlitter:文本拆分器是一个对象,可以将一个文档对象拆分为多个较小的文档对象。 这样做的目的是为了方便后续的检索和生成,因为大模型的输入窗口有限,在较短的文本中更容易找到相关信息。 文本嵌入:文本嵌入是将文本转换为嵌入(高维向量)的对象。 文本嵌入可用于衡量文本之间的相似度,从而实现检索的功能。 向量存储:向量存储是可以存储和查询嵌入的对象。 向量内存通常使用一些索引技术(如 faiss 或 annoy)来加速嵌入的检索。 检索器:检索器是一个对象,可以根据文本查询返回相关的文档对象。 检索器的一个常见实现是vectorstoreretriever,它利用向量存储器的相似性搜索功能来实现检索。 ChatModel:聊天模型是一个对象,可以根据一系列输入生成输出消息。 聊天模型通常基于大型模型(如 GPT-3)来实现文本生成功能。 使用LangChain构建RAG应用的一般流程如下:
首先,我们需要加载数据。 我们可以通过使用数据加载器来做到这一点,根据数据源的类型选择正确的数据加载器。 例如,如果我们的数据源是一个网页,我们可以使用 WebBaseLoader,它可以使用 urllib 和 beautifulsoup 来加载和解析网页,返回一个文档对象。 然后,我们需要将文档对象拆分为更小的文档对象。 我们可以使用文本拆分器来实现这一步,根据文本的特点选择合适的文本拆分器。 例如,如果我们的文本是一篇博客文章,我们可以使用 RecursiveCharacterTextsPlitter,它可以递归地使用通用分隔符(如换行符)来拆分文本,直到每个文档对象的大小与它需要的一样好。 接下来,我们需要将文档对象转换为嵌入并将其存储在向量内存中。 我们可以使用文本嵌入器和向量内存来实现这一步,根据嵌入的质量和速度来选择合适的文本嵌入和向量存储器。 例如,如果我们想使用 OpenAI 的嵌入模型和 Chroma 的向量存储器,我们可以使用 OpenAiEmbeddings 和 Chrom**ECTORSTORE。 然后,我们需要创建一个检索器,根据用户的输入检索相关的文档对象。 我们可以使用向量内存检索器来做到这一点 - 将向量内存对象和文本嵌入器对象作为参数传递以创建向量内存检索器对象。 最后,我们需要创建一个对话模型,该模型根据用户的输入和检索到的文档对象生成输出消息。 我们可以使用Langchain提供的聊天模型来实现这一步,并根据模型的性能和成本选择合适的聊天模型。 例如,如果我们想使用 OpenAI 的 GPT-3 模型,我们可以使用 OpenAICHATModel。 以下是使用 Langchain 构建 RAG 应用程序的示例
导入langchain的库。
from langchain import *
加载数据源。
loader = webbaseloader()
doc = loader.load("")
拆分文档对象。
splitter = recursivecharactertextsplitter(max_length=512)
docs = splitter.split(doc)
将文档对象转换为嵌入并将它们存储在矢量内存中。
embedder = openaiembeddings()
vector_store = chrom**ectorstore()
for doc in docs:
embedding = embedder.embed(doc.page_content)
vector_store.add(embedding, doc)
创建检索器。
retriever = vectorstoreretriever(vector_store, embedder)
创建对话模型。
prompt = hub.pull("rlm/rag-prompt")
llm = chatopenai(model_name="gpt-3.5-turbo", temperature=0)
创建 Q&A 应用。
def format_docs(docs):
return "".join(doc.page_content for doc in docs)
rag_chain = (
prompt
llm| stroutputparser()
启动应用程序。
rag_chain.invoke("what is main purpose of xxx.html?")
LangChain和RAG的结合可以带来以下优势:
灵活性:您可以根据自己的需求和数据源选择不同的组件和参数,从而自定义 RAG 应用程序。 您也可以使用自定义组件,只要它们遵循 Langchain 的接口规范即可。 可扩展性:您可以使用Langchain的云服务来部署和运行RAG应用程序,而无需担心资源和性能限制。 您还可以使用 Langchain 的分布式计算能力来加速您的 RAG 应用程序,利用多个节点的并行处理能力。 可视化:您可以使用 Langsmith 可视化 RAG 应用程序的工作流程,查看每个步骤的输入和输出,以及每个组件的性能和状态。 您还可以使用 Langsmith 来调试和优化您的 RAG 应用程序,识别和解决潜在的问题和瓶颈。 LangChain和RAG的组合可以应用于多种场景,例如:
专业问答:您可以使用LangChain和RAG在专业领域(例如医疗保健,法律或金融)构建问答应用程序。 您可以从域中的数据源中检索相关信息,以帮助大型模型回答用户的问题。 例如,您可以从医学文献中搜索疾病诊断和方案,以帮助大型模型回答与医学相关的问题。 文本摘要:您可以使用LangChain和RAG来构建文本摘要应用程序,例如新闻摘要或摘要。 您可以从多个数据源中检索相关文本,以帮助大型模型生成全面的摘要。 例如,您可以从多个新闻**中检索有关同一事件的报道,以帮助大型模型生成全面的摘要。 文本生成:您可以使用LangChain和RAG构建文本生成应用,如诗歌生成或故事生成等。 您可以从不同的数据源中获取灵感,以帮助大型模型生成更有趣、更有创意的文本。 例如,您可以从诗歌、歌词或**中检索相关文本,以帮助大型模型生成诗歌、歌曲或故事。 在本文中,我们介绍了如何使用LangChain开发一个简单的问答应用程序。 我们介绍了RAG的基本概念和优势,并讨论了相关的LangChain组件。 我们还介绍了LangChain和RAG相结合的优势和应用场景。
我们希望本文能帮助您了解LangChain和RAG组合的潜力和价值,并鼓励您尝试使用LangChain和RAG开发自己的应用程序。 如果您有任何问题或建议,请随时与我们联系,我们期待与您的沟通与合作。
参考资料: 1] Langsmith langsmith documentation. langchain. langchain documentation. chroma. chroma vector store.