はじめに
こんにちは、久保です。
本記事ではAWSで利用可能なAIエージェントのサービスを利用して、複数のナレッジベースを元にした回答を実現する方法について紹介します。
AIエージェントは、明確な定義はありませんが、「ユーザーの指示や目標に基づいて、与えられた情報や手段を元に自律的に必要なタスクの計画を作成し、実行まで行う仕組み」と言えるかと思います。
AWSではAIエージェントを実現するためのサービスとしてAmazon Bedrock Agentsと、Amazon Bedrock AgentCore(プレビュー)があります。
Amazon Bedrock Agentsはノーコード、もしくはローコードのレベルでAIエージェントを実現できるサービスで、Amazon Bedrock AgentCoreは開発者が自由にAIエージェントを開発し、開発したエージェントをAWS上でホストでき、かつ認証やMCPのアクセス制御、オブザーバビリティなどAIエージェントの運用に必要な機能を提供するサービスです。
今回は、AWSでBedrockを中心としたRAG(Retrieval-Augmented Generation)を構築、利用するケースにおいて、Amazon Bedrock Agentsを利用して複数種類のナレッジベースを元にした回答を実現する方法について紹介します。
対象読者
- Amazon Bedrock Agentsに興味がある方
- 生成AIを利用したRAG(Retrieval-Augmented Generation)に興味がある方
- 複数のデータソースを元にした回答を実現したい方
課題
企業が生成AIを利用する場合、企業が保有する独自の情報を利用して応答を生成したいケースが多いかと思います。
単純に1つのデータソース(やナレッジベース)からのみ情報を取得して回答を生成する場合は、比較的簡単に実現できますが、企業が保有する情報は様々な形式で存在し、複数のデータソースを元に回答を生成したいケースも考えられます。
例えば、以下のようなケースです。
- (1) 企業はエンターテイメントのチケットECサイトを運営しており、売り上げ分析のためのデータはRDBに保存されている
- (2) 社内向けのチケット販売社内ガイドおよびベストプラクティスはS3にPDFで保存されている
- (3) 社外向けのチケット販売ポリシーおよびFAQは別のS3バケットにPDFで保存されている
(2)と(3)は同じナレッジベースで扱うことも可能ですが、本例ではそれぞれが異なる管理者によって管理されており、別々のナレッジベースとして扱いたいとします。
このように複数のデータソース(ナレッジベース)を元に回答を生成したい場合に、Amazon Bedrock Agentsを利用することができます。
Amazon Bedrock Knowledge Bases について
AWSには生成AIアプリケーションで企業が持つ独自の情報を利用した応答を実現するRAG( Retrieval-Augmented Generation)を利用するためのサービスとしてAmazon Bedrock Knowledge Basesがあります(以後Bedrockナレッジベースと呼びます)。(Amazon Kendraもありますが、今回は割愛します。)
Amazon Bedrockのサービス群を活用してRAGを実現する際の選択肢は多く、下図のようにBedrockナレッジベースでは様々な方法でデータをインデックス化し、検索することができます。

また、Bedrock Agentsを利用することで、複数のBedrockナレッジベースを組み合わせて利用することができます。

今回の想定構成
今回は(1)のデータはRDBであるため、DBに対してSQLで問い合わせを行える必要があります。
この動作を実現する方法は、Amazon Redshiftを利用する方法や、RDS Data APIを利用する方法などがありますが、今回はAmazon Redshiftを利用し 構造化データを含むナレッジベース を作成します。
当該Redshiftに売り上げデータが入っているものとします。
(2)と(3)はそれぞれ別々のBedrockナレッジベースとしてS3にPDFで保存されているものを利用します。
また、フロントエンドにはAWSが提供してくださっているGenerative AI Use Cases (GenU)を利用します。

構築手順
前提事項
- エージェントがメインであるため、Bedrockナレッジベースの構築手順は簡略化しています。
- us-east-1 (バージニア北部) リージョンで実施しています。
1. Redshift Serverlessを利用した構造化データを含むナレッジベースの作成
(1)のナレッジベースを作成します。
上記記事の手順に従い、Redshift ServerlessおよびBedrockナレッジベース(名前を knowledge-base-redshift-serverless とします)を構築します。
こちらの手順では、Redshiftで提供されているtickitというサンプルデータベースをRedshift Serverlessにロードしています。
以下の様なスキーマを持つ、架空の2008年のチケット販売データです。
出典: AWS Builder Center
Bedrock Knowledge Bases: Structured Data Retrieval
Bedrockナレッジベース knowledge-base-redshift-serverless を作成しましたら、ナレッジベースのテストで自然言語からSQLへの変換ができることを確認します。

