Amazon Bedrock Knowledge Bases のベクターストアとして Aurora PostgreSQL が利用可能に！

この記事は [**セゾン情報システムズ Advent Calendar 2023**](https://qiita.com/advent-calendar/2023/sisco) シリーズ 2, 23 日目の記事でず。

## 2024/12/8 追記
以下のアップデートにより、Aurora Serverless でもナレッジベース用のベクターストアをクイック作成できるようになりました。本記事は手動での設定方法を解説しています。プロビジョンドクラスターや既存のクラスターに設定が必要な場合などはご参照いただければと思います。

https://aws.amazon.com/about-aws/whats-new/2024/12/amazon-aurora-quick-create-vector-store-bedrock-knowledge-bases/

## はじめに
2023/12/21 のアップデートで Knowledge Base for Amazon Bedrock のベクターストアとして Amazon Aurora PostgreSQL が選択可能になりました🎉

https://aws.amazon.com/jp/about-aws/whats-new/2023/12/amazon-aurora-postgresql-integration-bedrock-generative-ai/

上記のアップデートには以下の 2 つが含まれていますが、本記事では後者について扱います。
* Amazon Aurora ML から SQL で Amazon Bedrock 上の基盤モデルにアクセス可能に
* Knowledge Base for Amazon Bedrock のベクターストアとして Aurora PostgreSQL を選択可能に

Knowledge Base for Amazon Bedrock は任意の S3 バケットに検索対象とさせたいオブジェクトを配置するだけで、Amazon Bedrcok 上でマネージドな RAG の構成を簡単に実装できる機能です。そのほかの詳細や設定手順については以下の記事で触れていますので、もしよろしければご参照ください。

https://qiita.com/hayao_k/items/18d8bb7d59942a240782

## Aurora PostgreSQL の価格面のメリット
これまでは以下の 3 つのデータベースがサポートされていました。

* Vector Engine for Amazon OpenSearch Servelerless
* Pincone
* Redis Enterprise Cloud

Pincone および Redis Enterprise Cloud は AWS のサービスではありません。AWS のサービスを利用する必要がある場合は、Vector Engine for Amazon OpenSearch Serverless が唯一の選択肢でした。OpenSearch Serverless は Knowledge Base の Quick Setup から簡単に作成できる一方で、小規模利用におけるコストに課題があります。

OpenSearch Serverless のコンピューティング料金は OpenSearch Compute Unit (OCU) の使用量によって請求されます。2023/12/24 時点でバージニア北部リージョンの料金は $0.24 per OCU per hour です。

開発/テストモードを有効化 (スタンバイレプリカを無効化) した場合でも、最低 1 OCU が請求されるため　0.24 × 1 × 730 = $175.2/月 程度の料金が発生します。

Aurora PostgreSQL では Serverless v2 の最小容量 である 0.5 ACU のケースで 0.12 × 0.5 × 730 = $43.8/月 程度の料金になります。

:::note info
2024/11/21 追記
アップデートにより Aurora Serverless v2 が 0 ACU へのスケーリングをサポートし、自動停止時のコンピューティングコストが $0 になりました。🎉
:::

https://aws.amazon.com/jp/about-aws/whats-new/2024/11/amazon-aurora-serverless-v2-scaling-zero-capacity/

プロビジョンドインスタンスの場合、db.r6g.large で $189.80/月 の料金ですが、使用していない間は最大 7 日間インスタンスの停止が行えるため、これにより料金を節約することも可能です。

## 前提条件
Aurora PostgreSQL クラスターを Knowledge Base for Amazon Bedrock で使用するには以下の前提条件を満たす必要があります。

* エンジンバージョン
    * 15.4 以降
    * 14.9 以降
    * 13.12 以降
    * 12.16 以降
* pgvector 拡張機能のバージョン
    * 0.5.0 以降
* Data API の有効化
* Secrets Manager で管理されるユーザー情報による接続

Knowledge base から Aurora への接続は Data API を介しておこなわれます。え、Data API って Aurora Serverless v1 だけでは！？と思われた皆さん、ご安心ください。同日のアップデートで Data API が Aurora PostgreSQL のプロビジョンドインスタンスおよび Serverless v2 でもサポートされました。

https://aws.amazon.com/jp/blogs/database/introducing-the-data-api-for-amazon-aurora-serverless-v2-and-amazon-aurora-provisioned-clusters/

:::note warn
プロビジョンドインスタンスの場合、バースト可能クラス (t 系) では Data API はサポートされていませんのでご注意ください。
:::

https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/data-api.html#data-api.limitations

> **Limitations with RDS Data API**
> * Data API isn't supported on T DB instance classes.

## やってみる
### Aurora PostgreSQL クラスターの作成
今回は以下の設定で新規クラスターを作成しました。
* エンジンバージョン: 15.5
* 認証情報の設定: AWS Secrets Manager でマスター認証情報を管理
* DB インスタンスクラス: Serverless v2
* 容量の範囲: 最小 0.5 ACU、最大 1 ACU
* マルチ AZ 配置: Aurora レプリカを作成しない
* パブリックアクセス: なし
* モニタリング: Perfomance Insights オフ、拡張モニタリング無効化
* RDS Data API: 有効化

:::note warn
記事投稿当初、Aurora クラスターにパブリックアクセスが必要と記載しておりましたが、誤りでした🙇‍♂️ パブリックアクセスの設定やセキュリティグループへのルール追加は不要です。[@takakuni_](https://twitter.com/takakuni_) さん、ご指摘ありがとうございます！

:::

Data API の有効化をお忘れなく。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/90690060-fdd4-f629-ea59-d9a236066280.png)

### Aurora PostgreSQL クラスターの設定
コンソールのクエリエディタを使用してマスターユーザーでデフォルトの postgres データベースに接続します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/504626ba-2f35-0fa2-282a-f0891ed60bec.png)

