Amazon Bedrockハンズオン:Knowledge base、Agentを使用してRAGを構築し、回答をSlack通知させてみた
おはようございます!ベンジャミンの木村と申します!
AWS最大のカンファレンスイベントであるre:Invent2023に参加し、そこで発表されたAmazon BedrockのKnowledge baseとAgentを使用してRAGを構築したので、ここで構築手順を紹介させて頂けたらと思います!
内容は、外部公開されていない弊社情報をAmazon Bedrockにインプットさせ、質問の回答をSlackに通知させてみる、といったものになります。
目次
- Amazon Bedrockとは
- RAGとは
- 1. IAMユーザーを作成してログイン
- 2. Amazon Bedrockのモデルアクセスを申請
- 3. SNSの作成
- 4. Lambdaの作成
- 5. S3の作成
- 6. Knowledge base for Amazon Bedrockの作成
- 7. Agents for Amazon Bedrockの作成
- 8. AgentがLambdaを操作するためのリソースベースポリシーの設定
- 9. Bedrockに質問してみよう!
- 10. リソースの削除(絶対やってね!)
Amazon Bedrockとは

AmazonやAIスタートアップ企業が提供するすでに出来上がったFM(基盤モデル)をAPIを通じて利用できるようにするAWSマネージドサービスです。FM(基盤モデル)については下記をご参照ください。
このブログが書かれている時点(2024/1/13)でBedrockにて利用可能なFMは以下になります。
- Amazon Titan(テキスト生成、分類、質疑応答など)
- AI21 Labs Jurassic(質疑応答、テキスト、要約など)
- Anthropic’s Claude(対話やコーディング向けのFM)
- Cohere Command & Embed(テキストベースの応対など)
- Meta Llama 2(対話のユースケースなど)
- Stable Diffusion XL(画像生成モデルなど)
RAGとは

RAG(Retrieval Augmented Generation)とは、あらかじめ用意したデータストアから事実を検索して、最新の正確な情報に基づいて大規模言語モデル(LLM)に 回答を生成させることです。
いくら優秀なスタートアップが作ったFM(基盤モデル)といえど、外部に公開されていないデータや、最新の情報まではインプットされていないため、その場合は古い情報の回答を返したり、事実と異なる回答を返すことがあります。これをハルシネーションといいます。
FMに質問する前に、事前に外部公開されていないデータや最新の情報をデータストアにインプットしておくことで、FMはデータストアに保存されている正確&最新の情報を利用して回答を生成するようになり、ハルシネーションが軽減されます。
1. IAMユーザーを作成してログイン
※rootユーザーではなく、IAMユーザーでログインしないとBedrock操作時にエラーになります。
1-1.下記URLよりの IAMコンソール画面に移動
https://us-east-1.console.aws.amazon.com/iam/home?region=us-east-1#/users
1-1. 左ペインの「ユーザー」→表示されたボタンで「ユーザーの作成」をクリック

1-2. 以下の通り入力し、「次へ」をクリック
- ユーザー名:任意の名前
- マネージメントコンソールへのユーザーアクセスを提供する:有効
- コンソールパスワード:自動生成されたパスワード
- ユーザーは次回のサインイン時に新しいパスワードを作成する必要があります:有効

1-3. 以下の通り入力し、「次へ」をクリック
- 許可オプション:ポリシーを直接アタッチする
- 許可ポリシー:AdministratorAccess

1-4. 設定内容を確認して、「ユーザーの作成」をクリック

1-5. 表示された下記事項を控え(もしくはcsvをダウンロードし)、「ユーザーリストに戻る」をクリック
- コンソールサインインURL
- ユーザー名
- コンソールパスワード

1-6. 右上にあるアカウント情報をクリックし、「サインアウト」する

1-7. 1-5で控えた「コンソールのURL」をブラウザに入力し、表示された画面で「ユーザー名」、「パスワード」も入力し、「サインイン」をクリックする