2008年に最も売上が高かったカテゴリ別TOP3イベントを教えてください。という質問に対して、以下のSQLが生成され、実行されることが確認できました。
WITH top_events AS ( SELECT c.catname, e.eventname, SUM(s.qtysold) AS total_tickets_sold FROM tickit.sales s JOIN tickit.event e ON s.eventid = e.eventid JOIN tickit.category c ON e.catid = c.catid WHERE s.dateid IN ( SELECT dateid FROM tickit.date WHERE year = 2008 ) GROUP BY c.catname, e.eventname ORDER BY total_tickets_sold DESC ) SELECT catname, eventname FROM ( SELECT catname, eventname, ROW_NUMBER() OVER (PARTITION BY catname ORDER BY total_tickets_sold DESC) AS rn FROM top_events ) t WHERE rn <= 3;
このように、Redshiftを利用した構造化データを含むナレッジベースでは、自然言語からSQLへの変換を行い、SQLを実行して回答を生成することができます。(NL2SQLと呼ばれます)
2. S3にPDFをアップロードし、Bedrockナレッジベースを作成
(2)と(3)のナレッジベースを作成します。
- (2) 社内向けのチケット販売社内ガイドおよびベストプラクティスはS3にPDFで保存されている
- (3) 社外向けのチケット販売ポリシーおよびFAQは別のS3バケットにPDFで保存されている
名称はそれぞれ、
- (2)
knowledge-base-internal-policy - (3)
knowledge-base-external-policy
とします。
なお、S3をデータソースとしたBedrockナレッジベースの作成手順は以下ブログ記事を参照ください。(S3 Vectorsを利用する方法です。)
それぞれのデータソースのS3バケットには以下のような内容のPDFファイルを設置します。
サンプルのため内容は簡略化していますが、実際にはもっと多くのファイルやページ数があることが想定されます。
(2) knowledge-base-internal-policy
ファイル名: internal_guide_sample.pdf
チケット販売社内ガイドおよびベストプラクティス 第1章 チケット価格設定ガイドライン 需要の高いイベントでは、開催日が近づくにつれて価格を引き上げることが推奨されま す。 在庫が余っている場合は、割引キャンペーンを検討してください。 競合イベントとの価格差を常にモニタリングし、柔軟に調整を行いましょう。 第2章 マーケティング施策 地域ごとの需要分析を行い、ターゲット層に応じた広告を配信します。 スポーツイベントでは、シーズン開始前にキャンペーンを強化すると効果的です。 コンサートでは、出演者のSNSを活用した共同プロモーションが推奨されます。 第3章 データ活用のベストプラクティス 販売データは毎週分析し、カテゴリ別・地域別の傾向を把握してください。 顧客の購入履歴をもとに、レコメンド施策を展開します。 イベント終了後には、売上・在庫データをレポート化して次回の改善に活用しましょう 。 第4章 サポート対応手順 顧客からの問い合わせは、まずFAQを参照して回答します。 解決できない場合は、サポート担当者にエスカレーションしてください。 重大なトラブルは、管理者に即時報告が必要です。
(3) knowledge-base-external-policy
ファイル名: policy_faq_sample.pdf
チケット販売ポリシーおよびFAQ 第1章 チケット払い戻し・キャンセル規定 イベントの中止または主催者の判断による変更があった場合、チケットの払い戻しは所 定の手続きに従い行われます。 払い戻しの申請期限は、イベント開催予定日の7日以内です。 購入者都合によるキャンセルは原則不可ですが、主催者が認める場合は所定の手数料を 差し引いて返金します。 第2章 手数料と税金について チケット販売には、販売手数料5%が加算されます。 税金は地域の法令に基づき、購入者に請求されます。 出品者は売上に関する税務申告の責任を負います。 第3章 入場規則・年齢制限 一部のイベントでは年齢制限があります。18歳未満の入場は保護者同伴が必要です。 入場時には本人確認書類の提示を求められる場合があります。 飲食物や危険物の持ち込みは禁止されています。 第4章 よくある質問(FAQ) Q: 電子チケットを紛失した場合は? A: 購入履歴から再発行が可能です。 Q: 座席の変更はできますか? A: 購入後の座席変更はできません。 Q: 雨天時のイベントはどうなりますか? A: 原則開催されますが、中止の場合は払い戻しされます。
ここまでで、最終構成の図にある3つのBedrockナレッジベースが作成できました。

3. Bedrock Agentsの作成
Bedrockの画面から[エージェント]を選択し、[エージェントを作成]をクリックします。

名前にagent-tickitを入力し[作成]をクリックします。

エージェントビルダーの画面が表示されます。
必要に応じて[モデルを選択]でモデルを選択します。(以下ではAmazon Nova Premierを選択しています。)
"エージェント向けの指示"に以下を入力します。
あなたは優秀なアシスタントです。以下の3つのナレッジベースを元に質問に回答します。 1. knowledge-base-redshift-serverless: チケット販売の売り上げデータが保存されているデータベースです。自然言語からSQLへの変換を行い、SQLを実行して回答を生成します。 2. knowledge-base-internal-policy: チケット販売社内ガイドおよびベストプラクティスが保存されているナレッジベースです。 3. knowledge-base-external-policy: チケット販売ポリシーおよびFAQが保存されているナレッジベースです。 質問に対して最も適切なナレッジベースを選択し、回答を生成してください。

[その他の設定]を展開するとコードを安全に実行する機能などの設定が表示されますが、今回は利用しません。

ここで、一度画面最上部の[保存]をクリックして保存します。
保存することにより、必要なIAMロールが自動的に生成されます。
次のナレッジベースを追加する前に実施しておく必要があります。

