LangChain + LLM + Amazon Bedrock构建一个检索增强型问答RAG-GPT应用程序

数十年前,图灵抛出的时代之问"Can machines think?"将人工智能从科幻拉至现实,奠定了后续人工智能发展的基础。之后,无数计算机科学的先驱开始解构人类智能的形成,希望找到赋予机器智能的蛛丝马迹。时至今日,我们站在了一个新的起点上,机器不仅能够"思考",更能够通过学习和模仿人类的交流方式,与我们进行自然而流畅的对话。

在这篇文章中,我们将探讨如何利用LangChain + LLM + Amazon Bedrock等技术构建一个检索增强型问答GPT应用程序。这个应用程序不仅能够理解用户的问题,还能够从海量的数据中检索出相关信息,生成准确而有用的回答。

一、环境配置与安装

首先进入Amazon Bedrock 控制台:dev.amazoncloud.cn/experience/... Bedrock** 提供了构建生成式人工智能应用程序所需的一切,它是专门为创新者量身打造的平台,其通过一个简化的 API 接口,提供来自AI21 Labs、Anthropic、Cohere、Meta、Stability AI 等行业领先公司的高性能基础模型,为开发者提供了一个广泛的功能集,以便安全、私密且负责任地构建生成式 AI 应用程序。

扫码登录后,输入相关的信息进入操作界面,在上方搜索Cloud 9并进入Cloud 9 主界面

然后新建一个AWS Cloud 9环境,设置环境详细信息:

  1. 设置名称为 bedrock
  2. 设置实例类型 t3.small
  3. 平台 Ubuntu Server 22.04 LTS
  4. 超时 30 分钟
  5. 网络选择AWS Systems Manager (SSM)

创建好后打开Cloud 9 IDE:

Amazon Cloud9 IDE 中,选择 终端复制以下内容到终端,执行命令,以下载和解压缩代码

bash 复制代码
cd ~/environment/
curl 'https://dev-media.amazoncloud.cn/doc/workshop.zip' --output workshop.zip
unzip workshop.zip

解压完成:

继续使用 终端 ,安装实验所需的环境依赖项

javascript 复制代码
pip3 install -r ~/environment/workshop/setup/requirements.txt -U

二、构建检索增强型问答RAG-GPT应用程序

本节实验,我们将使用Retrieval Augmented Generation(简称RAG),首先将用户输入的提示词传递给数据存储,模拟以Amazon Kendra类似的查询方式出现。同时使用Amazon Titan Embeddings创建提示的数字表示,以传递到矢量数据库。然后,我们从数据存储中检索最相关的内容,以支持大型语言模型的响应。

在这个实验中,使用内存中的FAISS数据库来演示RAG模式。在实际的生产环境中 ,我们可能需要使用类似Amazon Kendra 这样的持久数据存储或Amazon OpenSearch Serverless的矢量引擎。

打开 workshop/labs/rag 文件夹,应用程序由三个文件组成:

  1. rag_lib.py用于支持库以调用 Bedrock。其通过导入langchain生态系统中的多个库和组件来构建一个基于语言模型的检索增强问答逻辑。
  2. rag_app.py用于Streamlit 前端,其利用Streamlit框架编写一个应用程序,创建用户输入界面,利用前面提到的检索增强生成问答系统,处理用户输入并生成回答的逻辑。
  3. 2022-Shareholder-Letter.pdf是私有的PDF文档,作为检索增强的个人私有知识库,这里可以替换为自己的知识库。

将本地准备的私有知识库pdf文件上传到 workshop/labs/rag 文件夹

然后打开rag_lib.py 文件,将以下代码复制进去

ini 复制代码
from langchain_community.embeddings import BedrockEmbeddings
from langchain.indexes import VectorstoreIndexCreator
from langchain_community.vectorstores import FAISS
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.llms import Bedrock

def get_llm():
    
    model_kwargs = { 
        "max_gen_len": 2048,
        "temperature":0.5,
        "top_p":0.9
    }
    
    llm = Bedrock(
        model_id="meta.llama2-70b-chat-v1",model_kwargs=model_kwargs) #设置调用模型     
    
    return llm
    
def get_index(): #creates and returns an in-memory vector store to be used in the application
    
    embeddings = BedrockEmbeddings() #创建一个 Titan Embeddings 客户端
    pdf_path = "2022-Shareholder-Letter.pdf" # 本地 PDF 文件
    loader = PyPDFLoader(file_path=pdf_path) #加载 PDF 文件
    
    text_splitter = RecursiveCharacterTextSplitter( #创建一个文本拆分器
        separators=["\n\n", "\n", ".", " "], #以(1)段落、(2)行、(3)句子或(4)单词的顺序,在这些分隔符处拆分块
        chunk_size=1000, #使用上述分隔符将其分成 1000 个字符的块
        chunk_overlap=100 #与前一个块重叠的字符数
    )
    index_creator = VectorstoreIndexCreator( #创建一个向量存储创建器        vectorstore_cls=FAISS, #为了演示目的,使用内存中的向量存储
        embedding=embeddings, #使用 Titan 嵌入
        text_splitter=text_splitter, #使用递归文本拆分器
    )
    index_from_loader = index_creator.from_loaders([loader]) #从加载器创建向量存储索引
    
    return index_from_loader #返回索引以由客户端应用程序进行缓存
    
def get_rag_response(index, question): #rag 客户端函数
    
    llm = get_llm()
    response_text = index.query(question=question, llm=llm) #针对内存中的索引进行搜索,将结果填充到提示中并发送给语言模型
    return response_text

