RAG实战案例:如何基于 LangChain 实现智能检索生成系统

news2024/11/23 15:28:26

在人工智能领域,如何有效结合大型语言模型(LLM)的常识性知识与特定的专有数据,一直是业界探索的热点。微调(Fine-tuning)与检索增强生成(Retrieval-Augmented Generation,简称RAG)两种方法各有千秋,且都对此问题有着不可忽视的贡献。

本文将重点介绍RAG的理论基础,并展示如何利用LangChain、GPT大模型以及Weaviate矢量数据库搭建一个简易的RAG流程。

什么是检索增强生成

检索增强生成 (RAG) 是一种使用来自私有或专有数据源的信息来辅助文本生成的技术。它将检索模型(设计用于搜索大型数据集或知识库)和生成模型(例如大型语言模型 (LLM),此类模型会使用检索到的信息生成可供阅读的文本回复)结合在一起。

通过从更多数据源添加背景信息,以及通过训练来补充 LLM 的原始知识库,检索增强生成能够提高搜索体验的相关性。这能够改善大型语言模型的输出,但又无需重新训练模型。额外信息源的范围很广,从训练 LLM 时并未用到的互联网上的新信息,到专有商业背景信息,或者属于企业的机密内部文档,都会包含在内。

RAG 对于诸如回答问题和内容生成等任务,具有极大价值,因为它能支持生成式 AI 系统使用外部信息源生成更准确且更符合语境的回答。它会实施搜索检索方法(通常是语义搜索或混合搜索)来回应用户的意图并提供更相关的结果。

但问题在于,尽管最先进的LLM经过大量数据训练,拥有广泛的常识性知识,但在需要生成训练数据之外的知识时,如最新、专有或特定领域信息时,LLM可能会出现不准确的情况。以下就是一个典型的例子:

问题:最新的华为Mate手机有哪些创新功能?

回答:抱歉,但我无法访问实时信息,我的知识只更新到2023年初。因此,如果华为Mate系列手机在那之后发布了新的型号或功能,我将无法为您提供具体信息。为了获取最新信息,我建议您查看最新的新闻资源或华为的官方声明。

因此,如何将LLM的常识与其他背景知识有效结合,以生成更准确、更符合实际情况的答案,成为了一个关键问题。这样才能帮助 LLM 生成更准确、更符合语境的补全,同时减少幻觉。

解决方案

传统上,我们通过微调来使神经网络适应特定领域或信息。这种方法虽然有效,但同时也存在计算资源消耗大、成本高昂且技术要求高等问题。因此,灵活适应不断变化的信息成为了一个挑战。

2020年,Lewis 等人在论文《知识密集型 NLP 任务的检索增强生成》(Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks) [4] 中,提出了一种更为灵活的技术——检索增强生成(Retrieval-Augmented Generation,RAG)。该研究将生成模型与检索模块结合起来,能够从易于更新的外部知识源中获取额外信息。

用一个简单的比喻来说, RAG 对大语言模型(Large Language Model,LLM)的作用,就像开卷考试对学生一样。在开卷考试中,学生可以带着参考资料进场,比如教科书或笔记,用来查找解答问题所需的相关信息。开卷考试的核心在于考察学生的推理能力,而非对具体信息的记忆能力。

同样地,在 RAG 中,事实性知识与 LLM 的推理能力相分离,被存储在容易访问和及时更新的外部知识源中,具体分为两种:

  • 参数化知识(Parametric knowledge): 模型在训练过程中学习得到的,隐式地储存在神经网络的权重中。
  • 非参数化知识(Non-parametric knowledge): 存储在外部知识源,例如向量数据库中。

(顺便提一下,这个贴切的比喻并非我首创,最早是在 Kaggle 的 LLM 科学考试竞赛中,由 JJ 提出的。)

下面是 RAG 工作流程的示意图:

