免责声明:本文中利用的会议记录纯属虚构,仅用于作为本文解释和教诲目的。
它并不反响任何实际的对话、事宜或个人。
任何与实际人物或事宜的相似之处纯属巧合。
本文概述的项目涉及利用多种 Amazon Web Services (AWS),详细来说包括 Amazon S3、Amazon API Gateway、AWS Lambda 和 Amazon Bedrock。

您是否曾在事情场所参加过看似多余乃至毫无意义的会议?对付我们大多数企业员工来说,答案无疑是肯定的。
我每周都会参加至少一次这样的会议。
有些星期,我的日程安排得满满的,险些没有韶光完成任务。
末了,我只能在静音状态下开始处理任务。
偶尔,我会错过一些与我有关的主要事情,以是我不得不重新开始心神专注。
这可能会让人非常沮丧,由于在整整一个小时内,可能只有几秒钟的对话与您有关。

随着天生式 AI 运用程序的涌现,我再也不用担心自己会陷入这些情形了!
在本文中,我将勾引读者理解如何利用 AWS Bedrock、AWS Lambda、AWS API Gateway 和 AWS S3 构建可扩展的管道,利用天生式 AI 产品来总结会议记录。

为什么选择 AWS

假设您熟习 ChatGPT 等天生式 AI 运用程序。
既然您可以将笔墨记录复制并粘贴到 ChatGPT 中并在几秒钟内天生择要,为什么还要利用 AWS?此外,一些运用程序已经可以做到这一点,如果没有包含在内,您可以将其添加到桌面。
这样做的缘故原由有很多,但我将重点先容个中最主要的两个:可扩展性安全性

提高工作效率 AWS Gen AI 在几秒钟内总结会议记录

可扩展性

作为一个云平台,AWS 许可用户、企业、实体等大规模构建运用程序和存储数据。
对付我们在本文中谈论的用例,AWS 中的会议记录择要运用程序可以扩展为在公司内拥有险些无限数量的终极用户,从会议记录的来源处直接输入到 AWS 的内部管道,并优化记录和天生的择要的存储本钱和容量。
此外,您可以自定义提示、输出令牌和许多其他参数。

安全

之前,我提到过,人们可以通过复制和粘贴笔墨记录来利用 ChatGPT 天生择要;这会违反许多安全最佳实践,如果关键数据透露,你乃至可能在某些情形下承担任务。
借助 AWS,可以设置必要的权限和防护方法,这样人们就可以充分利用天生式 AI 运用程序,而不必担心公司内部数据穿越公共网络。
现在,事不宜迟,让我们直接进入这个项目。

第 1 部分:创建 S3 存储桶

我们将从创建 S3 存储桶开始。
S3 是 AWS 供应的工具存储做事,许可用户快速大规模存储数据。
它还可以与 AWS 的许多其他做事和第三方运用程序集成。

要导航到 S3,请在搜索栏中搜索它,单击阁下的做事菜单,或者如果您以前利用过它,请在最近访问的部分中找到它。

图片由作者供应

进入 S3 页面后,单击创建存储桶。

图片由作者供应

为存储桶命名,其他选项保持不变。
如上图所示,我将存储桶命名为bedrock-text-summarization。
请把稳,所有存储桶名称都必须是全局唯一的,这意味着任何 AWS 账户中都不能有两个存储桶具有相同的名称。

第 2 部分:创建 boto3 层

截至撰写本文时,AWS Lambda 还没有最新版本的 boto3(适用于 Python 的 AWS SDK)。
因此,我们必须创建一个 boto3 层并将其上传到 AWS。
这确保我们拥有适当的库来调用 AWS Bedrock。
这个过程相对大略;但是,如果您从未利用过 Windows 命令提示符,则可能须要一些韶光。
请把稳,以下命令不适用于 Linux 系统。

首先,打开 Windows 命令提示符并分别运行以下命令。
如果这是您第一次这样做,安装 boto3 包可能须要一些韶光。

## 为您的 boto3 层创建一个新目录mkdir boto3_layer ## 将其设置为主目录cd boto3_layer ## 创建一个名为“python”的目录mkdir python ## 在 python 目录中创建一个虚拟环境python3 -m venv venv ## 激活虚拟环境venv/bin/activate ## 将 boto3 安装到环境中pip install boto3 -t ./python ## 停用虚拟环境deactivate

完成后,我选择按照以下步骤手动压缩 Python 文件:

1. 打开文件资源管理器并导航到包含要压缩的文件夹的目录(在本例中,是我们创建的 boto3_layer 内的 python 文件夹)。

2. 右键单击​要压缩的 python 文件夹。

3.从高下文菜单中选择“发送到” 。

4. 点击“压缩文件夹”

得到压缩文件夹后,导航到 Lambda 主页并单击左侧菜单中的“层” 。

图片由作者供应

您必须命名您的层并从此时上传您的压缩文件夹。
此外,请确保选择精确的兼容运行时。
在本例中,我将选择最新版本的 Python;但是,如果您操持在脚本中包含早期版本的 Python 中的库/函数/等,您还必须确保已启用它们。

图片由作者供应

第 3 部分:要求 Bedrock 访问权限

Bedrock 是 AWS 内的一个独特做事。
简而言之,它是一个 API,许可用户连接到来自领先 AI 公司的许多根本模型。
要利用个中任何模型,您都须要要求访问权限。
导航到 Bedrock 主页并选择左下角的“模型访问” :

图片由作者供应

进入模型访问页面后,您必须单击要访问的特定模型。
在这个项目中,我们利用Anthropic 的Claude 。
导航到此部分,在 Anthropic 供应的每个产品阁下,您该当会看到一个链接,上面写着:可供要求。
请把稳,不才面的屏幕截图中,我已经拥有访问权限,因此您的屏幕可能看起来不是这样的。
单击此处并完成必要的步骤。
实际的批准过程只须要几分钟。
我建议通读您利用的任何模型的文档和定价。
出于我们的目的以及在撰写本文时,我们将利用的 Claude 版本每 1,000 个输入令牌花费 0.008 美元,每 1,000 个输出令牌花费 0.024 美元。
我们的全体事情流程一次利用最多只需几美分,但要知道,如果欠妥心,任何重复利用都可能很快增加本钱。

图片由作者供应

第 4 部分:创建 Lambda 函数

AWS Lambda 是 AWS 供应的无做事器打算做事。
它与 AWS 的许多其他做事集成在一起。
我将其视为 AWS 的集中式编排工具。
例如,每当将新数据上传到特定的 AWS S3 存储桶(云存储做事) 时,您都可以配置 lambda 函数以将演习作业发送到 AWS SageMaker(机器学习演习和模型托管做事)以启动模型演习作业。
这只是 AWS Lambda 无数可能性之一。

对付这个项目,我们将利用 Lambda 向 AWS Bedrock 发送一个带有会议择要记录的提示,该提示将天生会议择要以及记录等分配给特定利益干系者的后续行动。
然后,Lambda 会将天生的择要发送到我们之前创建的 S3 存储桶。
我将在本节末端发布完全的 Lambda 函数代码。

首先,导航到 Lambda 函数页面并单击“函数”。
从那里,您只需命名您的函数并选择必要的运行时,在我们的例子中,它将是最新版本的 Python。

图片由作者供应

您的屏幕现在该当如下图所示:

图片由作者供应

接下来,我们将添加 boto3 层。
导航到页面底部查看“层”部分。
单击“添加层”。
这将带您进入以下页面:

图片由作者供应

从这里,选择自定义层,然后选择我们上传的 boto3 层。
您还将看到另一个下拉菜单,指定哪个版本;选择1,然后单击添加按钮。

现在我们已经添加了层,您可以导航到代码源窗口开始编写我们的函数。
我将在本文末端链接完全 Lambda 函数的 GitHub 要点;但是,我将在这里逐一分解。

讽刺的是,我们的 Lambda 函数将结合一系列较小的函数来折衷我们的完全事情流程。
我们的第一个函数将从文档中提取纯文本。
换句话说,任何可读的文本都将从文档中提取。
这是必要的,由于文档可能充斥着我们不一定须要的噪音。

def extract_text_from_multipart (数据): msg = message_from_bytes(数据) text_content = "" 如果msg.is_multipart(): 对付msg.walk()中的一部分: 如果part.get_content_type() == "text/plain" : text_content += part.get_payload(decode= True ).decode( 'utf-8' ) + "\n" 其他: 如果msg.get_content_type() == "text/plain" : text_content = msg.get_payload(decode= True ).decode( 'utf-8' )如果text_content则 返回text_content.strip()否则无

接下来,我们将创建一个函数来发送文本和调用 AWS bedrock 的提示。
对付实际模型,我们将利用 Anthropic 的 Claude V2。
请把稳,您可以轻松编辑提示文本以知足您的特定需求。
记下字典主体
在这里我们可以为调用的 AI 模型指定参数。
不熟习这些参数?别担心!
我将不才面分解它们:

max_tokens_to_sample:这是运用程序将采样的最大标记数,或者更实际地说,这是模型将读取的最大单个单词和/或数字数。
top_k:对付模型天生的每个标记,它会考虑最有可能的“下一个”标记列表。
较低的值将缩小标记的选择范围,而较高的值将许可模型考虑更广泛的选择范围。
top_p:与 top_k 非常相似;但是,它利用概率分布逻辑。
例如,如果我们选择 0.1,模型将考虑最有可能的前 10% 个标记。
stop_sequences:实质上是模型的停滞点。
如果模型碰着您指定的停滞点,它将在该序列之后停滞天生。

您还可以在此处查看正式文档!

def generate_summary_from_bedrock ( content:str ) -> str: prompt_text = f“”“Human:总结以下会议记录并列出详细的后续行动以及谁该当采纳这些行动:{content} Assistant:“”“ body = { “prompt”:prompt_text, “max_tokens_to_sample”:5000, “top_k”:250, “top_p”:0.2, “stop_sequences”:[ “\n\nHuman:” ] } try: bedrock = boto3.client(“bedrock-runtime”,region_name = “us-east-1”,config = botocore.config.Config(read_timeout = 300,retries = { 'max_attempts':3 })) response = bedrock.invoke_model(body=json.dumps(body),modelId= "anthropic.claude-v2:1" ) response_content = response.get( 'body' ).read().decode( 'utf-8' ) response_data = json.loads(response_content) summary = response_data[ "completion" ].strip() return summary except Exception as e: print ( f"天生择要时出错:{e} " ) return ""

我们调用的模型的相应须要一个位置来发送会议择要。
因此,我们将构建一个将其发送到 S3 存储桶的函数。

## 将输出保存到给定的 S3 存储桶def save_summary_to_s3_bucket ( summary, s3_bucket, s3_key ): s3 = boto3.client( 's3' ) try : s3.put_object(Bucket = s3_bucket, Key = s3_key, Body = summary) print ( "择要已保存到 s3" ) except Exception as e: print ( "将择要保存到 s3 时出错" )

末了,我们将创建Lambda Handler函数,它是 Lambda 函数的核心。
Lambda Handler充当调用 Lambda 函数时的入口点;因此,我们将利用我们在处理程序中创建的所有函数。

def lambda_handler(event,context): decoded_body = base64.b64decode(event [ 'body' ]) text_content = extract_text_from_multipart(decoded_body) if not text_content: return { 'statusCode':400, 'body':json.dumps(“无法提取内容”) } summary = generate_summary_from_bedrock(text_content) if summary: current_time = datetime.now()。
strftime('%H%M%S')#UTC 韶光,不一定是您的时区 s3_key = f'summary-output/ {current_time} .txt's3_bucket = 'bedrock-text-summarization'save_summary_to_s3_bucket (summary,s3_bucket,s3_key) else: print(“无择要已天生”) return { 'statusCode' : 200, 'body' :json.dumps(“择要天生完成”) }

我们的函数可能已经完成;但是,我们必须进行一些小配置。
当我们调用我们的基岩模型时,可能须要几秒钟乃至一分钟才能天生择要,详细取决于我们发送的成绩单的大小。
因此,我们将 Lambda 函数的超时设置为最多四分钟,以确保我们的函数不会超时。
为此,请导航到底部的配置菜单,单击左侧的常规配置,然后单击窗口中的编辑
之后,您该当会看到如下所示的屏幕。
确保超时设置为四分钟。

图片由作者供应

第 5 部分:创建 API

正如AWS API Gateway 主页上所述,我们将在这里构建会议记录择要天生器的前门。
利用 API Gateway,我们将构建一个具有 POST 方法的 API,许可我们将数据发送到 Lambda 函数。

首先,导航到 AWS API Gateway 主页并单击创建 API。

图片由作者供应

接下来,单击HTTP API窗口中的“构建”,由于这种类型的 API 最适宜我们的特定用例。

图片由作者供应

命名并单击“下一步”。

图片由作者供应

连续单击下一步,直到进入“查看和创建”页面。
单击“创建”。
您现在该当位于“路线”页面,该页面应如下所示。
单击左侧窗口中的“创建” 。

图片由作者供应

我们将在这里创建 POST 路由,以便我们利用 API 将数据发送到我们的运用程序。
从下拉列表中选择 POST 并为其命名。

现在您该当回到“路线”页面。
单击右上角的“支配” 。
将涌现如下所示的弹出窗口。
单击“创建新阶段”,
以蓝色突出显示。

我们将在此创建开拓阶段。
请把稳,我们不一定须要实行此步骤;这只是一个实际项目。
但是,在开拓生命周期中为运用程序支配设置不同的阶段是一种很好的做法。
在运用程序面向客户之前,这些阶段充当制衡系统。
将此阶段命名为dev(或您喜好的任何名称),并确保未启用自动支配。

创建开拓阶段后,我们还没有完成。
您该当在Stages页面上。
在单击支配之前,我们仍旧须要集成我们的 Lambda 函数。
单击左侧窗口中的Integrations 。

单击“POST”,然后单击“创建并附加集成”。

图片由作者供应

在集成类型下选择Lambda 函数,然后不才一个下拉菜单中选择我们的 Lambda 函数。
确保 AWS 区域与您的 Lambda 函数相同,否则您在调用 API 时会碰着缺点。

现在,单击右上角的支配,然后在弹出窗口中选择开拓。
此时,API 已正式支配,并带有我们可以调用的 URL。
单击左侧菜单中开拓部分上方的链接,它将导航到我们可以找到调用 URL 的页面。
请把稳,这些 URL 是实时的,因此只要有 URL,任何人都可以利用它们,并且我们没有添加任何必要附加的权限/令牌(因此,我在发布本文之前删除了我的 URL)。
话虽如此,我还是要谨慎,由于它会调用须要费钱的做事。

第 6 部分:将所有内容整合在一起!

现在到了大略而又令人愉快的部分!
是时候将我们的项目付诸实践了。
我们只需调用一次 API 即可得到会议择要。
要调用我们的运用程序,我们将利用Postman。
请把稳,我们可以利用许多技能来调用我们的 API,但我创造 Postman 最适宜我们的目的。
这在现实天下中可能会通过与贵公司的会议软件无缝集成的前端运用程序来完成。

在 Postman 主页上,点击Workspaces并创建一个新的事情区。
当您看到下面的下拉窗口时,选择HTTP 。

您现在该当看到一个如下图所示的窗口。

我们正在利用 API 发送数据;因此,我们必须选择GET阁下的下拉菜单并将其变动为POST。
要获取 API 的 URL,请导航回我们创建开拓阶段 API 后进入的页面。
复制并粘贴我们开拓阶段的调用 URL,然后将其粘贴到 Postman 事情区中的 POST 阁下
以下屏幕截图可作为获取 URL 的参考:

除了复制粘贴我们的 API 之外,我们还须要添加我们之前创建的会议择要路由。
在我们的 Postman 事情区中,将 /meeting-summary 添加到 URL 末端。
以下屏幕截图供参考:

接下来,单击Body,然后选择form-data。
在 Key下键入document,然后在键入document 的位置右侧的下拉菜单中选择file
然后,您将在此处上传会议记录。
对付这个项目,我决定找点乐子,让 Chat GPT 天生一份关于一家 AI 公司的虚假会议记录,该公司的 Gen AI 运用程序具有自我意识。
点击发送之前,我们的 Postman 事情区该当是什么样子的屏幕截图,以及我们发送的记录的简要预览如下!

现在是时候点击发送了!
如果我们的申请成功,我们该当在 Postman 中看到以下相应:

关于调试 Lambda 函数的解释

当我最初构建此运用程序时,第一次运行失落败了。
您的运用程序很可能在第一次考试测验时失落败,以是如果是这种情形,请不要担心。
我还没有碰着过在第一次测试运行时就构建成功的模型、产品、运用程序等的开拓职员或数据科学家。

如果存在问题,它很可能会在 Lambda 函数中显示出来。
要调试它,请导航到 AWS Cloudwatch,单击日志组,然后单击我们的 Lambda 函数。
导航到日志流部分,它将显示我们 Lambda 函数的任何运行的相应。
这是缺点处理派上用场的地方。
我在第一次运行时碰着的一些问题包括我的代码中的小拼写缺点以及 API、Lambda 和 S3 之间的不匹配区域。
如果您有任何问题,它们可能与我的不同;但是,这些可能是值得把稳的良好出发点。
下面的屏幕截图供参考:

图片由作者供应

成功运行运用程序后,您的 S3 存储桶中该当会有一个 txt 文件。
导航到 S3,选择我们最初创建的存储桶,然后单击以查看新天生的文件。
选择下载并查看输出!
以下是我天生的内容,供参考:

令人印象深刻!
你不这么认为吗?几秒钟内,该运用程序就天生了一份择要和详细后续行动,并分配了关键利益干系者。
我知道这是一份假的会议记录,但想象一下,利用这样的运用程序可以节省多少韶光。

结论

我必须大力感谢 Patrik Szepesi 和他的Udemy 课程,该课程先容了 AWS 中的天生式 AI,它勉励我连续这个项目并撰写了这篇文章。
它还勉励我开始研究一些个人用例,我希望这篇文章可以鼓励读者也这样做!
我希望您创造这些内容对您的 AI 工程之旅很有代价。
如果您有任何问题或想给我发送反馈,请随时揭橥评论!

下面是完全的 Lambda 函数

import boto3

import botocore.config

import json

import base64

from datetime import datetime

from email import message_from_bytes

## Extract text of text/plain type from the given document and decode it

def extract_text_from_multipart(data):

msg = message_from_bytes(data)

text_content = ""

if msg.is_multipart():

for part in msg.walk():

if part.get_content_type() == "text/plain":

text_content += part.get_payload(decode=True).decode('utf-8') + "\n"

else:

if msg.get_content_type() == "text/plain":

text_content = msg.get_payload(decode=True).decode('utf-8')

return text_content.strip() if text_content else None

## Calls on AWS bedrock with a given prompt and parameters and returns the output from bedrock. Note that the function expect a string and returns a string

def generate_summary_from_bedrock(content:str) ->str:

prompt_text = f"""Human: Summarize the following meeting transcript and list the specific follow up actions along with who should take those actions: {content}

Assistant:"""

body = {

"prompt":prompt_text,

"max_tokens_to_sample":5000,

"top_k":250,

"top_p":0.2,

"stop_sequences": ["\n\nHuman:"]

}

try:

bedrock = boto3.client("bedrock-runtime",region_name="us-east-1",config = botocore.config.Config(read_timeout=300, retries = {'max_attempts':3}))

response = bedrock.invoke_model(body=json.dumps(body),modelId="anthropic.claude-v2:1")

response_content = response.get('body').read().decode('utf-8')

response_data = json.loads(response_content)

summary = response_data["completion"].strip()

return summary

except Exception as e:

print(f"Error generating the summary: {e}")

return ""

## Saves the output to a given S3 bucket

def save_summary_to_s3_bucket(summary, s3_bucket, s3_key):

s3 = boto3.client('s3')

try:

s3.put_object(Bucket = s3_bucket, Key = s3_key, Body = summary)

print("Summary saved to s3")

except Exception as e:

print("Error when saving the summary to s3")

def lambda_handler(event,context):

decoded_body = base64.b64decode(event['body'])

text_content = extract_text_from_multipart(decoded_body)

if not text_content:

return {

'statusCode':400,

'body':json.dumps("Failed to extract content")

}

summary = generate_summary_from_bedrock(text_content)

if summary:

current_time = datetime.now().strftime('%H%M%S') #UTC TIME, NOT NECCESSARILY YOUR TIMEZONE

s3_key = f'summary-output/{current_time}.txt'

s3_bucket = 'bedrock-text-summarization'

save_summary_to_s3_bucket(summary, s3_bucket, s3_key)

else:

print("No summary was generated")

return {

'statusCode':200,

'body':json.dumps("Summary generation finished")

}

感谢关注雲闪天下。
(Aws办理方案架构师vs开拓职员&GCP办理方案架构师vs开拓职员)

订阅频道(https://t.me/awsgoogvps_Host)TG互换群(t.me/awsgoogvpsHost)