其通过加载PDF文件,创建文本的嵌入表示,并利用这些嵌入来构建一个向量索引,最后使用该索引来生成对特定问题的回答,其中:

  1. get_llm 函数:

    1. 主要用于模型获取与设置 ,用于初始化和返回一个Bedrock语言模型。
    2. Bedrock模型通过指定model_id来调用特定的预训练模型,这里是meta.llama2-70b-chat-v1
  2. get_index 函数:

    1. 主要用于向量存储创建 , 负责创建一个内存中的向量存储,用于后续的文本检索。
    2. BedrockEmbeddings用于生成文本的嵌入表示。
    3. PyPDFLoader加载指定路径的PDF文件,以便从中提取文本。
    4. RecursiveCharacterTextSplitter是一个文本拆分器,它根据指定的分隔符将文本分割成小块,并设置重叠以保持上下文连贯性。
    5. VectorstoreIndexCreator创建一个向量存储索引,使用FAISS作为后端,它是一个高效的相似性搜索和密集向量聚类库。
  3. get_rag_response 函数:

    1. 主要用于响应生成,它使用之前创建的向量索引和语言模型来生成对用户问题的回答。

    2. 调用get_llm获取语言模型实例。并使用index.query方法,结合问题文本和语言模型,查询向量索引以生成回答。

打开rag_app.py文件,将以下代码复制进去:

python 复制代码
import streamlit as st #所有 streamlit 命令都可以通过"st"别名使用
import rag_lib as glib  # 对本地库脚本的引用


st.set_page_config(page_title="Retrieval-Augmented Generation") #HTML title
st.title("Retrieval-Augmented Generation") #page title


if 'vector_index' not in st.session_state: #查看向量索引是否尚未创建
    with st.spinner("Indexing document..."): #在这个 with 块运行的代码时显示一个旋转器
        st.session_state.vector_index = glib.get_index() #通过支持库检索索引并存储在应用程序的会话缓存中
        
        
input_text = st.text_area("Input text", label_visibility="collapsed") #创建一个多行文本框
go_button = st.button("Go", type="primary") #按钮

if go_button:
    
    with st.spinner("Working..."):
        response_content = glib.get_rag_response(index=st.session_state.vector_index, question=input_text) #通过支持库调用模型
        st.write(response_content) 

这段代码通过使用Streamlit框架构建的简单Web应用程序,实现检索增强型文本生成(Retrieval-Augmented Generation)。程序通过加载文档建立一个向量索引,并允许用户输入文本,然后基于用户输入生成响应。整个程序的逻辑是:初始化页面 -> 创建并存储向量索引 -> 接收用户输入 -> 生成并展示响应:

  1. 初始化和页面设置:

    1. 导入streamlit库并设置别名st,用于后续的所有Streamlit命令。
  2. 向量索引的创建与存储:

    1. 检查st.session_state中是否已经存在vector_index,如果不存在,则执行索引创建过程。
    2. 使用st.spinner显示一个旋转指示器,告知用户正在进行索引操作。调用glib.get_index方法创建向量索引,并将结果存储在Streamlit会话状态中,以便后续使用。
  3. 用户输入和操作:

    1. 使用st.text_area创建一个多行文本框,允许用户输入文本。
  4. 响应生成与展示:

    1. 检测到"Go"按钮被点击后,使用st.spinner显示另一个旋转指示器,表示程序正在处理用户的请求。

    2. 调用glib.get_rag_response方法,传入用户输入的文本和之前创建的向量索引,生成响应。使用st.write将生成的响应内容写入到页面中,展示给用户。

然后在终端输入以下代码,安装相应依赖并运行

bash 复制代码
pip install chromadb
cd ~/environment/workshop/labs/rag
streamlit run rag_app.py --server.port 8080

当终端中显示如下内容时,说明成功运行:

You can now view your Streamlit app in your browser.

Network URL: http://*************:8080

External URL: http://*************:8080

然后打开Cloud9菜单栏- >Preview ->Preview Running Application进行预览:

可以看到应用可以从数据存储中检索最相关的内容,以支持大型语言模型的响应。

当然,在这个实验中,仅仅使用内存中的FAISS数据库来演示RAG模式。在实际的生产环境中 ,可能需要使用类似Amazon Kendra 这样的持久数据存储或Amazon OpenSearch Serverless的矢量引擎。

相关推荐
北京搜维尔科技有限公司3 分钟前
搜维尔科技:【应用】Xsens在荷兰车辆管理局人体工程学评估中的应用
人工智能·安全
说私域6 分钟前
基于开源 AI 智能名片 S2B2C 商城小程序的视频号交易小程序优化研究
人工智能·小程序·零售
YRr YRr6 分钟前
深度学习:Transformer Decoder详解
人工智能·深度学习·transformer
知来者逆11 分钟前
研究大语言模型在心理保健智能顾问的有效性和挑战
人工智能·神经网络·机器学习·语言模型·自然语言处理
云起无垠21 分钟前
技术分享 | 大语言模型赋能软件测试:开启智能软件安全新时代
人工智能·安全·语言模型
老艾的AI世界34 分钟前
新一代AI换脸更自然,DeepLiveCam下载介绍(可直播)
图像处理·人工智能·深度学习·神经网络·目标检测·机器学习·ai换脸·视频换脸·直播换脸·图片换脸
翔云API1 小时前
PHP静默活体识别API接口应用场景与集成方案
人工智能
浊酒南街1 小时前
吴恩达深度学习笔记:卷积神经网络(Foundations of Convolutional Neural Networks)4.9-4.10
人工智能·深度学习·神经网络·cnn
Tony聊跨境1 小时前
独立站SEO类型及优化:来检查这些方面你有没有落下
网络·人工智能·tcp/ip·ip
懒惰才能让科技进步1 小时前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