检索增强生成的工作流程

  1. 检索: 首先,我们需要进行的是检索过程。在这个阶段,我们利用用户的查询内容,从外部知识源获取相关信息。具体来说,就是将用户的查询通过嵌入模型转化为向量,这样就可以与向量数据库中的其他上下文信息进行比对。通过这种相似性搜索,我们可以找到向量数据库中最匹配的前k个数据。
  2. 增强:接下来,我们进入增强阶段。在这个阶段,我们将用户的查询和检索到的额外信息一起嵌入到一个预设的提示模板中。这个过程的目的是为了提供更丰富、更具上下文的信息,以便于后续的生成过程
  3. 生成: 最后,我们进行生成过程。在这个阶段,我们将经过检索增强的提示内容输入到大语言模型(LLM)中,以生成所需的输出。这个过程是RAG的核心,它利用了LLM的强大生成能力,结合了前两个阶段的信息,生成了准确、丰富且与上下文相关的输出。

在大语言模型(LLM)的应用中,检索增强生成(RAG)的工作流程是一个结构化的过程,它通过检索、增强和生成三个阶段,使得大语言模型(LLM)能够更好地理解和响应用户的查询,提供更准确、更具上下文的输出。

基于 LangChain 实现 RAG

今天我们来一起解读如何利用Python、OpenAI的大型语言模型(LLM)、Weaviate向量数据库以及OpenAI的嵌入模型,通过LangChain构建一个RAG系统。以下是步骤的简明扼要的概述:

首先,我们需要做的是环境准备工作。确保您的环境中已经安装了以下Python库:

  • LangChain:负责整个流程的编排。
  • OpenAI:提供嵌入模型和LLM服务。
  • Weaviate-Client:用于操作向量数据库。

同时,您需要在项目根目录下的.env文件中配置好环境变量。为了获取OpenAI的API密钥,您需要先注册OpenAI账户,并在API密钥页面生成新的密钥。

!pip install langchain openai weaviate-client

另外,你需要在项目的根目录下的 .env 文件中设置相关的环境变量。要获取 OpenAI 的 API 密钥,你需要注册 OpenAI 账户,并在 API 密钥 页面中选择“创建新的密钥”。

OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"

完成这些设置后,运行下面的命令来加载你所设置的环境变量。

import dotenv
dotenv.load_dotenv()

准备步骤

首先,我们需要建立一个向量数据库。这个数据库将作为我们的外部知识源,包含了所有必要的额外信息。为了填充这个数据库,我们需要遵循以下步骤:

收集数据并将其加载进系统

在这个阶段,我们首先需要收集并加载数据。这里以《华为新款手机有什么功能_2023华为手机上市新机型》为例,我们可以利用 LangChain 提供的众多 DocumentLoader 之一来加载这些数据。这里的 Document 是一个包含文本和元数据的字典,为了加载文本,我们可以使用 LangChain 的 TextLoader 来加载文本。

import requests
from langchain.document_loaders import TextLoader

url = "https://myzhengyuan.com/post/93853.html"
res = requests.get(url)
with open("93853.html", "w") as f:
    f.write(res.text)

loader = TextLoader('./93853.html')
documents = loader.load()

对文档进行分块处理

由于原始状态下的 Document 可能过长,无法适应大语言模型(LLM)的上下文窗口,所以我们需要将其分成更小的部分。LangChain 内置了许多用于此目的的文本分割器。在这个简单的示例中,我们可以使用CharacterTextSplitter,设置chunk_size约为500和chunk_overlap约为50,以保持块之间的文本连续性。

from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = text_splitter.split_documents(documents)

对分块内容进行嵌入并存储块

最后,我们需要为每个块生成向量嵌入,并将它们与其嵌入一起存储。为了生成向量嵌入,我们可以使用OpenAI的嵌入模型。同时,我们可以使用 Weaviate 向量数据库来存储这些嵌入。通过调用.from_documents()方法,向量数据库会自动填充这些块。

from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Weaviate
import weaviate
from weaviate.embedded import EmbeddedOptions

