独自ドキュメントをベクトル化し、生成 AI が根拠付きで回答する RAG を構築する
RAG(Retrieval-Augmented Generation / 検索拡張生成)は、生成 AI に外部のドキュメントを検索させ、その内容を根拠として回答を生成させる手法です。これにより、モデルが学習していない社内文書や最新情報に基づいた、ハルシネーション(もっともらしい誤答)の少ない回答が得られます。
Amazon Bedrock の Knowledge Bases を使うと、S3 に置いたドキュメントの取り込み・チャンク分割・ベクトル化・ベクトル DB への格納・検索までをフルマネージドで自動化できます。このハンズオンでは公式の amazon-bedrock-workshop の RAG ラボを参考に、マネジメントコンソールだけで RAG チャットボットの基盤を構築します。
| 項目 | 内容 |
|---|---|
| 対象サービス | Amazon Bedrock(Knowledge Bases / モデルアクセス)、Amazon S3、Amazon OpenSearch Serverless、Titan Text Embeddings |
| 主な学習内容 | モデルアクセス有効化・ドキュメント取り込み・埋め込み生成・ベクトル検索・Retrieve and Generate |
| 所要時間 | 75〜90 分(同期・インデックス作成の待機時間含む) |
| 難易度 | ★★★☆☆(中級者向け) |
| 前提知識 | S3・IAM の基礎知識、生成 AI / LLM の基本概念 |
| 費用目安 | 約 1〜3 USD(OpenSearch Serverless の最低キャパシティ課金あり・放置厳禁) |
ベクトルストアに使う Amazon OpenSearch Serverless は、コレクションが存在する間ずっと最低キャパシティ分の課金(目安で 1 時間あたり数十円〜数百円)が発生します。ハンズオン終了後は必ず「クリーンアップ」を実施し、コレクションを削除してください。数日放置すると数千円規模になり得ます。
| モデル種別 | 役割 | 本ハンズオンでの選択 |
|---|---|---|
| 埋め込みモデル(Embeddings) | テキストを数値ベクトルに変換し、意味的な類似検索を可能にする | Titan Text Embeddings V2 |
| 基盤モデル(Foundation Model) | 取得した文書を読み、人間向けの回答文を生成する | Claude 3.5 Sonnet(または Claude 3 Haiku) |
このハンズオンでは us-east-1(バージニア北部) を使用します。Knowledge Bases・Titan Embeddings・Claude 各モデルが揃っており、公式ワークショップも同リージョンを前提としています。コンソール右上のリージョンを us-east-1 に固定してから開始してください。東京リージョン(ap-northeast-1)でも構成可能ですが、利用可能モデルが異なる場合があります。
S3 バケット・Knowledge Base・OpenSearch コレクションは同じリージョンに作成してください。リージョンがずれると同期に失敗します。
Bedrock では、利用したい基盤モデルごとに事前のアクセス申請(有効化)が必要です。RAG に必要な「埋め込みモデル」と「回答生成モデル」の 2 つを有効化します。
AWS マネジメントコンソールで 「Bedrock」 を検索して開きます。リージョンが us-east-1 になっていることを確認します。
左メニュー最下部の 「Bedrock configurations」→「モデルアクセス(Model access)」 を開きます。「モデルアクセスを変更(Modify model access)」 または「特定のモデルを有効にする」をクリックします。
以下のモデルにチェックを入れます。
| 用途 | モデル | 提供元 |
|---|---|---|
| 埋め込み(必須) | Titan Text Embeddings V2 | Amazon |
| 回答生成(必須) | Claude 3.5 Sonnet | Anthropic |
| 回答生成(任意・低コスト) | Claude 3 Haiku | Anthropic |
「次へ」→「送信(Submit)」をクリックします。
モデルアクセス画面で、対象モデルのアクセスステータスが 「アクセスが付与されました(Access granted)」 になるまで待ちます。Amazon・Anthropic のモデルは通常すぐに有効化されます。
初回は簡単なユースケース(社内ドキュメント検索の検証など)の入力を求められる場合があります。フォームに沿って入力すれば即時付与されます。
Titan Text Embeddings V2 と Claude の両方が「アクセスが付与されました」と表示されていれば成功です。
RAG の検索対象となるドキュメントを S3 バケットにアップロードします。今回は架空の社内規定をサンプルデータとして用意します。
S3 コンソールで 「バケットを作成」 をクリックし、以下を設定します(バケット名は世界で一意である必要があります)。
他はデフォルトのまま「バケットを作成」をクリックします。
テキストエディタで以下の内容を company-policy.md という名前で保存します。日本語の社内規定を題材にします。
# 株式会社サンプル 社内規定(抜粋) ## 経費精算について 経費精算の締め日は毎月25日です。25日を過ぎた申請は翌月扱いとなります。 精算金額は申請月の翌月15日に給与口座へ振り込まれます。 領収書は電子データ(PDF または画像)での提出が必須です。 ## 勤務時間とリモートワーク 標準勤務時間は9時00分から18時00分(休憩1時間)です。 コアタイムは11時00分から15時00分です。 リモートワークは週3日まで認められています。事前に上長へSlackで申請してください。 ## 有給休暇 入社初年度は10日付与されます。 有給は1時間単位で取得可能です。 取得する場合は原則3営業日前までに勤怠システムで申請してください。 ## 経費として認められるもの - 業務に必要な書籍・技術書 - 業務用ソフトウェアのライセンス費用 - 顧客との会食費(1人あたり5000円まで) 出張時の宿泊費は1泊あたり12000円を上限とします。
Knowledge Bases は .txt / .md / .pdf / .html / .csv / .doc(x) / .xls(x) などに対応しています。複数ファイルをまとめて取り込めます。今回は Markdown を使用します。
作成したバケットを開き、「アップロード」→「ファイルを追加」 で company-policy.md を選択し、「アップロード」をクリックします。
複数の文書で試したい場合は、ここで追加のテキスト/PDF も一緒にアップロードしてください。
バケット内に company-policy.md が表示されていれば準備完了です。
S3 をデータソース、Titan を埋め込みモデル、OpenSearch Serverless をベクトルストアとして Knowledge Base を構築します。ベクトルストアはクイック作成を使い、面倒なインデックス設計を Bedrock に任せます。
Bedrock コンソール左メニューの 「ビルダーツール(Builder tools)」→「ナレッジベース(Knowledge Bases)」 を開き、「ナレッジベースを作成」→「ベクトルストアを使用するナレッジベース(Knowledge Base with vector store)」 を選択します。
IAM ロールは Bedrock が自動生成します(S3 読み取り・OpenSearch アクセス権限が付与されます)。「次へ」をクリックします。
「S3 を参照」からステップ 2 で作成したバケットを選択できます。チャンク戦略は 「デフォルトのチャンク化(Default chunking)」 のままで「次へ」をクリックします。
ステップ 1 で有効化したモデルが選択肢に表示されます。次元数はデフォルト(1024)のままにします。
ベクトルストアの作成方法で 「新しいベクトルストアをクイック作成(Quick create a new vector store)」→「Amazon OpenSearch Serverless」 を選択します。Bedrock がコレクションとベクトルインデックスを自動作成します。
OpenSearch Serverless コレクションが作成された時点から、最低キャパシティ分の課金が継続的に発生します。作業を中断する場合でもクリーンアップ(ステップのコレクション削除)を忘れないでください。
設定内容を確認し 「ナレッジベースを作成」 をクリックします。OpenSearch Serverless コレクションとインデックスの作成に 数分(3〜10 分程度) かかります。完了するまで待ちます。
ナレッジベースのステータスが「準備完了(Available)」になり、データソース一覧に company-policy-source が表示されれば成功です。
Knowledge Base を作成しただけではドキュメントはまだ取り込まれていません。「同期」を実行して、S3 のドキュメントをチャンク分割・ベクトル化し、OpenSearch に格納します。
作成したナレッジベース company-policy-kb の詳細画面を開きます。「データソース」 セクションで company-policy-source を選択し、「同期(Sync)」 ボタンをクリックします。
同期ジョブが開始されます。ドキュメント量にもよりますが、今回のサンプルなら 1〜3 分 で完了します。ステータスが 「完了(Completed / Ready)」 になるまで待ちます。
同期ジョブをクリックすると、取り込まれたソース数・処理したファイル数などの統計が確認できます。
S3 のファイルを追加・変更・削除した場合は、その都度「同期」を再実行しないとベクトルストアに反映されません。
同期ジョブのステータスが「完了」で、取り込みエラーが 0 件であれば成功です。これで RAG の検索準備が整いました。
マネジメントコンソールのテスト画面で、実際に質問して根拠付きの回答が返るかを確認します。
ナレッジベース詳細画面の右側にある 「ナレッジベースをテスト(Test Knowledge Base)」 パネルを開きます。「モデルを選択」 をクリックし、回答生成用に Claude 3.5 Sonnet(または Claude 3 Haiku)を選択します。
テストパネル上部で 2 つのモードを切り替えられます。今回は 「ソースを使用して応答を生成(Retrieve and generate)」 をオンにします。
| モード | 動作 |
|---|---|
| Retrieve and generate(生成あり) | 関連チャンクを検索 → モデルが自然文で回答 + 引用を提示 |
| Retrieve only(検索のみ) | 関連チャンクの生テキストをそのまま返す(生成しない) |
テスト用の質問を入力して送信します。ステップ 2 のサンプル文書に基づく質問例:
例えば「経費精算の締め日はいつですか?」と聞くと、「毎月25日です」 という回答とともに、根拠となった社内規定のチャンクが 引用元(Source / Citations) として表示されます。
回答の下に表示される 「ソースを表示(Show source details)」 をクリックすると、回答の根拠となった元テキストのチャンクと、それが属する S3 のファイルが確認できます。これが RAG の「根拠提示」機能です。
あえて文書に書かれていないこと(例:「社員食堂のメニューは?」)を質問してみます。RAG が正しく機能していれば、「提供された情報の中にはその記載が見つかりませんでした」 といった趣旨の回答になり、デタラメをでっち上げない(ハルシネーション抑制)ことを確認できます。
文書内の質問に正しい回答 + 引用元が返り、文書外の質問には「分からない」と答えれば、RAG が正しく動作しています。
基本動作を確認できたら、回答品質を高める設定や、アプリから利用するための API 呼び出しを試します。
テストパネルの 「設定(Configurations)」 から検索動作を調整できます。
| パラメータ | 説明 | 調整の目安 |
|---|---|---|
| 取得するソース数(Number of source chunks) | 検索で取得するチャンク数(Top-K) | 回答が不足するなら 5 → 10 に増やす |
| 検索タイプ | セマンティック / ハイブリッド検索 | 固有名詞や型番が多いならハイブリッド |
| プロンプトテンプレート | モデルへの指示文をカスタマイズ | 「必ず日本語で」「箇条書きで」等を追記 |
「ナレッジベースのプロンプトテンプレート」を編集すると、回答スタイルを制御できます。例として、以下のような指示を追記すると回答の一貫性が上がります。
あなたは社内規定に詳しいアシスタントです。 以下の検索結果のみを根拠として、日本語で簡潔に回答してください。 検索結果に答えが無い場合は「規定に記載がありません」と答えてください。 $search_results$
アプリに組み込む際は RetrieveAndGenerate API を使います。コンソール右上の CloudShell を開き、ナレッジベース ID(詳細画面に表示)を指定して実行します。
Python(boto3)で書くと以下のようになります。
import boto3
client = boto3.client("bedrock-agent-runtime", region_name="us-east-1")
resp = client.retrieve_and_generate(
input={"text": "リモートワークは週何日まで?"},
retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId": "<あなたのKnowledgeBaseID>",
"modelArn": "anthropic.claude-3-5-sonnet-20240620-v1:0",
},
},
)
print(resp["output"]["text"])
for c in resp.get("citations", []):
for ref in c.get("retrievedReferences", []):
print("出典:", ref["location"])
RetrieveAndGenerate:検索 + 回答生成までワンストップ。チャットボット向け。Retrieve:関連チャンクの取得のみ。自前のプロンプト処理や別モデルと組み合わせたいとき。CloudShell / boto3 から回答テキストと出典(retrievedReferences)が取得できれば、アプリ組み込みの準備が整っています。
このハンズオンで最も課金が継続するのは OpenSearch Serverless コレクションです。コレクションが残っている限り課金され続けるため、以下のクリーンアップを最後まで必ず実施してください。
company-policy-kb を選択 → 「削除」。bedrock-knowledge-base-...)を選択 → 「削除」。bedrock-kb-docs-<アカウントID> → 「空にする」→ その後「削除」。
AmazonBedrockExecutionRoleForKnowledgeBase_...)を削除。
OpenSearch Service → サーバーレス → コレクション一覧が空になっていることを必ず確認してください。コレクションが残っていると課金が続きます。
company-policy-kb が無い| 習得したスキル | 実践内容 |
|---|---|
| Bedrock モデルアクセス | 埋め込みモデル・生成モデルの有効化 |
| RAG の構成理解 | 取り込み(埋め込み・格納)と検索(Retrieve and Generate)の 2 フロー |
| Knowledge Bases 構築 | S3 データソース + Titan Embeddings + OpenSearch Serverless |
| データ同期 | ドキュメントのチャンク化・ベクトル化・インデックス作成 |
| 根拠付き回答 | 引用元提示・ハルシネーション抑制の確認 |
| API 連携 | RetrieveAndGenerate / Retrieve API によるアプリ組み込み |