1-8. 「パスワード」を変更し、「パスワードの変更を確認」をクリックする

1-9. コンソールにログインできれば完了

2. Amazon Bedrockのモデルアクセスを申請
Amazon BedrockのFMを使用する前に、FMの使用許可の申請が必要になります。今回はAnthropic’s Claudeをだけ申請します。
2-1. 下記URLよりのAmazon Bedrockコンソール画面に移動
※リージョンはバージニア北部にする必要があります。
https://us-east-1.console.aws.amazon.com/bedrock
2-2. 左ペインの「モデルアクセス」をクリックし、「モデルアクセスを管理」をクリック

2-3. 表示された画面で「ユースケースの詳細を送信」をクリック

2-4. 以下の通り入力し、「送信」をクリック
- 会社名:自分の会社名
- ウェブサイトURL:自分の会社のURL
- どの業界ですか?:自分の所属する業界
- 対象ユーザー:ハンズオンで使用なら「社内の従業員」を選択
- 目的は?:ハンズオンで使用なら「上記のいずれでもない」を選択
- ユースケース:ハンズオンで使用ならそのまま「ハンズオン」と記入

※生成された情報を何に使うか(ミッションクリティカルなことに使わないか等)を確認する項目になります。
2-5. 「Anthoropic」と「Amazon」を選択し、「モデルアクセスをリクエスト(もしくは「変更を保存」)」をクリック
※ここにチェック入れないと、Knowledgebaseの検証でロールエラーとなります。

2-6. ステータスが「進行中」から「アクセスが付与されました」に変更されたら、申請完了
※申請までに少し時間がかかります。(1~10分ほど)

3. SNS作成
それではまず、通知先を指定したいと思います。
通知先に用いるのはSlackのメールアドレスになります。Slackチャンネルのメールアドレスの取得方法は下記を参照ください。
3-1. 下記URLよりSNSのコンソール画面に移動
https://us-east-1.console.aws.amazon.com/sns
※リージョンはバージニア北部にしてください。
3-2. 左ペインの「トピック」をクリックし、「トピックの作成」をクリック

3-3. 以下の通り入力し、「トピックの作成」をクリック
- タイプ:スタンダード
- 名前:任意
- 表示名:任意(入力しなくてもOK)
※その他はデフォルト値

3-4. サブスクリプションの作成をクリック

3-5.以下の通り入力し、「サブスクリプションの作成」をクリック
- トピックARN:先ほど作ったSNSのARN(手順通りならすでに選択されている)
- プロトコル:Eメール
- エンドポイント:通知を送りたいSlackのメールアドレス
その他はデフォルト値

3-6.Slack側にメールが届くので、本文の「Confirm subscription」リンクをクリック

3-7. 下記にように表示されればSNSの作成は完了
※「click here to unsubscribe」は絶対に押さないように注意してください。Slack通知されなくなります。

4. Lambdaの作成
※こちらのLambdaは、Bedrockから来た回答をSNS経由でSlackに通知する機能になります。
4-1. 下記URLよりLambdaのコンソール画面へ移動
https://us-east-1.console.aws.amazon.com/lambda/
※リージョンはバージニア北部にしてください。
4-2. 左ペインの「関数」をクリックし、「関数の作成」をクリック

4-3.設定値を以下の通り入力し、「関数の作成」をクリック
- オプション:一から作成
- 関数名:任意
- ランタイム:Python 3.12(2024/2/9 最新バージョン)
他の値はデフォルト

4-4. 「コード」をクリックし、以下コードをコピー&ペーストして「デプロイ」をクリック