client = weaviate.Client(
  embedded_options = EmbeddedOptions()
)

vectorstore = Weaviate.from_documents(
    client = client,    
    documents = chunks,
    embedding = OpenAIEmbeddings(),
    by_text = False
)

第 1 步:检索

首先,我们需要在向量数据库中填充数据,然后定义一个检索器组件。这个检索器会根据用户的查询和嵌入块之间的语义相似度,为我们提供额外的上下文信息。

retriever = vectorstore.as_retriever()

第 2 步:增强

接下来,我们需要使用检索到的上下文信息来增强我们的提示。为此,我们需要准备一个提示模板。在LangChain中,我们可以使用ChatPromptTemplate来创建一个提示模板。这个模板会告诉LLM如何使用检索到的上下文来回答问题。如果LLM不知道答案,它会说出“我不知道”。我们要求LLM的答案尽可能简洁,最多使用三个句子。在Python中,我们可以这样实现:

from langchain.prompts import ChatPromptTemplate

template = """你是问答任务助手。使用以下检索到的上下文片段来回答问题。如果你不知道答案,就说你不知道。最多使用三个句子,保持答案简洁。
Question: {question} 
Context: {context} 
Answer:
"""
prompt = ChatPromptTemplate.from_template(template)

print(prompt)

第三步:生成

最后,我们需要构建一个RAG流程链条,将检索器、提示模板和LLM连接起来。定义好RAG链后,我们就可以调用它进行生成。

from langchain.chat_models import ChatOpenAI
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import StrOutputParser

llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

rag_chain = (
    {"context": retriever,  "question": RunnablePassthrough()} 
    | prompt 
    | llm
    | StrOutputParser() 
)

query = "最新的华为Mate手机有哪些创新功能?"
rag_chain.invoke(query)

输出结果如下:

华为Mate手机的创新功能包括:
1. 先进的处理器和大内存,适合处理复杂任务和大型应用程序
2. 高像素的多摄像头系统,能拍摄高质量照片和视频
3. 支持快速充电和无线充电技术
4. 5G网络支持
5. 流线型设计的双曲面屏幕、高刷新率和高清分辨率
6. 搭载最新的麒麟芯片,提供更快的运行速度和更高的能效比
7. 超级感知影像系统、超级快充技术、智能语音助手等功能

2023年华为上市的新机型包括Hi畅享60S、nova 11 SE、Mate 60系列、nova 12系列等。2022年上市的新机型有mate50、mate50Pro、mate50Pro+和Mate50 RS。

我们可以看到基于这个示例生成的 RAG 管道,如下所示:

总结

本文详细介绍了检索增强生成(RAG)的概念,并演示了如何利用Python实现RAG流程,该流程利用了OpenAI的大型语言模型(LLM)、Weaviate矢量数据库和OpenAI嵌入模型,并通过LangChain进行编排。通过本文的介绍,我们可以看到RAG为解决LLM在处理特定、最新和专有信息方面的不足提供了一个有效且灵活的方法。RAG的出现为大型语言模型提供了额外的、来自外部知识源的信息,使其在生成更精确、更贴合上下文的答案的同时,也能有效减少产生误导性信息的可能。通过Python的实际示例,读者可以清晰地了解RAG的工作原理和实际应用。

References

[1]. Retrieval-augmented generation (RAG)

https://python.langchain.com/docs/use_cases/question_answering/

[2]. Retrieval Augmented Generation (RAG): The Solution to GenAI Hallucinations

https://www.pinecone.io/learn/retrieval-augmented-generation/

[3]. LangChain for LLM Application Development

https://www.deeplearning.ai/short-courses/langchain-for-llm-application-development/

[4]. Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks

https://arxiv.org/abs/2005.11401

[5]. Open Book LLM Science Exam

https://www.kaggle.com/code/jjinho/open-book-llm-science-exam

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1327331.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

5 分钟内搭建一个免费问答机器人:Milvus + LangChain

