Bedrockナレッジベースの「自然言語 to SQL」で社内DB検索エージェントを作ろう！

# DBをRAGで検索できるように？

昨年末のAWS re:Inventでこんなアップデートがありました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-bedrock-knowledge-bases-structured-data-retrieval/

簡単に言うと、RedshiftやGlueデータカタログといったリレーショナルDBを、BedrockのナレッジベースからRAGのように検索できる機能です。

私はRedshift素人なのですが、Claudeに聞きながらやってみたら簡単に試せました。手順を紹介します。

![スクリーンショット 2025-02-02 23.50.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/243d90d4-9f12-1eda-25e0-97ea5390c54a.png)

:::note
今回の作業はすべてオレゴンリージョンで実施しました。
:::


# 【手順1】 Redshiftの設定

### Redshift Serverlessの作成

AWSマネジメントコンソール上部の検索バーで「redshift」と検索し、Amazon Redshiftのコンソールに移動します。

トップページにあるオレンジ色のボタン「Redshift Serverlessの無料トライアルをお試しください」をクリックして、設定はすべてデフォルトのまま「設定を保存」をクリックします。

1分ほどでセットアップが完了するので、「次へ」をクリックします。

![スクリーンショット 2025-02-01 20.00.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/4806334d-6ca2-3397-3750-11f446b84526.png)

サーバーレスダッシュボードが表示されたら、右上の「ワークグループを作成」をクリックします。

:::note info
Redshift Serverlessでは、プロビジョンド版でいう「クラスター」に近い概念として、「ワークグループ」という単位でデータベースの管理を行います。
:::

作成ウィザードを以下のように進めます。（記載がないものはデフォルトのままでOK）

ステップ1

- ワークグループの名前：`tori-gouzoku`

ステップ2

- 名前空間：`tori-gouzoku`
- 許可：「IAMロールを作成 > IAMロールをデフォルトとして作成する」をクリック

1分ほどでワークグループの作成が完了します。


### DBへのデータ投入

次に、画面上部の「データをクエリ」をクリックして、クエリエディタを起動します。

左ペインに並んでいるワークグループのうち「Serverless: tori-gouzoku」をクリックして、ポップアップ内の「Create connection」をクリックします。

![スクリーンショット 2025-02-01 20.16.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/5a9eb7ff-28a7-da08-9068-65a7f1abf011.png)

右ペインのクエリエディタに以下のSQLをコピペして、「▶ Run」ボタンをクリックすると「products（商品）」テーブルが新規作成されます。

```sql
CREATE TABLE products (
    product_id INTEGER PRIMARY KEY,
    product_name VARCHAR(100),
    sales INTEGER,
    popular_region VARCHAR(50)
);
```

表示される「Result 1」タブ内にエラーメッセージが出ていなければOKです。

続けて、同じクエリエディタ内に以下をコピペして上書きし、「▶ Run」ボタンをクリックすると、架空の焼鳥チェーン「鳥豪族」の商品データが投入されます。

```sql
INSERT INTO products (product_id, product_name, sales, popular_region) VALUES
    (1, 'もも豪族焼', 600000, '京都府'),
    (2, 'つくねチーズ焼', 400000, '兵庫県'),
    (3, 'ピーマン肉詰め', 350000, '北海道'),
    (4, '山芋の鉄板焼', 550000, '沖縄県'),
    (5, 'とり釜飯', 450000, '愛知県'),
    (6, 'ひざなんこつ唐揚げ', 300000, '大阪府');
```

表示される「Result 1」タブ内にエラーメッセージが出ていなければOKです。

:::note info
上記のサンプルデータはClaudeで作成しました。
DBの操作に慣れていない人でも、生成AIを使えばSQLを簡単に生成できますね。
:::

このクエリエディタはすぐ後で使うので、このままタブを開いておいてください。


# 【手順2】 Bedrockの設定

### モデルアクセスの有効化

マネジメントコンソール上部の検索バーに「Bedrock」と入力して、Amazon Bedrockのコンソールに移動します。

左メニューの下の方にある「モデルアクセス」をクリックし、「すべてのモデルを有効にする」をクリックします。

ステップ1：

そのまま「次へ」をクリック

ステップ2：

Bedrockの用途を申告します。内容はざっくりでOKです。

- 会社名/ウェブサイト/業界：あなたの会社情報を入力
- 対象ユーザー：「社内の従業員」にチェック
- ユースケースの説明：`個人検証`

ステップ3で「送信」をクリックすると、1分程度でモデルアクセスが承認されます。

※一部の古いモデルでエラーが出ることがありますが、今回使わないモデルのため気にせずでOKです。

![スクリーンショット 2025-02-01 20.55.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/6181e7d2-f066-c852-0286-2a049d39c764.png)

完了を待たずにそのまま次の作業へ進みましょう。


### ナレッジベースの作成

Bedrockコンソール左メニューの「ナレッジベース」をクリックし、画面右側の「ナレッジベースの作成 > Knowledge Base with structured data store」をクリックして、以下のとおり設定します。（記載ないものはデフォルトでOK）

