Amazon Bedrock Knowledge Bases の構造化データ取得機能に詰まったこと

## 前書き
![2E82A7FE-ACB6-4918-9E10-95182ED1D410.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/3f6a9aab-270e-8f4d-8099-79cf08f85d67.jpeg)

AWS re:Invent 2024で紹介された Amazon Bedrock Knowledge Bases の構造化データ取得機能を試そうとしたところ、データの同期に失敗しました。:frowning2:

利用したリソースは下記の通り、デフォルトの設定で作成してます。

 - Amazon Redshift serverless
 - Knowledge Base with structured data store

## 対策

Knowledge Base作られた際に、よく見たら画面の上に下記のメッセージがありました。

```
Knowledge Base 'knowledge-base-quick-start-111kr' created successfully. Before you sync the query engine, you must grant “select” permissions on the database schema or tables to the selected authentication option. For IAM role authentication, create a user for this role with the name 'IAMR:AmazonBedrockExecutionRoleForKnowledgeBase_111kr' and grant the permissions to that user. For more information, see link.
```
訳したら下記の内容になります。

```text
クエリエンジンを同期する前に、選択した認証オプションに対してデータベーススキーマまたはテーブルに対する
「select」権限を付与する必要があります。IAMロール認証の場合、
『IAMR:AmazonBedrockExecutionRoleForKnowledgeBase_111kr』
という名前でそのロール用のユーザーを作成し、そのユーザーに権限を付与してください。
```

ちょっとややこしいのは、権限まわりの別対応が必要だと分かっていても、具体的にどこにどう手をつければいいのか分からない点です。1時間かけた結果、解決策が見つかりました:point_up_tone1:

作成されたAmazon Redshift serverlessに入って、Knowledge Baseのユーザーを作成して、権限渡す必要がありました。

仮にKnowledge Baseの名前が `AmazonBedrockExecutionRoleForKnowledgeBase_111kr`である場合、下記のクエリをまず流す必要があります。

```sql
CREATE USER AmazonBedrockExecutionRoleForKnowledgeBase_111kr PASSWORD 'Abc12345678';
```
PASSWORDは大文字・小文字を含む8文字以上であれば問題ありませんが、実際にKnowledge Baseから接続する際にはRoleを使用するため、PASSWORDは使われないようです。

次はKnowledge Baseユーザーにアクセス権限をお渡しします。
スキーマ指定して渡してもいいし、テーブル指定でも大丈夫です。

```sql
GRANT SELECT ON ALL TABLES IN SCHEMA dev.public TO AmazonBedrockExecutionRoleForKnowledgeBase_111kr;

GRANT SELECT ON certification_info TO "IAMR:AmazonBedrockExecutionRoleForKnowledgeBase_111kr";
```
権限渡してから、無事にデータの同期が成功しました。

## Knowledge Baseテスト

使用されたサンプルデータは下記の通りです。

```sql
-- 社員マスタテーブルの DDL
CREATE TABLE employee_master (
    employee_id INTEGER PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100),
    hire_date DATE,
    department VARCHAR(50),
    job_title VARCHAR(100)
);

-- サンプルデータの挿入
INSERT INTO employee_master (employee_id, first_name, last_name, email, hire_date, department, job_title)
VALUES
    (1, 'Taro', 'Yamada', 'taro.yamada@example.com', '2020-04-01', 'IT', 'Software Engineer'),
    (2, 'Hanako', 'Sato', 'hanako.sato@example.com', '2019-09-15', 'HR', 'HR Manager'),
    (3, 'Ichiro', 'Tanaka', 'ichiro.tanaka@example.com', '2021-01-10', 'Sales', 'Sales Representative'),
    (4, 'Yuki', 'Nakamura', 'yuki.nakamura@example.com', '2018-07-22', 'IT', 'System Administrator'),
    (5, 'Akiko', 'Suzuki', 'akiko.suzuki@example.com', '2022-03-01', 'Finance', 'Financial Analyst');

-- 格保有情報テーブルの DDL：
CREATE TABLE certification_info (
    certification_id INTEGER PRIMARY KEY,
    employee_id INTEGER,
    certification_name VARCHAR(100),
    certification_date DATE,
    expiration_date DATE,
    FOREIGN KEY (employee_id) REFERENCES employee_master(employee_id)
);

-- サンプルデータの挿入
INSERT INTO certification_info (certification_id, employee_id, certification_name, certification_date, expiration_date)
VALUES
    (1, 1, 'AWS Certified Solutions Architect - Professional', '2021-06-15', '2024-06-15'),
    (2, 1, 'ITIL Foundation', '2020-11-30', '2023-11-30'),
    (3, 2, 'SHRM-CP', '2020-03-10', '2023-03-10'),
    (4, 3, 'Salesforce Certified Administrator', '2022-01-20', '2024-01-20'),
    (5, 4, 'Cisco Certified Network Associate', '2019-09-05', '2022-09-05'),
    (6, 4, 'CompTIA Security+', '2021-04-18', '2024-04-18'),
    (7, 5, 'CFA Level 1', '2022-05-01', '2025-05-01');

```

@hayao_kさんの記事から拝借させていただきました。

https://qiita.com/hayao_k/items/460bf6aa8b0424eb0d82


ナレッジベースをテストしてみると、メタデータなしでも精度は高かったです。

![D71E5224-3C94-4605-B081-4DC0C4880B50.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/c21e2f29-484e-2af7-3a8e-524629bdbe39.jpeg)

Generate SQL queriesを選べば、sql文も作ってくれます。

![766FC6AC-F865-4E45-A901-3E223A411613_4_5005_c.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320164/9196de87-66a7-f9b7-a71c-6141817fdcca.jpeg)

## 最後

今までエージェントにデータ取得できるアクショングループを渡してましたが、Knowledge Bases の構造化データ取得機能利用した方が良かったかもしれません。
もう少し本番に近い環境で検証してみたいです。

## 参考記事

https://zenn.dev/fusic/articles/github-zenn-linkage-20241206-1#%E4%BA%8B%E5%89%8D%E6%BA%96%E5%82%99