搭建一个好用、便宜又准确的问答机器人需要多长时间&#xff1f; 答案是 5 分钟。只需借助开源的 RAG 技术栈、LangChain 以及好用的向量数据库 Milvus。必须要强调的是&#xff0c;该问答机器人的成本很低&#xff0c;因为我们在召回、评估和开发迭代的过程中不需要调用大语言…

[SWPUCTF 2021 新生赛]Do_you_know_http已

打开环境 它说用WLLM浏览器打开&#xff0c;使用BP抓包&#xff0c;发送到重发器 修改User-Agent 下一步&#xff0c;访问a.php 这儿他说添加一个本地地址&#xff0c;它给了一个183.224.40.160&#xff0c;我用了发现没用&#xff0c;然后重新添加一个地址&#xff1a;X-Forwa…

3. 行为模式 - 迭代器模式

亦称&#xff1a; Iterator 意图 迭代器模式是一种行为设计模式&#xff0c; 让你能在不暴露集合底层表现形式 &#xff08;列表、 栈和树等&#xff09; 的情况下遍历集合中所有的元素。 问题 集合是编程中最常使用的数据类型之一。 尽管如此&#xff0c; 集合只是一组对象的…

将qt程序注册成服务

将qt程序注册成服务 1、qt服务模块管理下载 qt-solutions 2、QtService项目 2.1、将qtservice拷贝到项目代码路径 2.2、实现服务管理 PS&#xff1a;响应服务的启停 CustomService.h #include <QCoreApplication> #include "qtservice.h"class CustomSer…

React网页转换为pdf并下载|使用jspdf html2canvas

checkout 分支后突然报错&#xff0c;提示&#xff1a; Cant resolve jspdf in ... Cant resolve html2canvas in ... 解决方法很简单&#xff0c;重新 yarn install 就好了&#xff0c;至于为什么&#xff0c;我暂时也不知道&#xff0c;总之解决了。 思路来源&#xff1a; 先…

opencv静态链接error LNK2019

opencv 3.1.0 静态库&#xff0c;包括以下文件 只链接opencv_world310d.lib&#xff0c;报错 opencv_world310d.lib(matrix.obj) : error LNK2019: 无法解析的外部符号 _ippicvsFlip_16u_I8&#xff0c;该符号在函数 "enum IppStatus (__stdcall*__cdecl cv::getFlipFu…

安全狗云原生安全-云甲·云原生容器安全管理系统

随着云计算的快速发展&#xff0c;容器技术逐渐成为主流。然而&#xff0c;随着容器的普及&#xff0c;安全问题也日益突出。为了解决这一问题&#xff0c;安全狗推出了云原生容器安全管理系统——云甲。 云甲是安全狗云原生安全的重要组成部分&#xff0c;它采用了先进的云原生…

深入了解Spring MVC工作流程

目录 1. MVC架构简介 2. Spring MVC的工作流程 2.1. 客户端请求的处理 2.2. 视图解析和渲染 2.3. 响应生成与返回 3. Spring MVC的关键组件 3.1. DispatcherServlet 3.2. HandlerMapping 3.3. Controller 3.4. ViewResolver 4. 结论 Spring MVC&#xff08;Model-Vi…

【Midjourney】Midjourney根据prompt提示词生成黑白色图片

目录 &#x1f347;&#x1f347;Midjourney是什么&#xff1f; &#x1f349;&#x1f349;Midjourney怎么用&#xff1f; &#x1f514;&#x1f514;提示词格式 &#x1f34b;&#x1f34b;应用示例——“秘密花园”式涂色书配图生成 &#x1f34c;&#x1f34c;例子1…

浅述无人机技术在地质灾害应急救援场景中的应用

12月18日23时&#xff0c;甘肃临夏州积石山县发生6.2级地震&#xff0c;震源深度10千米&#xff0c;灾区电力、通信受到影响。地震发生后&#xff0c;无人机技术也火速应用在灾区的应急抢险中。目前&#xff0c;根据受灾地区实际情况&#xff0c;翼龙-2H应急救灾型无人机已出动…