コードは下記より参照(SNSトピックのARNは項番3で作成したSNSのものを使用ください)
【re:Invent 2023】Agents for Amazon Bedrockで生成AIアプリの可能性を広げようimport boto3 import json def lambda_handler(event, context): api_path = event["apiPath"] if api_path == '/send-slack': param = event['requestBody']['content']['application/json']['properties'] title = next(item for item in param if item['name'] == 'title')['value'] message = next(item for item in param if item['name'] == 'message')['value'] body = send_slack(title, message) response_body = {"application/json": {"body": json.dumps(body, ensure_ascii=False)}} action_response = { "actionGroup": event["actionGroup"], "apiPath": event["apiPath"], "httpMethod": event["httpMethod"], "httpStatusCode": 200, "responseBody": response_body, } api_response = {"messageVersion": "1.0", "response": action_response} return api_response def send_slack(title, message): sns_client = boto3.client('sns') # SNSトピックにメッセージをパブリッシュ response = sns_client.publish( TopicArn="<SNSトピックのARN>", # 例:TopicArn="arn:aws:sns:us-east-1:1111111:Bedrock-slack-test-kim" Message=message, Subject=title ) return response
4-5. 「設定」→「アクセス権限」→「IAMロール名」をクリック

4-6. 表示されたIAMロールで「許可を追加」→「ポリシー」をアタッチをクリック

4-7. 表示された画面で「AWSLambdaBasicExecutionRole」,「AmazonSNSFullAccess」を選択し、「許可を追加」をクリック(以上でLambda作成完了)

5. S3の作成
5-1. 下記URLよりS3のコンソール画面へ移動
https://s3.console.aws.amazon.com/s3
5-2. 「バケットの作成」をクリック

5-3. 以下の通り入力し、「バケットを作成」をクリック
- AWSリージョン:バージニア北部
- 名前:任意(一意の名前にしてください)
※他はデフォルト

5-4.作成したS3に、KnowledgeBase for Amazon Bedrockへ読み込ませる資料をドラッグ&ドロップ
※資料の拡張子は.txt、.md、.html、.doc と .docx、.csv、.xls と .xlsx、および .pdfのみになります。また、名前はアルファベットで表記ください。

5-5. 作成したバケットに、以下記述が書かれたyamlファイル(OpenAPI仕様)をドラッグ&ドロップ(以上でS3構築完了)

【re:Invent 2023】Agents for Amazon Bedrockで生成AIアプリの可能性を広げようopenapi: 3.0.0 info: title: Send Slack API version: 1.0.0 description: APIs for send information to slack. paths: /send-slack: post: summary: APIs for send information to slack. description: The title and message should be determined based on the instructions given. If the title and message are unclear, please ask the user to determine them. operationId: send requestBody: required: true content: application/json: schema: type: object properties: title: type: string description: Title of notification message: type: string description: Contents of notification required: - title - message responses: '200': description: Information sent successfully content: application/json: schema: type: object properties: sendId: type: string description: Unique Id to track the status of the send notifications sendStatus: type: string description: Status of send notifications
※OpenAPI仕様についての説明は下記をご参照ください
6. Knowledge base for Amazon Bedrockの作成
Knowledge base の概要ですが、簡単にRAGが構築できるAWSマネージドサービスになります。
今までRAGを構築しようとした場合、ベクトルデータベース、ベクトル変換プログラム、FMをそれぞれ用意して組み合わせるための独自実装が必要でした。Knowledge baseは既にこれらが組み合わされているため利用者はAWSコンソールから数クリックするだけで簡単にRAGを構築することができます。
6-1. 下記URLよりBedrockのコンソール画面へ移動
※リージョンはバージニア北部に作る必要があります。
https://us-east-1.console.aws.amazon.com/bedrock
6-2. 左ペインより「Knowledge base」を選択し、「Create konwledge base」をクリック

6-3. 以下の通り入力し、「Next」をクリック
- Knowledge base name:任意の名前
- Knowledge base description:任意の説明(入力しなくてもOK)
それ以外はデフォルト値

6-4. 以下の通り入力し、「Next」をクリック
- Data source name:任意の名前
- S3 URI:項番3-4で作成したKnowledge baseに読み込ませるS3バケットのオブジェクトを選択する(S3 URIはBrowse S3より選択できる)