ナレッジベースの箇所で[Add]をクリックし、先ほど作成した3つのナレッジベースを追加します。

ここでは[エージェント向けのナレッジベースの指示]を以下のように設定します。
エージェントはこれらの情報を元に、質問に対して最も適切なナレッジベースを選択するため、これらの指示は重要です。
knowledge-base-redshift-serverless:
売り上げデータに関する情報が必要な場合に参照するナレッジベースです。自然言語からSQLへの変換を行い、SQLを実行して回答を生成します。knowledge-base-internal-policy:
社内向けのチケット販売社内ガイドおよびベストプラクティスに関する情報が必要な場合に参照するナレッジベースです。knowledge-base-external-policy:
社外向けのチケット販売ポリシーおよびFAQに関する情報が必要な場合に参照するナレッジベースです。

他の2種類も同じ様に登録します。
なお、Bedrock Agentsに登録できるナレッジベースはデフォルトでは最大2つまでになっています。デフォルトのままの場合はService Quotasからクォータ
Associated knowledge bases per Agentを3に増やす申請を行なってください。
3種類登録完了すると以下のようになります。

画面最上部の[保存して終了]をクリックします。

右側の画面の[準備]をクリックします。これによりエージェントがビルドされ、利用可能になります。

画面右側のテスト画面で質問を入力し、[実行]をクリックします。
売り上げについて聞いてみます。
売り上げが最も大きい地域TOP3は?

しばらくすると回答が生成されます。
正しい単位は米ドルなのですが、単位の情報がないため円で回答しています。
このような調整はエージェント側のプロンプトなどで調整可能です。

[トレースを表示]をクリックすると、どのように回答が生成されたかの詳細が確認できます。

トレース1を展開して確認すると、内部でSQLが生成され、実行されていることがわかります。

複数のナレッジベースを参照する質問もしてみます。
総売上高はいくらですか?また、データ活用時のプラクティスがあれば教えてください。

トレース2を参照すると、内部向けナレッジベースを対象に、データ活用のベストプラクティス、売上データの分析方法についてを検索していることがわかります。

テストが完了しましたら、[エイリアスを作成]をクリックし、エイリアスを作成します。

[エイリアス名]に"production"を入力し、[エイリアスを作成]をクリックします。

Bedrock Agentsでは、バージョンとエイリアスという2種類の識別子を使ってエージェントの管理を行います。例えばエイリアスにdevとprodを用意しておき、dev=バージョン2, prod=バージョン1のように設定することができます。devで問題ないことを確認した後、prodへの関連付けバージョンを2に変更することで、簡単に本番環境でのバージョンアップを実現できます。

4. Generative AI Use Cases (GenU)での利用
Generative AI Use Cases (GenU) を利用することで、簡単にフロントエンドを構築できます。
出典: https://github.com/aws-samples/generative-ai-use-cases/blob/main/README_ja.md
本記事ではGenUの詳細は割愛しますが、以下のように設定することで、先ほど作成したBedrock Agentsを利用できます。
packages/cdk/parameter.tsのenvsに以下のように設定します。
...略 const envs: Record<string, Partial<StackInput>> = { dev: { agentEnabled: true, agents: [ { displayName: 'tickitエージェント', agentId: 'AGENT_ID', // 先ほど作成したBedrock AgentsのIDを指定 aliasId: 'ALIAS_ID', // 先ほど作成したエイリアスのIDを指定 }, ], // Agent を左ペインでインライン表示にする inlineAgents: true, }, ...略
上記設定でGenUをデプロイし、ブラウザでアクセスします。
ここまでで、最初に示した構成が完成となります。

問題なくデプロイできれば、以下のように左ペインにtickitエージェントが表示されます。

5. 動作確認
総売上高はいくらですか?また、データ活用時のプラクティスがあれば教えてください。と質問します。

[トレース]の部分をクリックすると、Bedrock Agentsのトレースが確認できます。 こちらはリアルタイムに表示されるため、エージェントが現在どのように動作しているかを確認できます。
テストで実行したのと同じ結果を得ることができました。
金額の単位が円なのは誤りです。今回はここの対応はしていません。
さいごに
今回はAmazon Bedrock Agentsを利用して、複数のナレッジベースを元にした回答を実現する方法について紹介しました。
Amazon Bedrock Agentsではナレッジベースだけではなく、アクショングループという機能を利用して、Lambdaを利用したツール(外部APIの呼び出しやコードの実行)をエージェントに手段として与えることも可能です。
注意することとして、エージェントの動作はエージェントで利用する言語モデルの性能やプロンプトに依存し、生成AIの特性上、必ずしも期待通りに動作しない場合があります。
また、複数のナレッジベースを利用する場合、ナレッジベースの数が増えるほど、エージェントがどのナレッジベースを利用すべきかの判断が難しくなり、誤ったナレッジベースを参照してしまう可能性もあります。
手順が決まっている様なタスクを実行する場合は、Amazon Bedrock フローを利用してワークフローを構築する方が適している場合もありますのでこちらもご参照ください。
久保 賢二(執筆記事の一覧)
猫とAWSが好きです。
