はじめに
Amazon Q BedrockとBedrockを使って、Slackチャットボットを作りたいと思いました。
Bedrockに関する以下記事を参考にやってみることにしました。
CloudFormationのデプロイやOpenSearchのIndex作成は、まとめてTerraformでできるようにしました。
OpenSearchは料金が安くなるようマネージドクラスターを使用しました。
コードは以下格納しています。
構成図
今回作るものの構成図は以下の通りです
データソースにはS3を指定し、試しにLambdaからデータソースの同期をできるようにしてみました。
また、RAGに入れたいでデータがGitHubにあったので、そこから取れるようにしています。
デプロイの流れ
Terraformコマンドで構築できるようにしました。
terraform init
terraform plan
terraform apply
※前提としてLambdaに使用するPythonパッケージの用意が必要です。
terraform apply
では以下の流れが実行されます。
- スタックtemplate.yamlによるOpenSearchドメインの作成
- OpenSearchのインデックスの作成
- スタックbedrock-template.yamlによるBedrockリソースの作成
- スタックlambda-template.yamlによるS3にデータをアップロードするLambdaの作成
CloudFormationスタックファイルの概要
CloudFormationスタックファイルで作成するAWSリソースは以下の通り
スタックファイル名 | リソース名 | リソースの種類 | 役割の概要 |
---|---|---|---|
template.yaml | BedrockAgentInSlackPolicy | AWS::IAM::ManagedPolicy | Bedrock Agent用のIAMポリシー |
BedrockAgentInSlackRole | AWS::IAM::Role | Chatbot用のIAMロール | |
SlackChannelConfiguration | AWS::Chatbot::SlackChannelConfiguration | SlackチャンネルとAWS Chatbotの連携設定 | |
OpenSearchRole | AWS::IAM::Role | OpenSearch用のIAMロール | |
BedrockOpenSearchRole | AWS::IAM::Role | BedrockがOpenSearchにアクセスするためのIAMロール | |
KnowledgeBaseBucket | AWS::S3::Bucket | ナレッジベース用のS3バケット | |
OpenSearchDomain | AWS::OpenSearchService::Domain | ベクトル検索用のOpenSearchドメイン | |
bedrock-template.yaml | BedrockKnowledgeBase | AWS::Bedrock::KnowledgeBase | Bedrockナレッジベース |
BedrockDataSource | AWS::Bedrock::DataSource | S3データソース | |
BedrockAgent | AWS::Bedrock::Agent | Bedrockエージェント | |
BedrockAgentAlias | AWS::Bedrock::AgentAlias | Bedrockエージェントエイリアス | |
BedrockAgentRole | AWS::IAM::Role | Bedrockエージェント用のIAMロール | |
BedrockAgentPolicy | AWS::IAM::ManagedPolicy | Bedrockエージェント用のIAMポリシー | |
lambda-template.yaml | GitHubRepoUrlParameter | AWS::SSM::Parameter | GitHubリポジトリURL用のSSMパラメータ |
GitHubPATParameter | AWS::SSM::Parameter | GitHub Personal Access Token用のSSMパラメータ | |
GitHubUsernameParameter | AWS::SSM::Parameter | GitHubユーザー名用のSSMパラメータ | |
LambdaExecutionRole | AWS::IAM::Role | Lambda実行用のIAMロール | |
GitHubToS3SyncFunction | AWS::Lambda::Function | GitHubからS3への同期処理を行うLambda関数 | |
ScheduledRule | AWS::Events::Rule | Lambda関数を定期実行するEventBridgeルール | |
PermissionForEventsToInvokeLambda | AWS::Lambda::Permission | EventBridgeがLambdaを実行するための権限 |
CloudFormationスタックファイルの詳細
lambda-template.yamlはbedrock-template.yamlに含めても問題ありませんが、今後のカスタマイズを考慮し、分けることにしました。
OpenSearchのIndexを作成する
OpenSearchドメイン作成後、Bedrockナレッジベースで使用するベクトルインデックスを作成します。
インデックスのmappingを含むJSONはindex.jsonとしています。
また、OpenSearchへの認証にはパスワードではなく、IAMロールを使用するようにしました。
terraform {
required_version = ">= 1.0.0"
required_providers {
opensearch = {
source = "opensearch-project/opensearch"
version = "~> 2.0"
}
}
}
provider "opensearch" {
url = module.main_stack.opensearch_endpoint != "" ? "https://${module.main_stack.opensearch_endpoint}" : ""
aws_region = var.aws_region
aws_assume_role_arn = module.main_stack.bedrock_opensearch_role_arn
insecure = true
opensearch_version = "2"
}
resource "opensearch_index" "bedrock_index" {
name = "bedrock-index"
index_knn = true
mappings = file("${path.module}/../../src/index.json")
number_of_replicas = "1"
number_of_shards = "1"
force_destroy = true
}
SlackにてBedrock Agentに接続する
デプロイ後にSlackからBedrock Agentに接続するためのメッセージを行う必要があります。
outputs.tfにて送信するメッセージが出るようにしました。
output "slack_connect_agent" {
description = "ARN of the Slack Connect Agent"
value = "@Amazon Q connector add agent ${module.bedrock_stack.agent_arn} ${module.bedrock_stack.alias_id}"
}
おわりに
今回は記事、構成図の作成を含めて、生成AIを使うように意識しました。
記事作成の労力が減った分、「本当に価値がある記事か」を考えることとなりました。
どのようにアウトプットしていくか考えながら、勉強していけたらなと思います。