6-5. 以下の通り入力し、「Next」をクリック
- Embiddings model:Titan Embiddings G1 – Text v1.2
- Vector database:Quick create a new vector store – Recommended
※上記を選択するとOpensearch Serverlessが作成されます。後でOpensearch Serverlessを削除しないと月10万ぐらいの高額な請求書がきますのでご注意ください…

6-6. 設定値を確認し、「Create Knowledge base」をクリック
※作成までに少し時間がかかります。(5~10分ほど)

6-7. 「Select model」をクリック

6-8. 以下の通り入力し、「Apply」をクリック
- Category:Anthropic
- Model:Claude 2.1
- Throughput:On-demand

6-9. 「Sync data source」をクリック
※ここも少し時間がかかります。(1分ほど)

6-10. フォームで質問内容を入力し、「Run」をクリック。求めていた答えが返ってくるかテストします。
※ここで求めていた回答が来ない場合、S3に置いたデータに求める回答のデータが保存されていないことになります。S3データを追加するか、見直しをお願いします。

7. Agents for Amazon Bedrockの作成
Agentの概要ですが、ユーザからの指示に対して予めセットアップされたツールを駆使して対応してくれる執事のようなAWSマネージドサービスになります。Agentにセットアップ可能なツールは現時点(2024/1/13時点)ではFMとしてAnthropic’s Claude、ナレッジデータベースとしてKnowledge base、カスタムアクションを実行するためのLambdaの3つが指定可能です。(今後、Agentに指定できるAWSサービスはStep Functionsのように増えていくのかな?と推測しています)
7-1. 下記URLよりBedrockのコンソール画面へ移動
※リージョンはバージニア北部にする必要があります。
https://us-east-1.console.aws.amazon.com/bedrock
7-2. 左ペインより「Agents」をクリックし、「Create Agents」をクリック

7-3. 以下の通り入力し、「Next」をクリック
Agent Name:任意の名前
Agent description:任意の説明(入力なしでもOK)

7-4. 以下の通り入力し、「Next」をクリック
- モデル:「Anthoropic」、「Cloude V2.1」を選択
- Instructions for the Agent:こちらはAgentへの指示内容になります。以下URL、作成例を参考に自分で考えて作成してください。(ここの指示内容で精度がかなり変わります…より細かく、具体的に…)
[作成例]
あなたは株式会社ベンジャミンの社員です。使用する言語は日本語とします。株式会社ベンジャミンについて質問をされます。以下にあなたができる作業を記載しますので、実行してください。
作業1: 株式会社ベンジャミンの内容に関する情報が必要な場合はナレッジベースから情報を取得してください。単に株式会社ベンジャミンと指示があった場合もナレッジベースから情報を探すようにしてください。株式会社ベンジャミンはBJM、ベンジャミンと呼ばれることもあります。
作業2: 質問が受け付けられたら、質問の内容をLambda(Bedrock-to-slack-test-kim)からSNS(Bedrock-to-slack-test-kim)を通じて必ずチームのSlackに即座に通知してください。titleとmessageは質問内容を基に生成し、通知してください。もしtitleとmessageが不明な場合はユーザーに質問して決定してください。
例:
ユーザーからの質問: ベンジャミンの役員は誰ですか?
Claudeの回答: "株式会社ベンジャミンの代表取締役は川尻純です。
Slack通知のtitle: ベンジャミンの役員に関する質問の回答
Slack通知のmessage: 株式会社ベンジャミンの代表取締役は川尻純です。

7-5. 以下の通り入力し、「Next」をクリック
- Enter Action group name:任意の名前
- Description:任意の説明(値なしでもOK)
- Select Lambda function:項番2で作成したLambdaを選択する
- S3 URI:項番3-5で作成したS3に保存済みyamlファイル(OpenAPI仕様)の場所を選択する

