建立使用亚马逊 Bedrock 知识库的 Q&A 应用程序 - Retrieve API

背景

在本笔记本中,我们将深入探讨如何使用亚马逊 Bedrock 的知识库构建 Q&A 应用程序 - Retrieve API。在这里,我们将查询知识库以获得基于相似性搜索的所需数量的文档块。然后,我们将使用相关文档和查询来增强提示,这将作为输入传递给 Anthropic Claude V2 以生成响应。

使用知识库,我们可以安全地将基础模型 (FM) 在亚马逊 Bedrock 中连接到我们公司的数据以进行检索增强生成 (RAG)。访问额外的数据可帮助模型生成更相关、更具上下文针对性和更准确的响应,而无需不断重新训练 FM。从知识库检索的所有信息都附有来源归属,以提高透明度并最大程度地减少幻觉。有关使用控制台创建知识库的更多信息,请参阅此帖子 。 我们将在笔记本中涵盖 2 个部分:

  • 第 1 部分,我们将分享如何使用 RetrieveAPI 与亚马逊 Bedrock 的基础模型。我们将使用 mistral.mistral-7b 模型。
  • 第 2 部分,我们将展示使用 Anthropic Claude 3 Haiku 模型的 langchain 集成。

模式

我们可以使用检索增强生成 (RAG) 模式来实现解决方案。RAG 从语言模型 (非参数) 之外检索数据,并通过添加相关检索数据来增强提示。在这里,我们正在有效地对使用控制台/sdk 创建的知识库执行 RAG。

先决条件

在回答问题之前,必须处理和摄取文档。

  1. 通过连接我们的 s3 存储桶 (数据源) 将文档加载到知识库中。
  2. 摄取 - 知识库将它们拆分成更小的块 (基于所选的策略),生成嵌入并将其存储在相关的矢量存储中,笔记本 0_create_ingest_documents_test_kb.ipynb 为我们处理了这一点。

data_ingestion

笔记本演练

对于我们的笔记本,我们将使用亚马逊 Bedrock 知识库提供的 Retreive API,它将用户查询转换为嵌入,搜索知识库,并返回相关结果,为我们提供更多控制权来构建基于语义搜索结果的自定义工作流程。 Retrieve API 的输出包括 retrieved text chunks、源数据的 location typeURI,以及检索的相关性 scores

然后,我们将使用生成的文本块并将其与原始提示结合,并通过使用基于我们的用例的提示工程模式将其传递给 anthropic.claude-v2 模型。

用例:

数据集

在这个例子中,我们将使用多年来的亚马逊股东信作为文本语料库来执行问答。这些数据已经被摄取到亚马逊 Bedrock 的知识库中。我们将需要 knowledge base id 来运行这个例子。 在我们的特定用例中,我们可以同步不同领域主题的不同文件,并以相同的方式查询此笔记本,以使用知识库的检索 API 评估模型响应。

Python 3.10

⚠ 对于此实验室,我们需要基于 Python 3.10 运行时运行笔记本。⚠

如果我们在 Amazon SageMaker studio 之外的本地环境中进行研讨会,请确保我们正在运行 Python 运行时 > 3.10。

设置

要运行此笔记本,我们需要安装以下软件包。

%pip install --force-reinstall -q -r ./requirements.txt
%store -r

使用上面安装的依赖项重新启动内核

# restart kernel
from IPython.core.display import HTML
HTML("<script>Jupyter.notebook.kernel.restart()</script>")

按照以下步骤初始化 bedrock 客户端:

  1. 导入必要的库,包括 langchain 用于 bedrock 模型选择,llama index 用于存储包含 llm 和嵌入模型实例的服务上下文。我们将在笔记本的后续部分使用此服务上下文来评估我们 Q&A 应用程序的响应。

  2. anthropic.claude-v2 初始化为我们的大型语言模型,以使用给定知识库的 RAG 模式执行查询完成。

import boto3
import pprint
from botocore.client import Config
import json

pp = pprint.PrettyPrinter(indent=2)
session = boto3.session.Session()
region = session.region_name
bedrock_config = Config(connect_timeout=120 read_timeout=120 retries={'max_attempts': 0})
bedrock_client = boto3.client('bedrock-runtime' region_name = region)
bedrock_agent_client = boto3.client("bedrock-agent-runtime"
                              config=bedrock_config region_name = region)
print(region)

第 1 部分 - 使用亚马逊 Bedrock 的基础模型的 Retrieve API

定义一个检索函数,它调用亚马逊 Bedrock 知识库提供的 Retreive API,该 API 将用户查询转换为嵌入,搜索知识库,并返回相关结果,为我们提供更多控制权来构建基于语义搜索结果的自定义工作流程。 Retrieve API 的输出包括 retrieved text chunks、源数据的 location typeURI,以及检索的相关性 scores。我们还可以在 retrievalConfiguration 中使用 overrideSearchType 选项,它提供了使用 HYBRIDSEMANTIC 的选择。默认情况下,它将为我们选择正确的策略以获得最相关的结果,如果我们想覆盖默认选项以使用混合或语义搜索,可以将值设置为 HYBRID/SEMANTIC

retrieveAPI

def retrieve(query kbId numberOfResults=5):
    return bedrock_agent_client.retrieve(
        retrievalQuery= {
            'text': query
        }
        knowledgeBaseId=kbId
        retrievalConfiguration= {
            'vectorSearchConfiguration': {
                'numberOfResults': numberOfResults
                'overrideSearchType': "HYBRID" # optional
            }
        }
    )

