[AWS]トークン上限突破!NL-to-SQLの壁を壊すBedrock RAG活用法

ツール

Amazon Bedrockでトークンの上限を超えるような巨大なテーブル構成(データベーススキーマ)を読み込ませ、自然言語での問い合わせ(NL-to-SQL)などに活用するには、すべてのテーブル定義を一度にプロンプトへ含めるのではなく、必要な情報だけをその都度モデルに提供する「Retrieval Augmented Generation (RAG)」というアプローチが不可欠です。

以下に、簡単な方法からAWSの機能をフル活用した本格的な方法まで、段階的に解説します。

基本的な考え方:なぜそのままではダメなのか?

Claude 3などの高性能モデルでも、一度に処理できるトークン数には上限があります(例:200Kトークン)。数十〜数百のテーブルを持つデータベースのCREATE TABLE文をすべてテキスト化すると、この上限を容易に超えてしまいます。無理に詰め込もうとすると、以下のような問題が発生します。

  • トークン上限エラー: APIがエラーを返す。
  • 性能劣化: モデルがコンテキストを把握しきれず、クエリの生成精度が著しく低下する。
  • コスト増大: 毎回巨大なプロンプトを送信するため、利用料金が高くなる。

この問題を解決する鍵がRAGです。これは「ユーザーの質問に関連する情報だけを、外部の知識源からリアルタイムで検索し、プロンプトに埋め込んでからモデルに渡す」という考え方です。

方法1:手動での情報選択(小規模・テスト向け)

最もシンプルな方法です。開発者が手動で必要な情報を選択し、プロンプトに含めます。

  1. 質問の分析: ユーザーの質問(例:「先月の売上トップ5の製品は?」)を見て、どのテーブルが必要かを人間が判断します(この場合、productsordersorder_itemsテーブルなど)。
  2. スキーマの限定: 判断したテーブルのCREATE TABLE文やカラム情報だけを抜き出します。
  3. プロンプトの作成: 抜き出したスキーマ情報と質問を組み合わせて、Bedrockに送信します。
【コンテキスト】
以下のテーブル定義を参考にしてください。

CREATE TABLE products (
  product_id INT PRIMARY KEY,
  product_name VARCHAR(255),
  price DECIMAL(10, 2)
);

CREATE TABLE orders (
  order_id INT PRIMARY KEY,
  order_date DATE,
  customer_id INT
);

CREATE TABLE order_items (
  order_item_id INT PRIMARY KEY,
  order_id INT,
  product_id INT,
  quantity INT
);

【質問】
先月の売上トップ5の製品名を教えてください。上記のテーブルからSQLクエリを生成してください。
  • メリット: 実装が容易で、すぐに試せる。
  • デメリット: スケールしない。質問ごとに関連テーブルを判断する専門知識が必要で、自動化が難しい。

方法2:スキーマ情報のベクトル化と検索(RAGの本格実装)

これが本番環境で推奨される、スケーラブルで本格的なアプローチです。

ステップの概要

  1. 前処理: データベースから全てのテーブル定義(CREATE TABLE文など)を抽出し、テーブル単位で分割(チャンキング)します。
  2. ベクトル化: 分割した各テーブル定義を、Amazon Titan Embeddings などの埋め込みモデルを使い、意味を捉えた数値の配列(ベクトル)に変換します。
  3. 格納: 生成したベクトルと元のテーブル定義テキストを、ベクトルデータベースに格納します。
  4. 検索と生成:a. ユーザーの質問も同様にベクトル化します。b. ユーザー質問のベクトルと最も意味的に近いテーブル定義のベクトルを、ベクトルデータベースから検索します。c. 検索で見つかったテーブル定義と元の質問を組み合わせてプロンプトを作成し、BedrockのLLMに送信してSQLを生成させます。

AWSサービスを利用した実装例

オプションA: Knowledge Bases for Amazon Bedrockを利用する(最も簡単)

AWSがRAGの仕組みをマネージドで提供してくれる機能です。

  1. スキーマをS3に配置:
    • データベースから全テーブルのCREATE TABLE文を取得し、1テーブル1ファイル(例:products.sql)のようにして、Amazon S3バケットにアップロードします。
    • 【重要】 各テーブルの役割を説明するコメントをファイル内に含めると、検索精度が向上します(例:-- このテーブルは顧客情報を格納します)。
  2. Knowledge Baseの作成:
    • Bedrockのコンソールで「Knowledge Base」を作成します。
    • データソースとして、先ほどスキーマをアップロードしたS3バケットを指定します。
    • Bedrockが自動でS3のファイルをチャンキングし、Titan Embeddingsでベクトル化し、内部のベクトルストア(Amazon OpenSearch Serverlessなど)に格納してくれます。
  3. クエリの実行:
    • RetrieveAndGenerate APIを呼び出すか、コンソールのテスト画面から質問します。
    • Bedrockは裏側で質問内容に最も関連性の高いテーブル定義(ファイル)をKnowledge Baseから検索し、その情報を基にLLM(例: Claude 3)が回答(SQLクエリ)を生成します。

