前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >【AIGC】通过RAG架构LLM应用程序

【AIGC】通过RAG架构LLM应用程序

原创
作者头像
Freedom123
发布于 2024-05-08 10:44:55
发布于 2024-05-08 10:44:55
24000
代码可运行
举报
文章被收录于专栏:AIGCAIGC
运行总次数:0
代码可运行

toc


在之前的博客文章中,我们已经描述了嵌入是如何工作的,以及RAG技术是什么。本节我们我们将使用 LangChain 库以及 RAG 和嵌入技术在 Python 中构建一个简单的 LLM 应用程序。

我们将使用 LangChain 库在 Python 中构建一个简单的 LLM 应用程序。LangChain是一个流行的库,它使构建这样的应用程序变得非常容易。

我们的 RAG 应用程序将使用私有数据扩展 LLM 的知识。在这种情况下,它将是一个包含一些文本的 PDF 文件。

也可以通过使用 OpenAI 代理并通过将特定文件上传到 OpenAI 的服务器来扩展其知识库来实现类似的目标。但是,这种方法需要将我们的机密数据存储在 OpenAI 的服务器上,这可能并不总是符合我们的隐私偏好。

1.安装条件

在一开始,我们必须安装应用程序将使用的所有必需模块。让我们在终端的项目目录中编写此命令

代码语言:shell
AI代码解释
复制
pip install langchain-community==0.0.11 pypdf==3.17.4 langchain==0.1.0 python-dotenv==1.0.0 langchain-openai==0.0.2.post1 faiss-cpu==1.7.4 tiktoken==0.5.2 langchainhub==0.1.14

让我们创建一个“data”目录并将 PDF 文件放入其中。 我们还必须在项目目录中创建一个 main.py 文件,我们将在其中存储应用程序的整个代码。

在 main.py 文件中,我们将创建用于存储逻辑的 main() 函数。该文件将如下所示:

代码语言:shell
AI代码解释
复制
def main():
  print("Hello World!")

if __name__ == "__main__": 
  main()

2.导入PDF文件

我们将使用LangChain提供的名为PyPDFLoader的文档加载器。

代码语言:shell
AI代码解释
复制
from langchain_community.document_loaders import PyPDFLoader

pdf_path = "./data/2210.03629.pdf"

def main():
  loader = PyPDFLoader(file_path=pdf_path)
  documents = loader.load()
  print(documents) 

if __name__ == "__main__": 
  main()

首先,我们应该创建一个 PyPDFLoader 对象的实例,我们将路径传递给文件。下一步是简单地调用此对象的 load 函数,并将加载的文件保存在 documents 变量中。它将是一个由 Document 对象组成的数组,其中每个对象都是我们文件的一页的表示形式。

print() 函数应该输出一个类似于这样的数组:

代码语言:shell
AI代码解释
复制
[Document(page_content='[...]', metadata={'source': pdf_path, page: 1}), Document(page_content='[...]', metadata={'source': pdf_path, page: 2}), ...]

3.切割文件

我们不想将整个文档作为上下文发送到 LLM。为什么?在关于RAG的文章中对此进行了更详细的描述。为了拆分文档,我们将使用 LangChain 提供的一个名为 CharacterTextSplitter 的类,我们可以从 langchain 库中导入它:

代码语言:shell
AI代码解释
复制
from langchain.text_splitter import CharacterTextSplitter

然后我们可以创建一个实例并调用 split_documents() 函数,将加载的文档作为参数传递。

代码语言:shell
AI代码解释
复制
def main():
  loader = PyPDFLoader(file_path=pdf_path) 
  documents = loader.load() 
  text_splitter = CharacterTextSplitter( chunk_size=1000, chunk_overlap=50, separator="\n" ) 
  docs = text_splitter.split_documents(documents)

让我们简要描述一下这里发生了什么。

首先,我们将创建一个 CharacterTextSplitter 对象,该对象采用多个参数:

  • chunk_size - 定义以令牌为单位的单个块的最大大小。
  • chunk_overlap - 定义块之间的重叠大小。这有助于通过确保块不会以扭曲其含义的方式拆分来保留拆分文本的含义。
  • separator - 定义将用于描述块的分隔符。