7-6. 以下の通り入力し、「Next」をクリック
- Knowledge base:項番4で作成したKnowlege baseを選択
- Knowledge base instructions for Agent:こちらはAgentからKnowledge Baseへの指示内容になります。以下作成例を参考に自分で作成してください。
[作成例]
株式会社ベンジャミン(BJM, ベンジャミン)の会社概要をナレッジベースで参照しております。株式会社ベンジャミンに関する質問が来た時はこちらから、データの取得をお願いします。 実行結果はLambdaより、slackにメール通知をお願いします。

7-7. 設定値を確認し、「Create Agent」をクリック(以上でAgent作成は完了)

8. AgentがLambdaを操作するためのリソースベースポリシーの設定
8-1. 下記URLよりLambdaのコンソール画面へ移動
https://us-east-1.console.aws.amazon.com/lambda/
※リージョンはバージニア北部にしてください。
8−2. 項番3で作成したLambdaの「設定」タブを選択し、左ペインから「アクセス権限」に戻り、「リソースベースのポリシーステートメイト」のペインから「アクセス権限の追加」をクリック

8-3. 以下の通り入力または選択し、「保存」をクリック(以上でLambdaリソースベースのポリシーステートメントの設定は完了)
- 対象:AWSのサービス
- サービス:Other
- ステートメントID:任意(一意の値)
- プリンシパル:bedrock.amazonaws.com
- リソースARN:項番5で作成したAgentsのARN
- アクション:lambda:InvokeFunction

9. Bedrockに質問してみよう!
9-1. 下記URLよりBedrockのコンソール画面へ移動
※リージョンはバージニア北部にする必要があります。
https://us-east-1.console.aws.amazon.com/bedrock
9-2. Agentのコンソール画面へ移動し、右ペインの「Test」の入力フォームより質問する
質問例:ベンジャミンの役員は誰?回答内容なSlackに通知をお願いします。
下記の通り目的の回答がもらえ、Slackにも同じ文章の通知が届けば成功!
※Slackに通知が届かない場合、Agentへの指示内容を変更する必要がある。(また、追加で「Slackへ通知して」と指示を出すと通知してくれることもある)


10. リソースの削除(絶対やってね!)
10-1. Opensearch Serverlessの削除
10-1-1. 下記URLよりOpensearchのコンソール画面へ移動
https://us-east-1.console.aws.amazon.com/aos/home?region=us-east-1#opensearch/dashboard
※リージョンはバージニア北部にする必要があります。
10-1-2. 左ペインより「コレクション」を選択し、「bedrock-knowledge-base〜」という名前のコレクションをチェックして「削除」をクリック

10-1-3. 左ペインより「データアクセスポリシー」をクリックし、「bedrock-knowledge-base〜」という名前のアクセスポリシーをチェックして「削除」をクリック

10-1-4. 左ペインより「暗号ポリシー」をクリックし、「bedrock-knowledge-base〜」という名前の暗号ポリシーをチェックして「削除」をクリック

10-1-5. 左ペインより「ネットワークポリシー」をクリックし、「bedrock-knowledge-base〜」という名前のネットワークポリシーをチェックして「削除」をクリック

10-2. Knowledge baseの削除
下記を参照して削除してください。
10-3. Agentの削除
10-3-1. 下記URLよりBedrockのコンソール画面へ移動
※リージョンはバージニア北部にする必要があります。
https://us-east-1.console.aws.amazon.com/bedrock
10-3-2. Bedrockコンソール画面の左ペインより「Agent」をクリックし、削除対象のAgentをチェックして「Delete」をクリック

10-4. Lambda削除
10-4-1. 下記URLよりLambdaのコンソール画面へ移動
https://us-east-1.console.aws.amazon.com/lambda/
※リージョンはバージニア北部にしてください。
10-4-2. 削除対象のLambda関数のコンソール画面へ移動し、右上の「アクション」をクリックし、表示された「関数の削除」をクリック

10-5. S3の削除
下記を参照して削除してください(S3バケットは中身を空にしないと削除できません)
10-6. SNSの削除
下記を参照して削除してください