pgvector 拡張機能をインストールします。

```sql
-- pgvegtor 拡張機能のインストール
CREATE EXTENSION IF NOT EXISTS vector;

-- pgvector のバージョン確認
SELECT extversion FROM pg_extension WHERE extname='vector';
```

pgvector のバージョンは 0.5.0 以降である必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/4c6eab2d-0cb7-10b1-24b4-e74bb006e6c6.png)

スキーマおよびロールを作成し、権限を付与します。

```sql
-- スキーマの作成
CREATE SCHEMA bedrock_integration;

-- ロールの作成
CREATE ROLE bedrock_user WITH PASSWORD 'your_password' LOGIN;

-- スキーマに対する権限を付与
GRANT ALL ON SCHEMA bedrock_integration to bedrock_user;
```

AWS Secrets Manager で bedrock_user の RDS データベースの認証情報を作成します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/9eae11a1-a3ad-1146-9b35-bde4dca15475.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/2c13fbc1-21e4-37d8-7561-b0406e356ef2.png)

クエリエディタで bedrock_user の認証情報を使用して postgres データベースに接続し、テーブルおよびインデックスを作成します。

```sql
-- テーブルの作成
CREATE TABLE bedrock_integration.bedrock_kb (id uuid PRIMARY KEY, embedding vector(1536), chunks text, metadata json);

-- インデックスの作成
CREATE INDEX on bedrock_integration.bedrock_kb USING hnsw (embedding vector_cosine_ops);
```

### Knowledge base の作成
Bedrock コンソールの Orchestration から Knowledge base を選択し、Create knowledge base へ進みます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/53cb921d-5d61-14db-794a-fa447d7cb01f.png)

Step 1 で Knowledge base の名前および詳細を入力します。ここではすべてデフォルト値のまま次へ進みます。サービスロールも新規作成を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/8b17b5cb-2ce7-1e1e-8aa8-fc22ab5399a5.png)

Step 2 でデータソースの配置先となる S3 バケットを指定します。オブジェクトがカスタマー管理の KMS キーで暗号化されている場合は Add customer-managed KMS key for S3 data にチェックを入れます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/f62c185a-15d2-5559-49da-ac261a9beaaf.png)

Step 3 でベクターストアの設定を行います。`Choose a vector store you have created` から　Amazon Aurora を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/d607727d-3edd-c05c-ad0c-9f9f82f2658e.png)

Aurora Cluster の接続情報を入力します。

* Amazon Aurora DB Cluster ARN: `arn:aws:rds:<region>:<account_id>:cluster:<your_cluster>`
* Database name: postgres
* Table Name: bedrock_integration.bedrock_kb
* Secret ARN: `arn:aws:secretsmanager:<region>:<account_id>:secert:<your_secert>`
* Customer managed KMS key for your secret: secret をカスタマー管理キーで暗号化している場合に KMS キーの ARN を指定


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/a3b3efe7-b1fa-1843-7ede-8bb9dd8aeec3.png)

Index field mapping で次の情報を入力します。(bedrock_kb テーブルの定義とマッピングします。)

* Vector field: embedding
* Text field: chunks
* Bedrock-managed metadata field: metadata
* Primary key: id

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/6207dadb-1b70-64eb-c3a5-4ab0cbb87836.png)

Step 4 で入力内容を確認し、Knowledge base の作成を完了します。Knowledge base の作成が完了したら最初に S3 バケット上に配置したデータを同期する必要があるため、Sync をクリックします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/9e93a6e3-7dad-ed7d-b882-6de6020b198f.png)

今回はあらかじめ [PDF 版 のAmazon Bedrock のユーザーガイド (英語)](https://docs.aws.amazon.com/bedrock/latest/userguide/bedrock-ug.pdf) を S3 バケットに格納しています。

## 動作確認
コンソールの Test Knowledge base から Bedrock のユーザーガイドを元に回答が生成されることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/aeedee1b-68db-d1b4-b608-92d8235e8eb2.png)

クエリエディタに接続し、bedrock_kb テーブルを参照してみると、ベクトルデータが格納されていることがわかります。

```sql
select * from bedrock_integration.bedrock_kb limit 10;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/a81b9a3e-3fd2-fa62-6bb5-526d99676741.png)


## 参考
https://docs.aws.amazon.com/AmazonRDS/latest/AuroraUserGuide/AuroraPostgreSQL.VectorDB.html


以上です。
参考になれば幸いです。