使用生成式人工智能构建个性化多语言问答知识库
每小时 1.56 美元。
每个组织通常都会积累各种文档,包括项目文档、手册、投标书、Salesforce 数据、代码存储库等。在如此庞大的信息中查找特定文档并在其中进行搜索绝非易事。而且,就算您找到了所需的文档,文档本身也可能篇幅冗长,而您可能更需要的是一个内容概要。
使用文本总结的 Web 应用程序或许是一个简单的解决方案,但使用它们可能会泄露组织的敏感信息!
好在,我们有更好的解决方案。在本教程中,我们将利用多个数据源构建一个全面的知识库。有了这个知识库,您就可以搜索查询的答案,并收到简明的摘要和进一步学习的链接。为使其易于访问,我们将通过支持多语言的便捷问答形式来简化这一过程。
学习内容
- 如何使用 Amazon Kendra 构建由机器学习驱动的智能搜索服务。
- 如何使用预训练的开源生成式人工智能大语言模型 (LLM)。
- 如何使用人工智能服务检测文本中的主要语言。
- 如何使用人工智能服务翻译文本。
解决方案概览
我们将使用 SageMaker IAM 执行角色在 Amazon SageMaker Studio 中构建解决方案,我们可以在这里从同一账户与 Amazon 服务进行交互,无需额外的凭证或安全配置。
图 1 中可以看到解决方案由以下部分组成:
用户提出问题。
使用 Amazon Comprehend 检测查询所用的语言。
使用 Amazon Translate,问题将被翻译成数据源语言。
查阅智能知识库。
用 Amazon Kendra 的答案和用户问题向 LLM 请求汇总和优化的答案。
将答案翻译成问题所用的语言。
提供精简答案及其精简的原文。
我们将分五个部分构建这个解决方案:
- 第 1 部分 - 使用示例数据借助 Amazon Kendra 构建智能数据库。
- 第 2 部分 – 查询 Amazon Kendra 中的索引。
- 第 3 部分 - 添加多语言功能:检测文本的语言并对其进行翻译。
- 第 4 部分 - 创建端点以调用生成式人工智能大语言模型 (LLM)
- 第 5 部分 - 使用 LLM 总结答案
- 第 6 部分 - 清理资源
让我们开始吧!
第 1 部分 - 使用 Amazon Kendra 构建智能数据库
Kendra 是一种机器学习支持的智能搜索服务,您可以在其中自动添加、更新或删除、同步多数据源,还可以通过提供要抓取的 URL 来索引网页。
首先,您需要创建一个 Kendra 索引,用于保存文档的内容,并且构建方式要保证可以对文档进行搜索。按照此处的步骤在控制台中创建 Kendra 索引。
索引处于 Active(活跃)状态后,将数据源添加到索引(图 3)选择 Add data source(添加数据源),然后选择 Add dataset(添加数据集),添加名称并在语言中选择英语 (en)。
在数据同步结束后,您就准备好了用于查询的知识库。
在这里,您可以看到更多将源代码上传到 Kendra 的方法。
注意:您可以免费开始使用 Amazon Kendra 开发人员版,该试用版在前 30 天内最多可免费使用 750 小时。您可以点击此处查看定价。
第 2 部分 - 搜索 Amanzon Kendra 索引
要搜索 Amazon Kendra 索引,请使用检索 API,它会返回有关数据源的索引文档的信息。您也可以使用查询 API。但是,查询 API 仅返回长度最多为 100 个 Token 的摘录段落,而使用检索 API,您可以检索长度最多为 200 个 Token 的较长段落。
Amazon Kendra 利用各种要素根据输入的搜索词确定相关性最高的文档。这些要素包括文档的文本/正文、文档标题、可搜索的自定义文本字段和其他相关字段。
此外,可以将筛选器应用于搜索以缩小结果范围,例如根据特定的自定义字段,如“部门”,来筛选文档(例如,仅返回来自“法务”部门的文档)。有关详细信息,请参阅自定义字段或属性。
您可以通过多种方式搜索 Amazon Kendra 索引。
使用控制台搜索
在左侧的导航栏中,选择 Search indexed content(搜索索引内容),然后在文本框中输入查询并按 enter(回车键)(图 4)。
To search with Amazon SDK for Python(Boto3)(要使用适用于 Python (Boto3) 的 Amazon SDK 进行搜索),请使用以下代码:
import boto3
kendra_client = boto3.client("kendra")
def QueryKendra(index_id,query):
response = kendra_client.retrieve(
QueryText = query,
IndexId = index_id)
return response
用其他方式搜索
您还可以使用适用于 Java 的 Amazon SDK 和 Postman 进行搜索。
第 3 部分 - 添加多语言功能:检测文本语言并对其进行翻译
在这部分,您将使用两个可与 API 调用一起使用的 AI/ML 服务:
Amazon Comprehend,使用 Boto3 Comprehend 客户端的 DetectDominantLanguage 检测提问的主要语言
Amazon Translate,使用 Boto3 Translate 客户端的 TranslateText 将问题翻译成 Kendra 知识库的语言(在这次教程中为英语),并将答案翻译回最初问题的语言。
TranslateText API 需要以下参数:
- Text(String 类型):要翻译的文本。
- SourceLanguageCode(String 类型):源文本的语言代码。如果指定为 auto,Amazon Translate 将调用 Amazon Comprehend 来确定源语言。
- TargetLanguageCode(String 类型):目标语言代码。
以下是用来进行翻译的函数:
import boto3
translate_client = boto3.client('translate')
def TranslateText(text,SourceLanguageCode,TargetLanguage):
response = translate_client.translate_text(
Text=text,
SourceLanguageCode=SourceLanguageCode,
TargetLanguageCode=TargetLanguage
)
translated_text = response['TranslatedText']
source_language_code = response['SourceLanguageCode'] #you need SourceLanguageCode to answer in the original language
return translated_text, source_language_code
若想了解更多关于上述服务作为 API 调用的信息,可以访问此博客:Comprehend、Rekognition、Textract、Polly、Transcribe 和其他服务的所有功能。
注意:Amazon Translate 和 Amazon Comprehend 的免费套餐最长为 12 个月。您可以点击此处和此处分别查看定价。
要了解 Amazon Kendra 数据源中文档的语言代码,请使用 Describe Data Source API:
def get_target_language_code(data_source_id,index_id):
response_data_source = kendra_client.describe_data_source(
Id = data_source_id,
IndexId = index_id
)
return response_data_source['LanguageCode']
多语言问答智能知识库的代码为:
text = "¿que es Amazon S3?"
index_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
data_source_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
target_language_code = get_target_language_code(data_source_id,index_id)
query,source_language_code = TranslateText(text,"auto",target_language_code)
response = QueryKendra(index_id,query)
#print the result
for query_result in response["ResultItems"]:
print("-------------------")
document_title = query_result['DocumentTitle']
document_title_translated,language = TranslateText(document_title,target_language_code,source_language_code)
print("DocumentTitle: " + document_title_translated)
document_content = query_result['Content']
document_content_translated,language = TranslateText(document_content,target_language_code,source_language_code)
print("Content: ",document_content_translated)
print("Go deeper: ", query_result['DocumentURI'])
Amazon Kendra 提供了一系列答案,这些答案可能很长(图 5)。这时候对结果进行精简会不会更好?
第 4 部分 - 创建端点以调用生成式人工智能大语言模型 (LLM)
在这部分,您将使用 Amazon SageMaker JumpStart,它能为各种问题类型(包括我们的总结问题)提供预训练的开源模型,帮助您入门机器学习。最好的部分是,您还可以使用 SageMaker Python SDK 来访问模型。
总而言之,您将使用 Flan UL2 基本模型,该模型是一种基于热门的开源 LLM FLAN-T5 架构的 Text2Text 生成模型,用于:
- 文本总结
- 常识推理/自然语言推理
- 问答
- 句子/情感分类
- 翻译(在撰写本博客时,所涉及的语言比 Amazon Translate 少)
- 代词解析
♀️ 开始使用 Amazon SageMaker JumpStart:
1.打开 Amazon SageMaker 控制台
2. 在左侧导航栏中找到 JumpStart,然后选择 Foundation models(基础模型)。
3. 搜索 Flan UL2 模型,然后单击 View model(查看模型)。
4. 在 Studio 中打开笔记本
5. 使用快速设置创建一个 Sagemaker 域,这通常需要几分钟时间⏳……如果您已经创建了域和用户配置文件,您可以使用 Select domain and user profile(选择域和用户配置文件)。
6. 按照 Jupyter 笔记本中的步骤操作并在其中探索,然后等我进行到步骤 5
在 Jupyter 笔记本中,您可以了解 FLAN-T5 模型的功能。
转到 Jupyter 笔记本中的第 3 部分以部署 Sagemaker 端点。这是使用 Boto3 和 Amazon 凭证以 API 调用的形式对 ML 模型进行实时推理的调用。
获取 Sagemaker 端点的方式有两种:
model_predictor.endpoint_name
第 5 部分 - 使用 LLM 总结答案
在 Jupyter 笔记本上的步骤 5 中,您可以看到用于控制生成的文本同时执行此模型支持的推理定义的高级参数。
我们按以下方式定义参数:
import json
newline, bold, unbold = "\n", "\033[1m", "\033[0m"
parameters = {
"max_length": 50,
"max_time": 50,
"num_return_sequences": 3,
"top_k": 50,
"top_p": 0.95,
"do_sample": True,
}
其中:
- num_return_sequences:对应 LLM 将发出的每个查询的答案个数。
- max_length:模型生成的最大令牌数。
- top_k:限制随机抽样,选择概率最高的样本的 k 值。
- top_p:使用随机加权策略选择输出,该策略具有按照概率排名靠前的连续结果,累积概率 ≤ p。
- do_sample:设置为 True,因为 Flan-T5 模型使用采样技术。
要从指定端点上托管的模型获取推理,您需要使用 Amazon SageMaker 运行时的 InvokeEndpoint API,您可以使用以下函数执行这项操作:
def query_endpoint_with_json_payload(encoded_json, endpoint_name):
client = boto3.client("runtime.sagemaker")
response = client.invoke_endpoint(
EndpointName=endpoint_name, ContentType="application/json", Body=encoded_json
)
return response
要使响应具备可读性,请使用以下函数:
def parse_response_multiple_texts(query_response):
model_predictions = json.loads(query_response["Body"].read())
generated_text = model_predictions["generated_texts"]
return generated_text
要想让 LLM 生成优化答案,您需要提供由 Amazon Kendra 文档部分和用户问题组成的提示语(或代码中的 text_inputs),以便模型理解上下文。
一个好的提示语会带来好的结果。如果您想了解更多关于改进提示的信息,我留下这份 提示语工程指南。
def summarization(text,query):
payload = {"text_inputs": f"{text}\n\nBased on the above article, answer a question. {query}", **parameters}
query_response = query_endpoint_with_json_payload(
json.dumps(payload).encode("utf-8"), endpoint_name=endpoint_name
)
generated_texts = parse_response_multiple_texts(query_response)
print(f"{bold} The {num_return_sequences} summarized results are{unbold}:{newline}")
for idx, each_generated_text in enumerate(generated_texts):
#Translate the answer to the original language of the question
answer_text_translated,language = TranslateText(each_generated_text,TargetLanguage,source_language_code)
print(f"{bold}Result {idx}{unbold}: {answer_text_translated}{newline}")
return
使用 text_inputs 改进提示语,寻找最符合您需求的最佳选择。
将所有代码整合在一起,并 Build your own knowledge base with multilingual Q&A powered by Generative AI(使用生成式人工智能构建个性化多语言问答知识库)。
text = "¿que es Amazon S3?"
target_language_code = get_target_language_code(data_source_id,index_id)
query,source_language_code = TranslateText(text,"auto",target_language_code)
response = QueryKendra(index_id,query)
for query_result in response["ResultItems"]:
print("-------------------")
document_title = query_result['DocumentTitle']
document_title_translated,language = TranslateText(document_title,target_language_code,source_language_code)
print("DocumentTitle: " + document_title_translated)
document_content = query_result['Content']
document_content_translated,language = TranslateText(document_content,target_language_code,source_language_code)
print("Go deeper: ", query_result['DocumentURI'])
summarization(document_content,query)
在图 6 中,您可以看到总结文本的 3 个结果。这是因为您将 num_return_sequences 参数设置为 3:
第 6 部分 - 清理资源
如果您的初衷是为了学习,并且您不打算继续使用这些服务,那么请您务必删除它们,以避免产生不必要的费用。
删除 Amazon Kendra 索引
- 打开 Amazon Kendra 控制台。
- 在导航栏中,选择索引,然后选择要删除的索引。
- 选择“删除”来删除该索引。
删除 Amazon Sagemaker 模型和端点
在部署端点的 Sagemaker Studio 的笔记本中,运行以下代码:
# Delete the SageMaker endpoint
model_predictor.delete_model()
model_predictor.delete_endpoint()
总结
感谢您学习本教程,您可以收集本教程的所有代码,并使用生成式人工智能构建个性化多语言问答知识库。此数据库支持使用任何语言进行查询,并使用提问的语言向您回复概要,同时优先保障数据隐私。
您可以通过应用提示语工程技术来优化 LLM 的响应结果。其中一项有趣的技巧是保持前后一致性,就像我们这里所采取的方式一样,也就是对 Amazon Kendra 中最相关文档给出一致回答,然后基于所有回答使用 LLM 给出最具一致性的答案。亲自动手试试吧!
然后,您可以将代码放在 Amazon Lambda 函数中,为了提高此应用程序的性能,您可以通过合并 Amazon DynamoDB 表来引入缓存机制。在 Amazon DynamoDB 表中,您可以存储从 Amazon Kendra 获取的回复,将这些回复用作分区键,并将总结用作排序键。通过这种方法,您可以先查阅表格,然后再生成总结,从而提供更快的响应并全面优化用户体验。
以下这些链接可供您进一步学习: