AWS事業本部の梶原@福岡オフィスです。
先日作成したSlack Appに対して、Amazon Bedrockの検証の為に、応答部分を変更してAmazon Bedrock Slack Appを作成してみます。
ということで、以前作成したSlack Appをベースに
Amazon BedrockのAPIを呼び出して、回答を作成し、返信する Slack Appを作成してみます
はじめに
以下の技術、サービスを使っています。詳しくは参考情報や、リンクなどをご参照ください
- Amazon Bedrock
- 本日GAされました。リリース内容などは以下のブログなどをご参考ください
- https://dev.classmethod.jp/articles/amazon-bedrock-ga/
- https://dev.classmethod.jp/articles/breaing-news-amazon-bedrock-was-released/
- Slack (Slack Bolt for Python)
- Slack 純正のSDK
- Chalice(Python Serverless Microframework for AWS)
- ちょっと情報は少ないですが、デプロイと削除が1撃で手軽にできるので選定しました
前提条件
- AWS アカウントまた以下サービスへの権限が必要です
- Amazon Bedrock
- AWS IAM
- AWS Lambda
- Amazon API Gateway
- Amazon S3
- Slack
- アプリケーションがインストール可能なこと
事前準備
Amazon Bedrock
AWS コンソールにて、Amazon Bedrock の使用可能なモデルの確認を行って下さい。必要応じてBedrockで使用するモデルへのアクセスをリクエストしてください。
今回は、AL21 Labs の Jurassic-2 Mid を使用しますので、該当の項目が[Access granted]になっていることを確認してください
Amazon Bedrock > Model access リージョン:us-east-1
https://us-east-1.console.aws.amazon.com/bedrock/home?region=us-east-1#/modelaccess
AWS 環境設定
Chaliceでデプロイをおこなうので、事前にCredential等を設定してください
Bedrock の使用可能なリージョン us-east-1 を指定します
$ aws configure
AWS Access Key ID [None]: xxxxx
AWS Secret Access Key [None]: xxxxx
Default region name [ap-northeast-1]: us-east-1
Default output format [None]:
Pythonの環境設定
Python 3.10 の環境設定をします。
以降の処理はPython3.10 のvenv環境での実行を想定しています
$ python3.10 -m venv .venv310
$ source .venv310/bin/activate
$ python --version
Python 3.10.12
$ pip --version
pip 22.0.2 from .venv310/lib/python3.10/site-packages/pip (python 3.10)
各種pipパッケージのインストール
Slack, Chalice, Boto3, のパッケージをインストールしておきます。
※ Boto3 SDK はAmazon Bedrock の対応が含まれる 1.28.57 以上を指定してください
requirements.txt
slack_bolt
chalice
boto3 >= 1.28.57
尚、requirements.txt に記載したファイルはAWS Lambdaにデプロイされる際にLambda Layerに一緒にパッケージングされます。便利!
$ pip install -r requirements.txt
Chalice、Slackについて
このアプリケーションの元となる、Chalice, Slackの部分はこちらのエントリーでご案内していますのでご参考ください。
やってみた
Slack Bolt for Pythonのclone
実際は、Chalice の部分だけで良いのですが、まとめて取得します。
$ git clone https://github.com/slackapi/bolt-python.git
Chalice
Slack Bolt for Python にChaliceのサンプルがあるので流用します。
$ cd bolt-python/examples/aws_chalice/
メンションの応答の実装部分に、AWS Bedrock APIの処理を追加して、メンションされた内容に対して、AWS Titan モデルで回答を作成して返すようにしてみます
なお、Amazon Bedrockのコードは公開されているAWS サンプルのBedrock のワークショップのコードや、API リファレンスを参考にしています。
環境変数設定
.chalice フォルダにある Chalice(AWS Lambda)の環境変数を設定します。
Bedrockの呼び出しの権限などは、以下で設定するLambdaのロールに対して行いますので、特にここでAPIキーなどの設定は必要ありません。
現在はLambdaに含まれているboto3のバージョンが古いため、automatic_layer でboto3を含んだレイヤーを自動作成してLambaで使用します。
config.json
{
"version": "2.0",
"app_name": "bolt-chalice-bedrock",
"stages": {
"dev": {
"api_gateway_stage": "api",
"environment_variables": {
"SLACK_BOT_TOKEN": "xoxb-xxxxx",
"SLACK_SIGNING_SECRET": "xxxxxx"
},
"autogen_policy": false,
"automatic_layer": true
}
}
}
Amazon Bedrock を呼び出す際に必要なポリシーをpolicy-dev.jsonに設定します。
以下で、bedrockの呼び出しをすべて許可状態にしています。必要に応じて、権限を絞る等の対応を実施してください
{
"Effect": "Allow",
"Action": [
"bedrock:*"
],
"Resource": "*"
}
policy-dev.json
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"lambda:InvokeFunction"
],
"Resource": [
"*"
]
},
{
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:PutLogEvents"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"bedrock:*"
],
"Resource": "*"
}
]
}
実装部分
既存の処理はSlackアプリに対して、メンションされた場合(”app_mention”)に、say()でメッセージを返していますので、この部分に変更を行います
元のコード
@bolt_app.event("app_mention")
def handle_app_mentions(body, say, logger):
logger.info(body)
say("What's up? I'm a Chalice app :wave:")
Bedrockを使用してメンションの内容から返信を作成するコードに置き換えます
- メンションでAppが受け取ったメッセージからメンション部分を削除
- Bedrock で AL21 Labs の Jurassic-2 Mid モデルを使用して応答を生成
- スレッドに返信する
<br />import boto3
import botocore
logging.info(f"boto3={boto3.__version__}, botocore={botocore.__version__}")
@bolt_app.event("app_mention")
def handle_app_mentions(body, say, logger):
logger.info(body)
event = body["event"]
channel = event["channel"]
ts = event["ts"]
# Slackでメンションを受け取ったらメッセージからメンションを取り除く
mention_text = re.sub(r'<@.*?> ', "", event["text"])
# 応答を生成
# Bedrock Clientの作成
bedrock_client = boto3.client('bedrock-runtime')
titanInputText = f"{mention_text}\n"
bedrock_body = {
"prompt": titanInputText,
"maxTokens": 200,
"temperature": 0.7,
"topP": 1,
}
body_bytes = json.dumps(bedrock_body).encode('utf-8')
response = bedrock_client.invoke_model(
accept="*/*",
body=body_bytes,
contentType="application/json",
modelId="ai21.j2-mid-v1",
)
resp_body = response["body"].read()
resp_body_json = json.loads(resp_body.decode('utf-8'))
logging.info(resp_body_json["completions"][0]["data"]["text"])
text_prompts = resp_body_json["completions"][0]["data"]["text"]
# スレッドに返信
say(f"{text_prompts}", thread_ts = ts)
デプロイ
新しいBoto3を含んだLambdaのLayerも自動で作成して、更新デプロイしてくれるのでとても助かります。
$ chalice deploy
...
Creating Rest API
Resources deployed:
- Lambda Layer ARN: arn:aws:lambda:us-east-1:123456789012:layer:bolt-chalice-bedrock-dev-managed-layer:1
- Lambda ARN: arn:aws:lambda:us-east-1:123456789012:function:bolt-chalice-bedrock-dev
- Rest API URL: https://hoge.execute-api.ap-northeast-1.amazonaws.com/api/
動作確認
インストールが正常にいけば、任意の部屋に追加したSlack Appを追加して、メンションしてください。
以下のようにBedrock API からの答えが生成されており、スレッドに返信されていれば成功です
リソース削除
以下コマンドでAWS上のリソースはきれいに削除できます
$ chalice delete
まとめ
以前作ったSlack App を流用して、さくっとBedrock API 使ってSlack App を作成してみました。 Bedrock ではほぼ同じ、APIのインターフェースで様々なモデルがよべるようになるので、いろいろなバリエーションができるかと思います。
プロンプト検証は、Jypter Notebook(SageMaker)などで、行うことが多いと思いますが、デモや共有して検証して貰う際などに流用できるかと思います。
参考情報
Chalice