在 docs 变量中,我们将得到一个 Document 对象数组 - 与 PyPDFLoader 类的 load() 函数相同。

4.准备环境变量

下一步是将这些块转换为数字向量,并将它们存储在向量数据库中。这个过程叫做嵌入,也有一篇关于它的博文,所以我们现在不会详细介绍它。

对于嵌入过程,我们需要一个外部嵌入模型。为此,我们将使用 OpenAI 嵌入。为此,我们必须生成一个 OpenAI API 密钥。

但在此之前,我们必须创建一个 .env 文件,用于存储此密钥。

现在,我们需要在 platform.openai.com/docs/overview 页面上创建一个帐户。 之后,我们应该通过创建一个新的密钥在 platform.openai.com/api-keys 页面上生成一个 API 密钥。

复制密钥并将其粘贴到 .env 文件中,如下所示:

代码语言:shell
AI代码解释
复制
OPENAI_API_KEY=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

让我们通过导入 load_dotenv 函数将环境变量加载到我们的项目中:

代码语言:shell
AI代码解释
复制
from dotenv import load_dotenv

并在 main 函数的开头调用它:

代码语言:shell
AI代码解释
复制
def main(): 
	load_dotenv()
	loader = PyPDFLoader(file_path=pdf_path) 
	documents = loader.load() 
	text_splitter = CharacterTextSplitter( chunk_size=1000, chunk_overlap=50, separator="\n" ) 
	docs = text_splitter.split_documents(documents)

5.直线嵌入功能

首先,我们必须导入 OpenAIEmbeddings 类:

代码语言:shell
AI代码解释
复制
from langchain_openai import OpenAIEmbeddings

我们应该创建这个类的实例。让我们将其分配给 'embeddings' 变量,如下所示:

代码语言:shell
AI代码解释
复制
embeddings = OpenAIEmbeddings()

6.设置向量数据库

我们已经加载并准备了我们的文件,我们还为嵌入模型创建了一个对象实例。我们现在已准备好将块转换为数字向量并将它们保存在向量数据库中。我们将使用 FAISS 矢量数据库将所有数据保存在本地。Facebook AI 相似度搜索 (Faiss) 是 Facebook AI 设计的一款工具,用于对密集向量进行有效的相似性搜索和聚类。

首先,我们需要导入 FAISS 实例:

代码语言:shell
AI代码解释
复制
from langchain_community.vectorstores.faiss import FAISS

并实现转换和保存嵌入的过程:

代码语言:shell
AI代码解释
复制
def main(): 
	load_dotenv() 
	loader = PyPDFLoader(file_path=pdf_path) 
	documents = loader.load() 
	text_splitter = CharacterTextSplitter( chunk_size=1000, chunk_overlap=50, separator="\n" ) 
	docs = text_splitter.split_documents(documents) 
	embeddings = OpenAIEmbeddings() 
	vectorstore = FAISS.from_documents(docs, embeddings)    
	vectorstore.save_local("vector_db")

我们在代码中添加了两行。第一行采用我们的拆分块 (docs) 和嵌入模型将块从文本转换为数字向量。之后,我们将转换后的数据保存在本地的“vector_db”目录中。

7.创建提示

为了准备提示,我们将使用“langchain”中心。我们将从那里提取一个名为“langchain-ai/retrieval-qa-chat”的提示。这个提示是专门为我们的案例设计的,允许我们从提供的上下文中向模型询问事物。在引擎盖下,提示如下所示:

代码语言:shell
AI代码解释
复制
Answer any use questions based solely on the context below:
<context> 
{context}
</context>

让我们从“langchain”库导入一个"hub":

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
from langchain import hub

然后,只需使用“pull()”函数从中心检索此提示并将其存储在变量中:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")

8.设置大语言模型

接下来我们需要的是一个大型语言模型——在我们的例子中,它将是 OpenAI 模型之一。同样,我们需要一个 OpenAI 密钥,但我们已经将它与嵌入一起设置,因此我们不需要再做一次。

让我们继续导入模型:

代码语言:shell
AI代码解释
复制
from langchain_openai import ChatOpenAI, OpenAIEmbeddings

并将其分配给我们 main 函数中的一个变量:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
llm = ChatOpenAI()