ステップ1：

- ナレッジベースの詳細 > ナレッジベース名：`tori-gouzoku`
- IAM許可 > サービスロール名：`AmazonBedrockExecutionRoleForKnowledgeBase_gouzoku`

ステップ2：

- Query engine details > Workgroup：tori-gouzoku
- Default storage metadata > Database：dev

ステップ3で「ナレッジベースを作成」をクリックすると、1分程度でナレッジベースが作成されます。

![スクリーンショット 2025-02-02 23.25.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/6145d6f2-ce25-8984-a4a3-f38d4df1975a.png)

:::note
通常のナレッジベースと違い、ルートユーザーでもエラーなく作成できます。（豆です）
:::

次に、先ほど開いておいたRedshiftのクエリエディタ画面へ戻り、以下のSQLを実行します。

```SQL
-- ナレッジベース用のDBユーザーを作成
CREATE USER "IAMR:AmazonBedrockExecutionRoleForKnowledgeBase_gouzoku"
  WITH PASSWORD DISABLE;

-- ナレッジベースにスキーマ使用権限を付与
GRANT USAGE ON SCHEMA public 
  TO "IAMR:AmazonBedrockExecutionRoleForKnowledgeBase_gouzoku";

-- ナレッジベースにsurveyテーブルへのSELECT権限を付与
GRANT SELECT ON products
  TO "IAMR:AmazonBedrockExecutionRoleForKnowledgeBase_gouzoku";
```

その後、作成したBedrockナレッジベースの画面に戻り、画面中段の「Query engine > dev」を選択して「同期」をクリックします。

![スクリーンショット 2025-02-01 21.31.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/89851acb-6728-b9c0-6f0b-fb5ed168726a.png)

数秒待つと、Redshiftのデータがナレッジベースに同期されます。


### 動作確認

ナレッジベース画面右側のテスト用サイドバーで「モデルを選択」をクリックし、「Anthropic > Claude 3.5 Sonnet v2 > US Anthropic Claude 3.5 Sonnet v2」を選択します。

チャットで `売上金額が最も大きい商品の名前は？` と質問してみましょう。

![スクリーンショット 2025-02-02 23.31.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/1c0cdced-02a1-edc3-a107-f282eace5bb1.png)

ちゃんとSQLを発行して「もも豪族焼」と答えてくれました！

「ソースの詳細を表示」をクリックすると、裏で発行されたSQLを確認することができます。


# 【手順3】 応用編

### エージェントの作成

このナレッジベースを持たせたAIエージェントを作成しましょう。
Bedrockコンソール画面左側のメニューから「エージェント」をクリックし、「エージェントを作成」をクリックして以下のとおり設定します。（記載ないものはデフォルトでOK）

エージェントを作成：

- 名前：`tori-gouzoku`

エージェントビルダー > エージェントの詳細：

- モデルを選択：Anthropic > Claude 3.5 Haiku > US Anthropic Claude 3.5 Haiku（推論プロファイル）
- エージェント向けの指示：`焼鳥チェーン「鳥豪族」の商品データをナレッジベースから取得して、ユーザーに売上向上のためのアドバイスを提供してください。`

ここまで入力したら、画面上部の「保存」をクリックして、画面中段の「ナレッジベース > 追加」をクリックし、以下のとおり設定します。

- ナレッジベースを選択：tori-gouzoku
- エージェント向けのナレッジベースの指示：`焼鳥チェーン「鳥豪族」の商品データが格納されています。`

設定後は「保存して終了」します。


### エージェントのテスト

画面右側のテスト用サイドバーにある「準備」ボタンを押したのち、チャットを試してみましょう。

![スクリーンショット 2025-02-02 23.38.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/064b46bf-56e6-d3c3-daf0-ea6b95a1e32a.png)

`売上金額が最も少ない商品をヒントに、売上改善のアドバイスをください。` と質問してみると、ちゃんとデータ通り「ひざなんこつ唐揚げ」に言及してアドバイスを提供してくれました！


# 実はこれ、色んなDBから連携できる？

今回はRedshiftに自分でSQLを投入しましたが、Redshiftは色んなAWSのDBサービスから「ゼロETL統合」でデータ連携ができます。

AuroraやDynamoDBなど、既に社内で利用しているデータベースを同期して、Bedrockエージェントから検索させられれば、生成AIのユースケースがかなり広がりそうですね！

また、Redshift以外にGlueデータカタログもデータストアに指定できるため、CSVなどのデータを直接取り込むのにも便利そうです。

https://docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base-structured-create.html

:::note
今回、色々試した限りでは、特にBedrockエージェントからRedshiftの検索をするのは意外と思いどおりにいきませんでした。

LLMが誤ったSQLを生成したり、Redshiftがエラーを吐くなど。
特にクエリやデータが日本語の場合、英語よりも動作が不安定な可能性もありそうです。

良いチューニング方法を見つけた方は、ぜひ教えてください！
:::