やりたいこと
・社内規定などの文書をS3に格納し、それをBedRockのナレッジベースのデータソースとして活用する
・Lexを使用して自由会話形式のボットを作成し、社員が社内規定に関する質問をすると、ボットが回答する仕組みを構築する。これにより、大量の文書から必要な情報を探す時間を短縮する
・LexをSlackと連携させ、SlackのDM上で会話できるようにする
S3の作成+社内文書の格納
バケット名を入力し、その他設定をデフォルトのままで、「バケットを作成」
Bedrockナレッジベースの作成
「Knowledge Base with vector store」を選択
(「Knowledge Base with structured data store」は構造化データの場合に使う)
ナレッジベース名は自動で付与されるが、変えても大丈夫
IAM許可は事前に作っていないので、「新しいサービスロールを作成して使用」
「埋め込みモデル」について、社内で「Titan Embeddings G1 - Text v1.2」を試しているメンバーがいるので、他モデル精度検証のため「Embed Multilingual v3」を選択します。
「ベクトルデータベース」について、「Amazon Aurora PostgreSQL Serverless」にして、「次へ」をクリック
設定内容を確認し、「ナレッジベースを作成」をクリック(数十分かかる)
モデルの有効化
左メニューの「モデルアクセス」をクリックし、利用できるベースモデルの画面を開きます
初めてBedrockを使う方は、各モデルの「アクセスのステータス」がすべて灰色の「リクエスト可能」になっていると思います。
モデルを利用する際は、AWS Marketplaceで課金が発生するため、事前に利用するモデルの有効化を行う必要があります。
使うモデルを選択し、「モデルアクセスをリクエスト」をクリック
すると、このようなメールが飛んでくる
今回は他者のハンズオンブログを参照しながら作成するので、ブログと同じく「Anthropic > Claude 3.5 Sonnet(回答文作成のモデル)」と「Cohere > Embed Multilingual(S3ファイル取り込み時のモデル)」を検証したく、両方とも有効化をしました。
S3とナレッジベースの同期
左メニューの「ナレッジベース」を再度クリックし、先ほど出来上がったナレッジベースをクリック
画面右側にある「ナレッジベースをテスト」には、「1 つ以上のデータソースが同期されていません。」と表示されています
画面真ん中あたりにある「データソース」に、作られたデータソースをクリックすると、S3と紐づけているのですが、
S3に格納されたファイルとの「同期」はまだ行われていませんので、「Document」が空状態。「同期」クリック
すると、このようにS3のファイルが取り込まれました。
(S3ファイルの変更がある場合、再度「同期」する必要があります)
取り込まれたS3ファイルは、Bedrock側でベクトル変換します。変換済みのデータはAurora Serverlessに格納されます。
Bedrockにおけるモデル検証
再びナレッジベースの画面に戻ります。画面右側にある「ナレッジベースをテスト」は初期状態で入力できないですが、
「回答を生成」にチェックを外すと、このように入力できるようになりました。
しかし、「有給は何日取れる」って質問すると、こんな感じでよくわからない回答文が帰ってきました。。。
「回答文生成」のモデルをまだ選択していないからです!
「回答を生成」にチェックを入れた状態で「モデルを選択」をクリック
先ほど有効化したAnthropic社とCohere社のモデルが選択肢として出てきました。「Claude 3.5 Sonnet v1」(回答文を作成するモデル)を選び、「適用」をクリック。
すると「Claude 3.5 Sonnet v1 オンデマンド」が表示されました。
もう一度同じ質問をすると、今度はまとまった回答文が帰ってきました!
Lambda作成
「一から作成」を選択し、ランタイムは「Python3.13」にし、「関数の作成」
以下のソースをデプロイします。
(Lexから質問文を受け付け、Bedrockナレッジベースへ渡し、最後は回答文をLexへ返す)
※knowledge_base_idはナレッジベース画面を参照し書き換えます。
※modelArnは、以下の方法で取得できます。
import boto3
import json
bedrock_agent_runtime_client = boto3.client('bedrock-agent-runtime')
def lambda_handler(event, context):
# Lexからの入力イベントを確認
print("Event received from Lex:", json.dumps(event))
user_prompt = event.get('inputTranscript')
# Knowledge Base IDに置き換えてください
knowledge_base_id = 'xxxx'
# Bedrockのモデル
modelArn = 'anthropic.claude-3-5-sonnet-20240620-v1:0'
response = bedrock_agent_runtime_client.retrieve_and_generate(
input={
'text': user_prompt,
},
retrieveAndGenerateConfiguration={
'type': 'KNOWLEDGE_BASE',
'knowledgeBaseConfiguration': {
'knowledgeBaseId': knowledge_base_id,
'modelArn': modelArn,
}
}
)
print("Received response:" + json.dumps(response, ensure_ascii=False))
response_output = response['output']['text']
response = {
"messages": [
{
"contentType": "PlainText",
"content": response_output
}
],
"sessionState": {
"dialogAction": {
"type": "Close"
},
"intent": {
"name": "Lexインテント名に書き換えてください",
"state": "Fulfilled"
}
}
}
return response
「設定」>「一般設定」>「編集」で、「タイムアウト」時間を30秒へ変更します。
(Bedrockの回答文生成に時間がかかる場合があり、初期設定の3秒は足りない恐れがあります。)
「設定」>「アクセス権限」>「ロール名」で、自動作成されたIAMロールへ遷移します。
初期状態は「AWSLambdaBasicExecutionRole」(CloudWatch関連の権限)しかないはずですが、「許可ポリシー」>「許可の追加」で 「AmazonBedrockFullAccess」ポリシーを付与し、ナレッジベースへのアクセス権限を与えます。
これで設定完了!
Lexボットの作成
児童オンラインプライバシー保護法 (COPPA)に「はい」、「次へ」
「Japanese」を選択し、好きな音声を一つ選び、「完了」
すると、「ボット (EmployeeBot) が正常に作成されました」が表示され、「インテント」作成の画面に遷移します。
「サンプル発話」とは、ユーザーが会話をスタートするときに、入力すると予想される代表的なフレーズ。
「社内規定を知りたい」を入力すると、ボットは新しい会話フローをスタートし、応答をはじめます。
スロットに「スロットを追加」をクリックし、スロットを追加
今回はユーザーが自由会話形式で質問できるようにしたいので、「AMAZON.FreeFormInput」を選択し、想定した定型の返答文を「社内規定に関するご質問にお答えいたします。何かご不明な点がございましたら、お気軽にお尋ねください。」で設定します。
ちなみにですが、Lexのほうで、様々な学習済みの「スロットタイプ」があり、例えば「AMAZON.City」を選択すると、会話中から自動で都市名らしき言葉を認識できます。
「フルフィルメントに Lambda 関数を使用」にチェックを入れます。
そうすると、ユーザーが質問を完了すると、Lambda関数がトリガーされます。
ちなみにですが、もし会話の開始時や途中に随時Lambdaをトリガーしたい場合、画面一番下の「初期化と検証に Lambda 関数を使用」にチェックを入れる必要があります。
今回はその想定がないため設定しません。
その他設定は今回いらないので、画面右下の「インテントを保存をクリック」して保存したら完了です。
インテント設定画面の一番上にスクロールすると、設定されて会話フローが確認できます。
Lambdaと連携
再び「Lex」に戻り、「ボット」>「ボット名」>「デプロイ」>「エイリアス」でクリックし、言語の「Japanese」を選択
Lexボットのテスト
構築が完了すると、「インテント」設定の画面の「テスト」をクリックし、「社内規定を知りたい」と入力
すると、会話がスタートされ、スロットで設定した定型文が返されました。
Bedrockのテストと同じく「有給は何日取れる」って質問すると、さっきとほぼ同じの回答が返されました!
裏では「Lex→Lambda→Bedrockナレッジベース」で動いているのがわかりました!
Slackアプリの作成+Lexボット連携
最後は、このLexボットをSlack上にも使いたいので、Slackアプリを作成し、Lexボットと連携します!
この前作ったブログを参照して設定してください。
Slackの検証
以上の設定が完了したら、SlackのDMでアプリを検索し、DMを投げてみましょう!
このようにSlackのDMでLexボットと会話できるようになりました!
参考サイト