9.从数据库检索上下文数据

我们已经完成了向量数据库、嵌入和 LLM(大型语言模型)的准备工作。现在,我们需要使用链条连接所有东西。为此,我们需要“langchain”提供的两种类型的链。

第一个是 'create_stuff_documents_chain',我们需要从 'langchain' 库中导入它:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
from langchain.chains.combine_documents import create_stuff_documents_chain

接下来,传递我们的大型语言模型 (LLM) 并提示它。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
combine_docs_chain = create_stuff_documents_chain(llm, retrieval_qa_chat_prompt)

此函数返回一个 LCEL Runnable 对象,该对象需要上下文参数。运行它将如下所示:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
combine_docs_chain.invoke({"context": docs, "input": "What is REACT in machine learning meaning?"})

10.仅检索相关数据作为上下文

它会起作用,但在这种情况下,我们将传递所有块 - 整个文档 - 作为上下文。在我们的例子中,文件有 33 页,这个上下文太大,我们可能会遇到这样的错误:

代码语言:shell
AI代码解释
复制
openai.BadRequestError: Error code: 400 - {'error': {'message': "This model's maximum context length is 4097 tokens. However, your messages resulted in 33846 tokens. Please reduce the length of the messages.", 'type': 'invalid_request_error', 'param': 'messages', 'code': 'context_length_exceeded'}}

为了解决这个问题,我们只需要将与查询相关的信息作为上下文传递。我们将通过将此链与另一条链相结合来实现这一点,该链将仅从数据库中检索对我们重要的块,并自动将它们作为上下文添加到提示中。

让我们从“langchain”库中导入该链:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
from langchain.chains import create_retrieval_chain 

首先,我们需要将数据库准备为检索器,这将启用对与查询相关的块的语义搜索。

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
retriever = FAISS.load_local("vector_db", embeddings).as_retriever()

因此,我们加载我们的目录,其中存储转换为向量的块并将其传递给嵌入函数。最后,我们将其作为检索器返回。

现在,我们可以组合我们的链:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
retrieval_chain = create_retrieval_chain(retriever, combine_docs_chain)

在后台,它将从数据库中检索相关块,并将它们作为上下文添加到我们的提示中。我们现在要做的就是使用我们的查询作为输入参数调用此链:

代码语言:python
代码运行次数:0
运行
AI代码解释
复制
response = retrieval_chain.invoke({"input": "What is REACT in machine learning meaning?"})

作为响应,我们将收到一个包含三个变量的对象:

  • input - 我们的查询;
  • context - 我们作为上下文传递给提示的文档(块)数组;
  • answer - 由大型语言模型 (LLM) 生成的查询的答案。

10.LLM app 全部代码

我们用 .pdf 文件中的数据扩展了 LLM 模型的知识库。该模型现在能够根据我们在提示中提供的上下文来回答我们的问题。

代码语言:shell
AI代码解释
复制
from dotenv import load_dotenv
from langchain import hub
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_community.document_loaders import PyPDFLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_community.vectorstores.faiss import FAISS

pdf_path = "./data/2210.03629.pdf"


def main():
    load_dotenv()

    loader = PyPDFLoader(file_path=pdf_path)
    documents = loader.load()

    text_splitter = CharacterTextSplitter(
        chunk_size=1000, chunk_overlap=50, separator="\n"
    )
    docs = text_splitter.split_documents(documents)

    embeddings = OpenAIEmbeddings()

    vectorstore = FAISS.from_documents(docs, embeddings)
    vectorstore.save_local("vector_db")

    retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")

    llm = ChatOpenAI()

    combine_docs_chain = create_stuff_documents_chain(llm, retrieval_qa_chat_prompt)

    retriever = FAISS.load_local("vector_db", embeddings).as_retriever()
    retrieval_chain = create_retrieval_chain(retriever, combine_docs_chain)

    response = retrieval_chain.invoke(
        {"input": "What is REACT in machine learning meaning?"}
    )

    print(response["answer"])


if __name__ == "__main__":
    main()

小结

遵守前面博客中的约定,输出一节基于RAG进行大语言模型构建的内容,我们共划分了10个小节分别进行了详细介绍,希望对初学者有很好的指导作用。

