支持私有云部署
AI知识库

53AI知识库

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


LangChain进阶指南:RAG实践总结

发布日期:2025-03-17 06:48:55 浏览次数: 1554 来源:爱康技术团队
推荐语

探索RAG在提升语言模型准确性和可靠性方面的突破性进展。

核心内容:
1. RAG解决LLMs“幻觉”问题的原理和优势
2. RAG的模型架构和工作流程解析
3. RAG在实际应用中的潜力和挑战

杨芳贤
53A创始人/腾讯云(TVP)最具价值专家

为什么要使用RAG?


当下领先的大语言模型(LLMs)通过大规模数据训练来掌握广泛的普遍知识,这些知识存储在其神经网络的权重中。然而,如果要求LLM生成涉及其训练数据以外的知识(如最新、专有或特定领域信息),就会出现事实上的错误(称为"幻觉")。


通过使用微调(fine-tuning)或是检索增强生成(RAG)方式都可解决这一问题。但通常使用微调通常需要耗费大量计算资源、成本高昂,且需要丰富的微调经验。此外Fine tuning需要代表性的数据集且量也有一定要求,且Fine tuning 并不适合于在模型中增加全新的知识或应对那些需要快速迭代新场景的情况。本文介绍的是另外一种方式,通过RAG的方式检索数据信息,这种方式成本低且可以快速地实现。


检索增强生成(RAG)是一个概念,它旨在为大语言模型(LLM)提供额外的、来自外部知识源的信息,提高 AI 应用回复的质量及可靠性。这样,LLM 在生成更精确、更贴合上下文的答案的同时,也能有效减少产生误导性信息的可能。RAG主要解决了 LLM 常见挑战,如提供虚假信息、过时信息和非权威信息等问题。


在论文《知识密集型 NLP 任务的检索增强生成》中,介绍了一种新的技术。检索增强生成(Retrieval-Augmented Generation,RAG)。这篇论文提出了一种新的模型架构,通过结合检索和生成两个阶段,解决了知识密集型NLP任务中的挑战。RAG有效利用外部知识库来增强模型性能,通过这种方式可以让LLM可以更易于查询到外部知识信息。

RAG和LLM之间存在着互补关系。RAG可以被视为一种扩展了功能的LLM,它通过引入额外的检索步骤,使得LLM能够有效利用外部知识。这两种技术结合使用,可以在许多复杂的自然语言处理任务中取得更好的效果,为开发更强大的NLP系统提供了新的可能性。

RAG的工作流程


  • 检索: 当接收到用户查询时,使用检索索引找到最相关的文档。具体来讲,对用户输入的查询信息Embedding转化为向量,再到向量数据库中检索其他匹配的上下文信息。通过这种相似性搜索,可以找到向量数据库中最匹配的相关数据。


  • 增强: 将向量数据库中检索到的信息与用户查询信息放到我们自定义的提示模板中。

  • 生成: 最后将上面经过检索以及增强后的提示内容输入到LLM中,LLM根据上述信息生成最终结果。


其中向量数据库里存储的是外部知识,通过嵌入模型将非结构化数据存储向量数据库中。具体流程如下图所示:
  • 加载:加载指定的数据,不同的文件可以通过不同的文档加载器完成。


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


  • 嵌入:利用Embedding技术可以将高维度的数据(例如文字、图片、 音频)映射到低维度空间,即把图片、音频和文字最终转化为向量来表示。其中,向量是一组数值,可以表示一个点在多维空间中的位置。


  • 存储:需要一个向量数据库用来存储和索引分割后的向量,便于日后快速的检索数据。

    基于 LangChain 实现的检索增强生成方法
LangChain 是一个开源的工具包,目标是帮助开发者快速构建 AI 应用程序。它提供了一系列的功能,如模型托管、数据管理和任务自动化等。通过LangChain我们可以快速地搭建一个RAG应用。


在这一部分,我们将展示如何利用Python 结合 OpenAI 的大语言模型、Weaviate的向量数据库以及 OpenAI 的嵌入模型来实现一个检索增强生成(RAG)流程。在这个过程中,我们将使用 LangChain 来进行整体编排。


  • Part 1 将外部知识写入向量数据库


准备好向量数据库,向量数据库(Vector Database)是一种以向量为基础的数据存储和查询系统,它利用向量空间模型来表示和查询数据。通过向量数据库将我们自己指定的资料转换为向量并写入到数据库。具体步骤如下:
   i. 收集数据并将其加载进系统


  ii. 将文档进行分块处理

 iii. 对分块内容进行嵌入,并存储这些块

  • 首先,加载指定的数据。数据类型支持文本、PDF、Word、Excel、CSV、HTML等不同的文件。下面例子中使用TextLoader来加载文本。针对不同文件类型可以使用不同的加载器,如CSVLoader加载CSV文件、WebBaseLoader通过URL方式加载网页数据,而PDF也有许多加载方式如PDFMinerLoader是其中之一。