オプションB: Agents for Amazon Bedrockを利用する(より高度な制御)

SQLを生成するだけでなく、実際にデータベースに接続して実行し、結果を要約して返すような、より複雑なタスクを実行できます。

  1. Knowledge Baseの準備: 上記の方法で、テーブルスキーマを格納したKnowledge Baseを作成します。
  2. Lambda関数の作成:
    • 生成されたSQLを実行するためのLambda関数を作成します。この関数はデータベースへの接続情報(AWS Secrets Manager経由が安全)を持ち、SQLを受け取って実行し、結果を返します。
  3. Agentの作成:
    • BedrockでAgentを作成し、モデル(例: Claude 3 Sonnet)を選択します。
    • Action Group を定義し、先ほど作成したLambda関数をツールとして登録します。
    • AgentにKnowledge Baseを関連付けます。
  4. Agentの実行:
    • ユーザーが「東京支社の今月の売上は?」と質問すると、Agentは以下のように自律的に動作します。
      1. (思考)売上を計算するにはテーブルスキーマが必要だ。
      2. (行動)Knowledge Baseを検索し、ordersbranchesテーブルの定義を取得する。
      3. (思考)取得したスキーマを基にSQLクエリを生成する。
      4. (行動)生成したSQLをツール(Lambda関数)に渡して実行する。
      5. (思考)返ってきた実行結果(数値データ)を分かりやすく要約する。
      6. (応答)「東京支社の今月の売上は〇〇円です。」と自然言語で回答する。

手法3:バッチ処理とプロンプトキャッシュ

  • バッチ推論の適用: 分割したデータを一括処理し、S3に結果を出力。オンデマンドより50%低コストで大規模データを処理可能。
    • ワークフロー例:
      S3 → Bedrockバッチジョブ → 結果をS3に保存 → Glueで統合
  • プロンプトキャッシュの最適化: 静的プロンプト(例:「このテーブルを分析せよ」)をキャッシュし、TTFT(初回応答時間)を最大85%短縮。動的部分(テーブルデータ)のみを変更。
    • 要件: Claude 3.5 Haiku/Sonnetなど対応モデル限定。

手法4:クォータ拡張と回避策

  • TPM(Tokens Per Minute)の引き上げ: AWSコンソール > Service QuotasでOn-demand InvokeModelのクォータ増加を申請。
    • 申請のポイント: ビジネスインパクト(例:「月次レポート処理の遅延により経営判断が遅れる」)を明記。
  • クロスリージョン推論:
    東京リージョンでリソース不足時、他リージョンに自動フォールバック。追加料金なし。

各手法の比較と選び方

手法概要メリットデメリット適したケース
手動選択人間が必要なスキーマを選んでプロンプトに含める。・実装が最も簡単<br>・追加コストなし・スケールしない<br>・自動化が困難<br>・人為的ミスが発生機能検証、PoC(概念実証)、ごく少数のテーブルが対象の場合。
Knowledge BasesスキーマをS3に置き、マネージドRAGで関連情報を自動検索させる。・RAGの複雑な実装が不要<br>・スケーラブル<br>・メンテナンスが容易・手動よりはコストがかかる<br>・細かいチューニングは限定的ほとんどの本番システム。自然言語からSQLを生成するタスクのコア機能として最適。
AgentsKnowledge Baseとツール(Lambda)を組み合わせ、自律的なタスク実行を実現する。・SQL生成→実行→要約まで一気通貫で自動化<br>・複雑な複数ステップのタスクに対応可能・設定項目が多く、実装が複雑<br>・コストが最も高くなる傾向高度なデータ分析チャットボットや、業務自動化ツールを構築する場合。

まとめ

トークンの上限を超える巨大なテーブル構成を扱うには、Knowledge Bases for Amazon Bedrockを利用するのが最も現実的で効果的な解決策です。まずはこの方法でスキーマ検索の基盤を構築し、必要に応じてSQL実行や結果の要約といった能動的なアクションが必要になった場合にAgents for Amazon Bedrockへと拡張していくことをお勧めします。

コメント

タイトルとURLをコピーしました