vivado生成时钟分析

生成的时钟 本节讨论生成的时钟&#xff0c;包括&#xff1a; •关于生成的时钟 •用户定义的生成时钟 •自动衍生时钟 •自动衍生时钟 关于生成的时钟 生成的时钟在设计内部由称为时钟修改块&#xff08;用于例如MMCM&#xff09;&#xff0c;或者通过一些用户逻辑。生…

应用 Strangler 模式将遗留系统分解为微服务

许多来源在一般情况下提供了微服务的解释&#xff0c;但缺乏特定领域的示例。新来者或不确定从哪里开始的人可能会发现掌握如何将遗留系统过渡到微服务架构具有挑战性。本指南主要面向那些正在努力启动迁移工作的个人&#xff0c;它提供了特定于业务的示例来帮助理解该过程。 …

EasyExcel使用: RGB字体,RGB背景颜色,fillForegroundColor颜色对照表

EasyExcel使用: RGB字体&#xff0c;RGB背景颜色&#xff0c;fillForegroundColor颜色对照表 使用EasyExcel导出表格可能会对字体颜色和单元格背景颜色进行自定义的修改。 可以自定义字体颜色或者每个单元格的颜色 要想自定义颜色&#xff0c;需要重写CellWriteHandler接口&am…

用友U8+CRM help2 任意文件读取漏洞复现

0x01 产品简介 用友U8 CRM客户关系管理系统是一款专业的企业级CRM软件&#xff0c;旨在帮助企业高效管理客户关系、提升销售业绩和提供优质的客户服务。 0x02 漏洞概述 用友 U8 CRM客户关系管理系统 help2接口处存在任意文件读取漏洞&#xff0c;攻击者通过漏洞可以获取到服…

【PyTorch】代码学习

文章目录 直接定义nn.Sequential(), 然后append(),最后直接net(),少写很多forward&#xff0c;适合直连式网络 直接定义nn.Sequential(), 然后append(),最后直接net(),少写很多forward&#xff0c;适合直连式网络 代码来源&#xff1a;https://github.com/zshhans/MSD-Mixer/b…

用C爬取人人文库并分析实现免积分下载资料

最近有个学妹学习遇到问题&#xff0c;想要的学习资料都在文库中&#xff0c;因为资料太多太杂&#xff0c;想要一篇篇找太难了&#xff0c;主要是太浪费精力了。因此&#xff0c;听说这个事情我能解决&#xff0c;立马找到我&#xff0c;给我一杯奶茶就把我收买了&#xff0c;…

node.js mongoose index(索引)

目录 简介 索引类型 单索引 复合索引 文本索引 简介 在 Mongoose 中&#xff0c;索引&#xff08;Index&#xff09;是一种用于提高查询性能的数据结构&#xff0c;它可以加速对数据库中文档的检索操作 索引类型 单索引、复合索引、文本索引、多键索引、哈希索引、地理…

ChatGPT一周年:开源语言大模型的冲击

自2022年末发布后&#xff0c;ChatGPT给人工智能的研究和商业领域带来了巨大变革。通过有监督微调和人类反馈的强化学习&#xff0c;模型可以回答人类问题&#xff0c;并在广泛的任务范围内遵循指令。在获得这一成功之后&#xff0c;人们对LLM的兴趣不断增加&#xff0c;新的LL…

听GPT 讲Rust源代码--src/tools(18)

File: rust/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs 在Rust源代码中的from_comment.rs文件位于Rust分析器&#xff08;rust-analyzer&#xff09;工具的ide-ssr库中&#xff0c;它的作用是将注释转换为Rust代码。 具体来说&#xff0c;该文件实现了从注…

数据库学习日常案例20231221-oracle libray cache lock分析

1 问题概述&#xff1a; 阻塞的源头为两个ddl操作导致大量的libray cache lock 其中1133为gis sde的create table as语句。 其中697为alter index语句。