import requestsfrom langchain.document_loaders import TextLoaderurl ="https://raw.githubusercontent.com/langchain-ai/langchain/master/docs/docs/modules/state_of_the_union.txt"res = requests.get(url)withopen("state_of_the_union.txt","w")as f:f.write(res.text)loader = TextLoader('./state_of_the_union.txt')documents = loader.load()
  • 其次,需要对文档进行分块。分块(chunking)是将大块文本分解成小段的过程。分块可以帮助我们优化从向量数据库被召回的内容的准确性。LangChain 也提供了许多文本分割工具,对于这个的示例,可以使用 CharacterTextSplitter来进行分割。设置片段大小 chunk_size 为 500,并且设置重叠token数量 chunk_overlap 为 50,以确保文本块之间的连贯性。



from langchain.text_splitter import CharacterTextSplittertext_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)chunks = text_splitter.split_documents(documents)
  • 最后,通过Embedding技术将其转为向量并存储这些文本块 。为了实现让LLM理解文件中的内容,需要为分块后的数据Embedding,并将它们存储起来。有多种方式可以Embedding,在本例中使用 OpenAI 的嵌入模型;最后使用Weaviate 向量数据库将向量保存。在LangChain中通过执行 .from_documents() 操作,就可以自动将这些块向量填充进向量数据库中。

from langchain.embeddings import OpenAIEmbeddingsfrom langchain.vectorstores import Weaviateimport weaviatefrom weaviate.embedded import EmbeddedOptionsclient = weaviate.Client(embedded_options = EmbeddedOptions())vectorstore = Weaviate.from_documents(client = client,documents = chunks,embedding = OpenAIEmbeddings(),by_text =False)
  • Part 2 使用向量库中的数据检索用户提出的问题


  • 检索:在前面已经将文件转为向量数据并写入到向量数据库中,接下来就可以将它设定为检索组件。这个组件能够根据用户查询与已嵌入的文本块之间的语义相似度,来检索出额外的上下文信息。

retriever = vectorstore.as_retriever()
  • 增强:准备一个提示模板,通过预设的提示信息,再加上检索后的上下文信息来增强原始的提示。

from langchain.prompts import ChatPromptTemplatetemplate ="""You are an assistant for question-answering tasks.Use the following pieces of retrieved context to answer the question.If you don't know the answer, just say that you don't know.Use three sentences maximum and keep the answer concise.Question: {question}Context: {context}Answer:"""prompt = ChatPromptTemplate.from_template(template)print(prompt)
  • 生成:通过RAG链,可以通过将检索器、提示模板与LLM 相结合。下面的RAG链会对用户提出的问题先进行向量检索,再将检索后的数据和提示模板结合,最终LLM根据上述信息生成答案。


from langchain.chat_models import ChatOpenAIfrom langchain.schema.runnable import RunnablePassthroughfrom langchain.schema.output_parser import StrOutputParserllm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)rag_chain =({"context": retriever,"question": RunnablePassthrough()}| prompt| llm| StrOutputParser())query ="What did the president say about Justice Breyer"rag_chain.invoke(query)
其中rag_chain是核心部分,在这一步中构建了使用GPT-3.5大模型,并通过prompt增强问题后去向量数据库中检索答案的RAG链。


上面例子中,我们对LLM提出问题:”‌总统对布雷耶大法官是如何评价的“。LLM通过向量库检索后回复:
"总统对布雷耶法官的服务表示感谢,并赞扬了他对国家的贡献。"


"总统还提到,他提名了法官凯坦吉·布朗·杰克逊来接替布雷耶法官,以延续后者的卓越遗产。"




总结

在基于 LLM实现的问答系统中使用 RAG 有三方面的好处:


  1. 确保 LLM 可以回答最新,最准确的内容。并且用户可以访问模型内容的来源,确保可以检查其声明的准确性并最终可信。


  2. 通过将 LLM建立在一组外部的、可验证的事实数据之上,该模型将信息提取到其参数中的机会更少。这减少了 LLM 泄露敏感数据或“幻觉”不正确或误导性信息的机会。


  3. RAG 还减少了用户根据新数据不断训练模型并随着数据的变化更新训练参数的需要。通过这种方式企业可以减低相关财务成本。


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

产品:场景落地咨询+大模型应用平台+行业解决方案

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

联系我们

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

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询