小编是一名热爱人工智能的专栏作者,致力于分享人工智能领域的最新知识、技术和趋势。这里,你将能够了解到人工智能的最新应用和创新,探讨人工智能对未来社会的影响,以及探索人工智能背后的科学原理和技术实现。欢迎大家点赞,评论,收藏,让我们一起探索人工智能的奥秘,共同见证科技的进步!

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
1 条评论
热度
最新
牛的,很有用
牛的,很有用
回复回复点赞举报
推荐阅读
WordPress终极优化篇2—Nginx+Redis Object Cache+Redis+opcache
Redis是一个可运行在内存中的数据库,所以如果拿来当作缓存器,并且配合持久化处理,能极大提升网站性能及访问速度
用户6948990
2025/04/03
1090
WordPress终极优化篇2—Nginx+Redis Object Cache+Redis+opcache
宝塔面板如何安装Memcached插件来加速wordpress访问
目前网站服务器带宽比较贵,在有限的小水管带宽前提下,如何加速wordpress访问倒是个难题,蜗牛般的速度强制劝退不少访问者,但是加钱加带宽嘛,又舍不得,现在图图来教小白们如何加速wordpress前后台访问,本篇文章就将配置方法分享给大家。
图图网
2021/08/28
1.3K0
宝塔面板如何安装Memcached插件来加速wordpress访问
宝塔BT面板+wordpress如何开启Memcached缓存,让网站飞起来
宝塔BT面板+wordpress如何开启Memcached缓存,让网站飞起来,主要减少查询,提升网站访问速度,降低卡顿的风险,减轻服务器压力
wordpress建站吧
2019/05/28
2.5K0
WordPress启用memcached动态缓存以及报错解决
张戈博客目前用的是Nginx 的 fastcgi 缓存方案,属于纯净态缓存模式,所以前台登录态什么的基本都没了。如果要兼顾前台登录态,又想速度快,有没有解决方案? 之前在分享张戈博客优化方案时提到,要
张戈
2018/03/21
1.8K0
WordPress启用memcached动态缓存以及报错解决
WordPress宝塔开启Memcached,加速网站访问。
Memcached 对象缓存为 WordPress 对象缓存提供了一个持久的后端。
Kit
2021/07/24
4.1K3
wordpress配置Memcached缓存
WordPress用Memcached缓存也已经半年之久了。对博客的访问速度提升还是很明显的。之前写过一篇文章介绍Memcached缓存以及如何部署(通过WPJAM Basic插件实现)
AlexTao
2019/07/16
3.4K0
wordpress配置Memcached缓存
WordPress优化-让17CE.COM 测速不在死机
这里我采用的是WP Super Cache + Memcached 当然也可以使用WP Super Cache + Redis 下面我会教大家如何进行使用。
残浔
2023/05/11
6060
WordPress优化-让17CE.COM 测速不在死机
【说站】WordPress安装memcached扩展实现网站加速(详细)
介绍一下WordPress网站如何安装Memcached扩展,搞定WP网站加速的问题,编程笔记也看了不少的教程,基本上千篇一律吧,这里介绍的memcached安装教程也记录了品编程笔记安装Memcached扩展过程中遇到的一些问题,最终品自行博客亲测成功。
很酷的站长
2022/11/24
1.6K0
【说站】WordPress安装memcached扩展实现网站加速(详细)
宝塔面板安装memcached并在WP使用batcache
宝塔面板添加memcached可以有效加速服务器访问速度,提高网站的用户体验。不过在实际使用中,博主发现很多新手有一个误区,就是添加了错误的memcached组件,导致起不到正常加速服务器的效果。本文分享一下误区在哪里以及应该怎么安装是正确的加速组件。
可定
2020/04/20
1K0
宝塔面板安装memcached并在WP使用batcache
wordpress网站利用Memcached加载速度优化
Memcached 是一种高性能的分布式内存对象缓存系统,在动态程序中使用 Memcached, 既能提高访问的速度,同时还减低了数据库的负载。
陌涛
2021/01/23
6130
使用memcache对wordpress优化,提速
一个部署在虚拟机中( 虚拟机安装memcache缓存),然后用这个优化的版本跟本地开发环境对比.
猿哥
2019/07/25
7440
WordPress使用Redis和opcache为网站加速教程
相信建站的朋友都十分关心网站速度问题了,玖柒的小窝一直在强调极速优化这次词语,同时在之前的很多文章中我也简单的介绍了子比主题的关于速度优化的一些原理。理论上来讲使用子比主题搭配一个不是太差的服务器,那么就已经很快了,如果你想让你的网站变得更快,那么看了这篇文章,我相信完全够了。
玖柒的小窝
2021/10/22
2.8K0
WordPress使用Redis和opcache为网站加速教程
教大家一个WPJAM Basic如何开启Memcacached内存缓存和对应的 WordPress 插件
Memcached 是一种高性能的分布式内存对象缓存系统,在动态程序中使用 Memcached, 既能提高访问的速度,同时还减低了数据库的负载。
Hello-1
2022/08/30
9980
教大家一个WPJAM Basic如何开启Memcacached内存缓存和对应的 WordPress 插件
网站速度优化之“缓存技术”、有效提升页面生成的时间!
Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载。它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态、数据库驱动网站的速度。
QUXINGDONG.COM
2018/11/18
1.1K0
网站速度优化之“缓存技术”、有效提升页面生成的时间!
部署Memchached
在安装LNMP时直接一键安装memcached,不赘述,对于memcache和memcached的区别,引用一下“简单来说:
空空裤兜
2023/03/03
3970
部署Memchached
实用教程:WordPress安装memcached对网站进行缓存加速
经常会看到wordpress使用redis或者memcache缓存进行加速,当然本站也不例外,由于使用的是宝塔和果酱大佬的wpjam插件,本着能少装插件就少装插件的原则,推荐使用memcached对wordpress进行加速,与使用redis加速差不多。
深白鸭
2023/02/22
1.2K0
实用教程:WordPress安装memcached对网站进行缓存加速
Batcache 插件给服务器提速的安装过程
魏艾斯博客写过有关开启 memcached,opcache 缓存的文章,前者是内容缓存插件,后者是 php 缓存插件,本来以为服务器优化折腾到此就差不多了,这几天在@张戈博客看到一篇文章,原来开启 memcached 之后,还可以再上一个 batcache 插件,用来把 html 静态文件放到内存中去,于是经过一番测试,在云服务器上安装了这个插件,下面写出相关操作步骤。
魏艾斯博客www.vpsss.net
2018/08/22
1.5K0
Batcache 插件给服务器提速的安装过程
一文详解 WordPress 中使用 Memcached 的常见问题
前面我们介绍了使用 Memcached 内存缓存来提高 WordPress 站点速度,虽然感觉介绍得非常清楚,但是还是有很多小伙伴还是会碰到问题,今天就把其中的常见的问题整理到一起发布,方便大家查看和 Debug,也欢迎收藏和分享该文,帮到更多的人解决问题。
Denis
2023/04/13
6080
一文详解 WordPress 中使用 Memcached 的常见问题
在wordpress上配置memcached
Memcached 是一种高性能的分布式内存对象缓存系统。在动态应用,Memcached 既能提高访问的速度,同时还减低了数据库的负载。
EltonZheng
2021/01/22
7350
使用 Memcached 内存缓存来提高 WordPress 站点速度
很多人问我 WordPress 怎么速度快,一般简单回答就是装 Memcached,这真的不是敷衍了事,一点不夸张,装上 Memcached 就可以让 WordPress 快上好几倍,但是真正用好 WordPress,还是需要对 WordPress 有更深的了解。
Denis
2023/04/13
7950
使用 Memcached 内存缓存来提高 WordPress 站点速度
推荐阅读
相关推荐
WordPress终极优化篇2—Nginx+Redis Object Cache+Redis+opcache
更多 >
LV.1
这个人很懒,什么都没有留下~
目录
  • 1.安装条件
  • 2.导入PDF文件
  • 3.切割文件
  • 4.准备环境变量
  • 5.直线嵌入功能
  • 6.设置向量数据库
  • 7.创建提示
  • 8.设置大语言模型
  • 9.从数据库检索上下文数据
  • 10.仅检索相关数据作为上下文
  • 10.LLM app 全部代码
  • 小结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档