在查询 LLM 的响应之前,先初始化我们的知识库 id

接下来,我们将调用 retreive API,并将 knowledge base idnumber of resultsquery 作为参数传递。

score: 我们可以查看每个返回的文本块的相关联分数,该分数描述了它与查询的相关性有多高。

query = "亚马逊在生成式 AI 领域做了什么?"
response = retrieve(query kb_id 5)
retrievalResults = response['retrievalResults']
pp.pprint(retrievalResults)

从 retrieveAPI 响应中提取文本块

在下面的单元格中,我们将从检索结果中获取上下文。

# fetch context from the response
def get_contexts(retrievalResults):
    contexts = []
    for retrievedResult in retrievalResults: 
        contexts.append(retrievedResult['content']['text'])
    return contexts
contexts = get_contexts(retrievalResults)
pp.pprint(contexts)

针对模型的特定提示来个性化响应

在这里,我们将使用下面的特定提示,让模型充当一个财务顾问 AI 系统,在可能的情况下使用事实性和统计信息来回答问题。我们将上面的 Retrieve API 响应作为 {contexts} 的一部分提供给提示,以供模型参考,同时还有用户 query

prompt = f"""
Human: 你是一个财务顾问 AI 系统,在可能的情况下使用事实性和统计信息来回答问题。
使用以下信息片段来回答括号内的问题。
如果你不知道答案,只需说你不知道,不要试图编造答案。
<context>
{contexts}
</context>

<question>
{query}
</question>

回答应该具体并尽可能使用统计数据或数字。

A:"""

调用亚马逊 Bedrock 的基础模型

在这个例子中,我们将使用亚马逊 Bedrock 的 mistral.mistral-7b 基础模型。 它是一个 7B 密集型变压器,部署速度快,易于定制。小巧但功能强大,适用于各种用例。

  • 最大令牌数: 8K
  • 语言: 英语
  • 支持的用例: 文本摘要、结构化、问答和代码补全
# payload with model paramters
mistral_payload = json.dumps({
    "prompt": prompt
    "max_tokens":512
    "temperature":0.5
    "top_k":50
    "top_p":0.9
})
注意: 请确保我们已在亚马逊 Bedrock 控制台的模型访问页面上订阅了 mistral-7B 模型,然后再继续。
modelId = 'mistral.mistral-7b-instruct-v0:2' # change this to use a different version from the model provider
accept = 'application/json'
contentType = 'application/json'
response = bedrock_client.invoke_model(body=mistral_payload modelId=modelId accept=accept contentType=contentType)
response_body = json.loads(response.get('body').read())
response_text = response_body.get('outputs')[0]['text']

pp.pprint(response_text)

第 2 部分 - LangChain 集成

在这个笔记本中,我们将深入探讨使用亚马逊 Bedrock 的 Retrieve API 和 LangChain 构建 Q&A 应用程序。我们将查询知识库以获得基于相似性搜索的所需数量的文档块,将其与 LangChain 检索器集成,并使用 Anthropic Claude V2.1 模型来回答问题。

from langchain_aws import ChatBedrock
from langchain.retrievers.bedrock import AmazonKnowledgeBasesRetriever

llm = ChatBedrock(model_id="anthropic.claude-3-haiku-20240307-v1:0"
              client = bedrock_client)

从 LangChain 创建一个 AmazonKnowledgeBasesRetriever 对象,它将调用亚马逊 Bedrock 知识库提供的 Retreive API,该 API 将用户查询转换为嵌入,搜索知识库,并返回相关结果,为我们提供更多控制权来构建基于语义搜索结果的自定义工作流程。 Retrieve API 的输出包括 retrieved text chunks、源数据的 location typeURI,以及检索的相关性 scores

query = "2022 年 AWS 收入同比增长了多少百分比?"
retriever = AmazonKnowledgeBasesRetriever(
        knowledge_base_id=kb_id
        retrieval_config={"vectorSearchConfiguration": 
                          {"numberOfResults": 4
                           'overrideSearchType': "SEMANTIC" # optional
                           }
                          }
        # endpoint_url=endpoint_url,
        # region_name=region,
        # credentials_profile_name="<profile_name>",
    )
docs = retriever.invoke(
        input=query
    )
pp.pprint(docs)

针对模型的特定提示来个性化响应

在这里,我们将使用下面的特定提示,让模型充当一个财务顾问 AI 系统,在可能的情况下使用事实性和统计信息来回答问题。我们将上面的 Retrieve API 响应作为 {context} 的一部分提供给提示,以供模型参考,同时还有用户 query

from langchain.prompts import PromptTemplate

PROMPT_TEMPLATE = """
Human: 你是一个财务顾问 AI 系统,在可能的情况下使用事实性和统计信息来回答问题。
使用以下信息片段来回答括号内的问题。
如果你不知道答案,只需说你不知道,不要试图编造答案。
<context>
{context}
</context>

<question>
{question}
</question>

回答应该具体并尽可能使用统计数据或数字。

A:"""
claude_prompt = PromptTemplate(template=PROMPT_TEMPLATE 
                               input_variables=["context""question"])

将上面定义的检索器和 LLM 与 RetrievalQA 链集成,构建 Q&A 应用程序。

from langchain.chains import RetrievalQA

qa = RetrievalQA.from_chain_type(
    llm=llm