Aurora MySQL 3.06 の ML 機能で Bedrock アクセスを試してみた

Aurora PostgreSQL では昨年末の時点ですでにサポートされていましたが、Aurora MySQL でも[こちらの記事](https://aws.amazon.com/jp/about-aws/whats-new/2024/03/aurora-mysql-integration-amazon-bedrock-generative-ai/)のとおり ML 機能で Bedrock へのアクセスがサポートされたので、試してみました。

https://aws.amazon.com/jp/about-aws/whats-new/2024/03/aurora-mysql-integration-amazon-bedrock-generative-ai/

## 環境を準備する

試すには以下の環境が必要です。

- Bedrock をサポートするリージョンと VPC
  - 今回は東京リージョンで試しました
- 有効化された Bedrock のベースモデル
  - 今回は Claude 2.1 で試しました
- Public Network にアクセス可能な Aurora クラスター／インスタンス
  - 今回は Aurora を Private Subnet に配置し、NAT ゲートウェイ経由で Bedrock にアクセスできるよう構成しました
  - Bedrock の VPC エンドポイントも試そうとしましたが、Aurora からエンドポイント指定できないのでうまく使えませんでした
- Aurora にアクセス可能な EC2 など
  - MySQL Client のインストールが必要です
  - 今回の主題ではないので設定手順等は省略します

手順は[こちらの公式ユーザーガイド](https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/mysql-ml.html#aurora-ml-sql-privileges)を参考にしました。

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/mysql-ml.html#aurora-ml-sql-privileges

### Bedrock のベースモデルを有効化する

東京リージョンで Anthropic Claude を有効化します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/0bc8c378-6cca-1cfc-f553-151f42e31720.png)

:::note
今回必要なのは下から 2 つ目です。
:::

### VPC を作成する

- 東京リージョン
- 3 つの AZ（AZ-a・c・d）
- Public Subnet と Private Subnet の両方あり
- NAT ゲートウェイあり

で作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/96a76e0c-2931-8bc0-ce12-17a415923051.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/0794ff0c-088e-98c7-f035-5c9c851947f9.png)

### Aurora 用のポリシーとロールを作成する

Aurora から Bedrock を呼び出すためのポリシーとロールを作成します。

まずはポリシーから。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/a0191dff-6992-20c7-e3c4-0c4354cdb032.png)

Bedrock の`InvokeModel`を、すべてのリソースに対して許可します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/babe23c7-34fb-8ffa-0d8a-1846c5dd0f57.png)

適当な名前で作成します。

続いてロールを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/c0ebf0be-9477-55c4-97d8-6156af148a85.png)

RDS の「Add Role to Database」を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/16b2a49d-a493-feed-44d1-fac5e4fbd839.png)

先ほど作成したポリシーを追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/105d49b5-6bf5-c82d-d658-eb62c0f1c0be.png)

適当な名前で作成します。

### DB サブネットグループを作成する

最初に作成した VPC のうち、3 つの AZ にまたがる Private Subnet を選んで DB サブネットグループを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/0b17b4e7-0578-66f2-3e43-67ea33013fe4.png)

### Aurora クラスターのパラメータグループを作成する

Bedrock アクセス用のロールを指定するために、Aurora クラスターのパラメータグループを作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/25b443fb-aaf5-d574-2cd4-4ca5619be6a4.png)

作成したパラメータグループを編集して、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/6e1133b8-250a-e136-cbe5-6a1509d71113.png)

`aws_default_bedrock_role`の値として、先ほど作成したロールの ARN を入れて保存します。

### Aurora クラスター／インスタンスを作成する

- Aurora MySQL 3.06.0
- パブリックアクセスなし
  - 今回は Private Subnet に置いて NAT ゲートウェイで Bedrock にアクセスするため
- 先ほど作成した DB サブネットグループ
- 新規の VPC セキュリティグループ
  - 今回は EC2 コンピューティングリソースへの接続ついでに作成
- 先ほど作成した Aurora クラスターのパラメータグループ

を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/4624a34c-4157-6561-4a47-b3544c364f48.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/932f8c62-edaa-ec6f-6084-059c59fcb15e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/713ffd3e-8563-7b20-8b09-d791d79cb9bf.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/d5b12e80-907b-c3dc-efc9-064aa5477e03.png)

