@TOC

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

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

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

一、环境配置与安装

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

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

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

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

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

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

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

创建好后打开Cloud 9 IDE:

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

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

cd ~/environment/
curl 'https://dev-media.amazoncloud.cn/doc/workshop.zip' --output workshop.zip
unzip workshop.zip

解压完成:

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

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

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的矢量引擎。

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

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

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

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

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

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

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

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 函数:
  • 主要用于模型获取与设置 ,用于初始化和返回一个Bedrock语言模型。
  • Bedrock模型通过指定model_id来调用特定的预训练模型,这里是meta.llama2-70b-chat-v1。
  1. get_index 函数:
  • 主要用于向量存储创建 ,负责创建一个内存中的向量存储,用于后续的文本检索。
  • BedrockEmbeddings用于生成文本的嵌入表示。
  • PyPDFLoader加载指定路径的PDF文件,以便从中提取文本。
  • RecursiveCharacterTextSplitter是一个文本拆分器,它根据指定的分隔符将文本分割成小块,并设置重叠以保持上下文连贯性。
  • VectorstoreIndexCreator创建一个向量存储索引,使用FAISS作为后端,它是一个高效的相似性搜索和密集向量聚类库。
  1. get_rag_response 函数:
  • 主要用于响应生成,它使用之前创建的向量索引和语言模型来生成对用户问题的回答。
  • 调用get_llm获取语言模型实例。并使用index.query方法,结合问题文本和语言模型,查询向量索引以生成回答。

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

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. 初始化和页面设置:
  • 导入streamlit库并设置别名st,用于后续的所有Streamlit命令。
  1. 向量索引的创建与存储:
  • 检查st.session_state中是否已经存在vector_index,如果不存在,则执行索引创建过程。
  • 使用st.spinner显示一个旋转指示器,告知用户正在进行索引操作。调用glib.get_index方法创建向量索引,并将结果存储在Streamlit会话状态中,以便后续使用。
  1. 用户输入和操作:
  • 使用st.text_area创建一个多行文本框,允许用户输入文本。
  1. 响应生成与展示:
  • 检测到“Go”按钮被点击后,使用st.spinner显示另一个旋转指示器,表示程序正在处理用户的请求。
  • 调用glib.get_rag_response方法,传入用户输入的文本和之前创建的向量索引,生成响应。使用st.write将生成的响应内容写入到页面中,展示给用户。

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

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进行预览:

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

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

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

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

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

欢迎学习《 Amazon Bedrock入门》,Amazon Bedrock 是一项完全托管式服务,可以提供领先的基础模型 (FM) 和一系列工具,用于快速构建和扩缩生成式 AI 应用程序。在课程中,您将进一步了解 Amazon Bedrock 的优势、功能、典型使用案例、技术概念和成本。还将回顾使用 Amazon Bedrock 以及其他 Amazon Web Services 产品构建 Chatbot 解决方案的架构。

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

最后

个人简介:博客专家,人工智能优质创作者,2022年博客之星人工智能领域TOP2,COC武汉城市开发者社区主理人、2023中国开发者影响力年度优秀主理人

点击下方公众号,加入采苓AI研习社