:::note warn
今回は Aurora に接続する EC2（過去の使い回し）の都合で古い証明書（今年の夏に期限が切れるもの）を指定していますが、通常は新しいものを使います。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/b66da7c6-60e2-95d5-1a55-e8bf95376178.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/3a68ccb8-fb8d-2f19-3d9d-3e21a8226333.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/96b40d66-c01d-de89-b1b6-f6be19c2d315.png)

作成が完了したら、最初のほうで作成したロールをクラスターに追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/9777ade2-5ad3-5efb-ad06-3f404b45c451.png)

さらに、Aurora インスタンスに設定されたセキュリティグループのアウトバウンドルールを編集して、Public Network に HTTPS アクセスできるようにしておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123899/d017b75e-d9c5-181e-15cf-2ca478761668.png)

これで環境が準備できました。

## 試してみる

EC2 から Aurora に MySQL Client で接続して試してみます。

### Bedrock アクセス用のストアドファンクションを作成する

まずはテスト用の DB（スキーマ）を作成します。

```sql:DBスキーマ作成
CREATE DATABASE bedrock_test;
USE bedrock_test;
```

続いて、Bedrock に接続するための権限を、接続中の MySQL ユーザーに付与します。

```sql:権限付与(1)
GRANT AWS_BEDROCK_ACCESS TO 【接続中ユーザー】;
```

そして Claude 2.1 アクセス用ストアドファンクションを作成します。

```sql:ストアドファンクション作成
CREATE FUNCTION invoke_claude (request_body TEXT)
    RETURNS TEXT
    ALIAS AWS_BEDROCK_INVOKE_MODEL
    MODEL ID 'anthropic.claude-v2:1'
    CONTENT_TYPE 'application/json'
    ACCEPT 'application/json';
```

ストアドファンクションの実行権限も接続中の MySQL ユーザーに付与します。

```sql:権限付与(2)
GRANT EXECUTE ON FUNCTION bedrock_test.invoke_claude TO 【接続中ユーザー】;
```

### プロンプト用テーブルを作成し、サンプルデータを挿入する

プロンプトを入れるためのテーブルを作成します。

```sql:テーブル作成
CREATE TABLE prompts (request varchar(1024));
```

そこにサンプルデータを入れます。

```sql:サンプルデータ挿入
INSERT INTO prompts VALUES (
'{
    "prompt": "\\n\\nHuman: JAWS-UGってなんですか？\\n\\nAssistant:",
    "max_tokens_to_sample": 300,
    "temperature": 0.5,
    "top_k": 250,
    "top_p": 1,
    "stop_sequences": [
        "\\n\\nHuman:"
    ],
    "anthropic_version": "bedrock-2023-05-31"
}');
```

### 実行

ストアドファンクションを使って Claude 2.1 に問い合わせてみます。

```sql:実行
SELECT invoke_claude(request) FROM prompts\G
```

すると、こんな結果が返ってきました（惜しいような惜しくないような…）。

```sql:結果
mysql> SELECT invoke_claude(request) FROM prompts\G
*************************** 1. row ***************************
invoke_claude(request): {"completion":" JAWS-UGとは、スクリーンリーダー「JAWS」のユーザーグループのことです。\n\nJAWSは視覚障害者などのためのスクリーンリーダーソフトウェアで、コンピュータの画面上のテキストを音声で読み上げることができます。JAWS-UGはこのJAWSを利用しているユーザーのコミュニティです。\n\nJAWS-UGでは、JAWSに関する情報交換やノウハウの共有、JAWSの操作方法や設定のアドバイスなどを行っています。また、JAWSの新しいバージョン情報や、視覚障害者向け情報技術全般に関する情報も提供しているようです。\n\n視覚障害者の情報アクセスを支援する技術の一つとして重要なJAWSですので、JAWS-UGはJAWSユーザーにとって有益なコミュニティだと思います。","stop_reason":"stop_sequence","stop":"\n\nHuman:"}
1 row in set (8.06 sec)
```

## Aurora PostgreSQL との違い

Aurora PostgreSQL との違いで大きいのは、

- MySQL にはベクトルを保存して検索する機能がない
  - PostgreSQL には pgvector がある
- Bedrock へのアクセスでも、埋め込み（Embeddings）用のモデルをサポートしていない

点でしょう。

このあたりをサポートしていれば、ベクターストアとしての活用が捗りそうなのですが。