Amazon Q Developer CLI を利用してノーコーディングでアプリのカスタマイズに挑戦！

## はじめに
こちらは、Amazon Q Developer CLIを利用して、OSSの生成AIアプリケーションである[GenU](https://aws-samples.github.io/generative-ai-use-cases-jp/)をノーコーディングでカスタマイズに挑戦する記事です。「直接コードを修正せずに、Amazon Q Developer CLIを利用してコードをカスタマイズする」というルールを科して、人事規定についての質問に答えてくれる「HRアシスタント」というRAGの機能をGenUに追加してみます。ぶっつけ本番の企画なので、この「はじめに」を書いている段階では成功するかわかっていません（笑）。

まずカスタマイズを始める前に、今回利用するAmazon Q Developer CLIとGenUをご説明します。

### Amazon Q Developer CLIとは

Amazon Q Developerとは、ソフトウェア開発のための生成AIを活用したアシスタントツールとなっています。コード生成、コードの変換、テストコードの生成など、ソフトウェア開発を便利にするさまざまな機能を備えています。

Amazon Q Developer CLIとは、このAmazon Q Developerをより便利に使うためのCLI（コマンドラインインターフェース）で、ターミナル上で開発者と対話をしながらコードの生成などを行うことができます。詳しくは、[こちらの記事](https://aws.amazon.com/jp/blogs/news/introducing-the-enhanced-command-line-interface-in-amazon-q-developer/)をご覧ください。

また、このCLIは追加料金無しで利用することが可能です。Amazon Q Developerの料金体系については、[こちらのページ](https://aws.amazon.com/jp/q/developer/pricing/)をご参照ください。

:::note warn
※2025/3/20現在、Amazon Q Developer CLIはWindowsでは利用できません。Windowsから利用したい場合は、WSL2などを利用して仮想環境上のLinuxから利用する必要があります。

:::

### GenUとは

[GenU](https://aws-samples.github.io/generative-ai-use-cases-jp/)とは、主にAWSの有志が開発している業務活用ができる生成AIアプリのOSSとなります。CDKを使って実装しているため、[たった3行のデプロイコマンド](https://aws-samples.github.io/generative-ai-use-cases-jp/ABOUT.html#%E3%83%87%E3%83%97%E3%83%AD%E3%82%A4)を実行するだけで、直ぐにアプリケーションを利用することができます。

LLMチャット、RAGチャット、翻訳などの生成AIのよくあるユースケースをはじめ、執筆、ダイアグラム生成、画像生成、動画生成などのより応用的なユースケースを備えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/0feb9636-7364-4fa8-8012-7421c8c34b40.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/ceb4851a-1747-4229-a20f-bab242a4e0ab.png)

今回はコードをカスタマイズして機能追加を行なっていきますが、ビルダーモードの機能を利用すると、プロンプトを定義するだけでコードをカスタマイズすることなく独自のユースケースを作成することができます。また、作成したユースケースは同一環境内の別ユーザーに共有することも可能です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/ef2f3c56-0158-48d6-afe5-deaeb8fad555.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/739c9c28-e49b-44e2-b86b-2090a6809bf2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/5b6d0158-12a4-4b3e-a033-9f1a89c2adb4.png)


## Amazon Q Developer CLIを使ったカスタマイズ

では、早速カスタマイズを始めていきます。はたして、ノーコーディングでカスタマイズができるのでしょうか…

### 前提条件

- Amazon Q Developer Proのユーザーを利用します
- GenUのデプロイと、ローカル開発環境は完了している状態でスタートします
- VS CodeのターミナルからCLIを実行します
- デプロイコマンド等は、適宜開発者が直接実行します

### カスタマイズ開始

#### 画面の新規追加

まずは、「HRアシスタント」の画面を追加します。こちらはRAGの機能なので、標準ユースケースとして実装されている「RAGチャット」の機能を参考に実装してもらいます。

ターミナルに`q chat [指示]`というコマンドを入力するだけで、Amazon Q Developer CLIにアクセスすることができて、それ以降は対話形式で開発を進めていくことができます。生成AIで実行するタスク全般に言えることですが、CLIに入力する指示はより具体的にすることが大事です。曖昧な指示では、自分の求めているコードを生成しない可能性が高くなります。人間に作業をお願いする時と同じように、自分のやって欲しいことを丁寧に伝えるようにしましょう。

```bash:Amazon Q Developer への指示
q chat 「HRアシスタント」という機能を追加してください。この機能はユーザーが人事規定に関する質問をすると、KnowledgeBaseから人事規定を検索して、その検索結果を元に回答を生成するRAGチャットの機能です。RagKnowledgeBasePageを参考に機能を追加してください。フロントエンドの修正だけでOKです。
```

コマンドを実行すると、Amazon Q Developerのエージェントが指示を実行するために必要な作業を考えて、自律的に作業を行います。以下の様に、エージェントの思考過程が表示されていくので、それを眺めながら待ちましょう。ソースの修正やコマンドの実行が必要な場合は、CLIがユーザーに実行許可を求めてくるので、その都度 `y` を入力して実行を許可してあげる必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/667509dd-5959-4b05-810f-f3b73134c881.png)

作業が完了すると、以下の様に作業内容のサマリーが表示されるので、エージェントがどの様な作業を行なったのかを確認できます。

```bash:実行結果サマリー

「HRアシスタント」機能を追加しました。この機能は、ユーザーが人事規定に関する質問をすると、KnowledgeBaseから人事規定を検索して、その検索結果を元に回答を生成するRAGチャッ
ト機能です。

実装内容の概要：

1. HrAssistantPage.tsx の作成
   • RagKnowledgeBasePageをベースに、HRアシスタント専用のページコンポーネントを作成
   • 人事規定に特化したUIメッセージを追加（空の状態での案内メッセージなど）
   • タイトルを「HRアシスタント」に変更

2. ルーティングの追加
   • main.tsxに新しいルート /hr-assistant を追加
   • HrAssistantPageコンポーネントをインポート

3. サイドメニューへの追加
   • App.tsxのサイドメニュー項目に「HRアシスタント」を追加
   • PiUserCircleアイコンを使用して人事関連であることを視覚的に表現
   • サブタイトルとして「人事規定」を表示

4. 機能フラグの追加
   • hrAssistantEnabled フラグを追加して機能を制御できるようにした
   • 現在はデフォルトで有効（true）に設定

この実装により、ユーザーはサイドメニューから「HRアシスタント」を選択し、人事規定に関する質問をすることができます。質問は既存のKnowledge Base機能を利用して処理され、関連
する人事規定の情報を元に回答が生成されます。
```

さらに具体的な作業内容は、Gitのコード差分を見ることで把握することができます。エージェントへの指示がやりやすくなるため、できれば毎回コード差分も見る様にしておきましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/89022dc2-1396-4aff-aa42-3280b19525dd.png)

今回の修正内容を見ると、`hrAssistantEnabled`という変数で「HRアシスタント」の利用可否を制御するようなコードを生成していますが、「HRアシスタント」は必ず使う機能なので、この制御は不要です。追加で指示をして、この部分を修正してもらいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/71113dbf-3bbf-478f-a605-9ae52b9bfe34.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/f7f4e902-1791-4e64-a976-78c3dd20be63.png)

以下の様に、具体的に指示を行います。追加の指示を行う前に、`git add .`で変更内容をステージングしておくと、追加の指示でどこを修正したのかがよりわかりやすくなります。なお、2回目以降の会話の場合は、`q chat`の記述は不要です。

```bash:Amazon Q Developer への指示
hrAssistantEnabledを使って利用可否を制御していますが、HRアシスタントは必ず利用する機能なので、固定表示にしてください。
```

```bash:実行結果サマリー
HRアシスタント機能を固定表示に変更しました。以下の修正を行いました：

1. hrAssistantEnabledフラグの削除
   • main.tsxからhrAssistantEnabledフラグを削除
   • App.tsxからも同様に削除

2. ルーティングの修正
   • main.tsxのルート定義で、条件分岐を使わずに直接HRアシスタントのルートを追加
  javascript
   {
     path: '/hr-assistant',
     element: <HrAssistantPage />,
   },
   

3. サイドメニュー項目の修正
   • App.tsxのサイドメニュー項目で、条件分岐を使わずに直接HRアシスタントのメニュー項目を追加
  
javascript
   {
     label: 'HRアシスタント',
     to: '/hr-assistant',
     icon: <PiUserCircle />,
     display: 'usecase' as const,
     sub: '人事規定',
   },
   

これにより、HRアシスタント機能は環境変数や設定に関わらず、常に表示・利用可能になりました。サイドメニューには「HRアシスタント」という項目が固定で表示され、ユーザーはいつ
でもこの機能にアクセスできます。
```

コード差分を見てみると、指示した通り`hrAssistantEnabled`が削除されていることがわかります。このように、生成されたコードに不満がある場合は、追加指示を行うことで修正することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/edfab1fc-3ff6-49b1-b1b9-3094413766fa.png)

では、現時点のコードで動作を確認してみます。以下の様にメニューに「HRアシスタント」が表示され、そこをクリックするとチャット画面が表示されました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/d34dbdd0-f537-4dde-9745-2742f21666b2.png)

標準のRAGチャットをベースにコードが生成されたので、既存のKnowledgeBaseのデータを元に回答が生成されると思います。私のKnowledgeBaseの環境にはBedrockのユーザーガイドが登録されているため、Bedrockの質問に答えてくれるはずです。試してみましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/c4dbf16f-899e-4e43-ac7b-c555bc2a14d8.png)

予想通り、Bedrockユーザーガイドを元に回答を生成してくれました。たった、2つの指示だけでこの画面を作ってくれました。続いて、この画面の作り込みを行なっていきます。

### 画面の作り込み

「HRアシスタント」は人事規定の質問について答えてくれる機能なので、人事規定以外のドキュメントは検索したくありません。今回は、KnowledgeBaseのメタデータフィルタリングの機能を使って、ドキュメントの絞り込み検索を行っていきます。

RAGチャットにはメタデータフィルタリングの機能が標準搭載されており、以下の設定画面からフィルタリングの設定を行うことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/648282dc-433e-4d44-8076-a79ab272a1a3.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/78b0c4ab-64c6-4145-87d9-68c404453496.png)

このメタデータフィルタリングの機能を利用して、カテゴリが「HR」のドキュメントだけを検索するようにすれば、実現できそうです。

しかし、今回は思いつきで「HRアシスタント」を作ることにしたので、動作確認に利用できるデータを持ち合わせていません。せっかくなので、Amazon Q Developer CLIを利用してテストデータを作成したいと思います。GenUでは、`packages/cdk/rag-docs/docs`にドキュメントを格納することで、KnowledgeBaseで利用するS3バケットに自動でファイルをアップロードすることができます。では、以下の通り指示をしてテストデータが自動作成できるか試してみましょう。

```bash:Amazon Q Developer への指示
HRアシスタントのテストデータを作成してください。テストデータはマークダウン形式として、適当な人事規定を作成して保存してください。保存先は、"packages/cdk/rag-docs/docs"です。metadataの定義も行ってください。categoryを"HR"として、それ以外は設定不要です。
```
```bash:実行結果サマリー

HRアシスタントのテストデータとして、3つの人事規定のマークダウンファイルとそれぞれのメタデータファイルを作成しました。

### 作成したファイル

1. 一般人事規定
   • ファイル: hr-policy-general.md
   • メタデータ: hr-policy-general.md.metadata.json
   • 内容: 雇用区分、採用、異動、休職、退職、定年、解雇などの基本的な人事規定

2. 休暇制度規定
   • ファイル: hr-policy-leave.md
   • メタデータ: hr-policy-leave.md.metadata.json
   • 内容: 年次有給休暇、特別休暇（結婚、忌引、産前産後、育児、介護など）の詳細規定

3. 給与規定
   • ファイル: hr-policy-salary.md
   • メタデータ: hr-policy-salary.md.metadata.json
   • 内容: 給与の構成、計算期間、支払方法、昇給、降給、休職中の給与などの規定

### メタデータの設定

各ファイルのメタデータには、以下の情報を設定しました：

json
{
  "metadataAttributes": {
    "category": "HR",
    "title": "（各規定のタイトル）",
    "tag": ["人事", "（関連タグ）"],
    "is_public": true
  }
}


これらのファイルは指定された場所（packages/cdk/rag-docs/docs）に保存されており、HRアシスタント機能のテストに使用できます。ユーザーが人事規定に関する質問をすると、これら
のドキュメントから関連情報が検索され、回答が生成されます。

```


無事、3種類のテストデータを作成してくれました。メタデータについても、標準構成に含まれているmetadataサンプルを自動で読み込んで、それを参考に出力してくれました。生成されたテストデータを見たい方は、以下を展開してご確認ください。

<details><summary>一般人事規定（テストデータ）</summary>

```text:hr-policy-general.md
# 一般人事規定

## 1. 目的

本規定は、当社における人事管理の基本的事項を定め、公正な人事管理を実施することにより、会社の円滑な運営と従業員の福祉増進を図ることを目的とする。

## 2. 適用範囲

本規定は、当社のすべての従業員に適用する。ただし、別途個別の契約を締結している場合は、その契約を優先する。

## 3. 雇用区分

当社の従業員は、以下の区分に分類される。

1. 正社員：期間の定めのない雇用契約を締結した従業員
2. 契約社員：期間を定めた雇用契約を締結した従業員
3. パートタイマー：1日または1週間の所定労働時間が正社員より短い従業員
4. アルバイト：学生等で、一時的または補助的な業務に従事する従業員

## 4. 採用

1. 当社は、公正な採用選考を行い、能力・適性・経験等を総合的に判断して採用を決定する。
2. 採用に際しては、所定の書類の提出を求める。
3. 採用後3ヶ月間は試用期間とし、この期間中に不適格と認められた場合は、解雇することがある。

## 5. 異動・配置転換

1. 会社は、業務上の必要性に応じて、従業員に対して配置転換、転勤、出向等の人事異動を命じることがある。
2. 従業員は、正当な理由なくこれを拒むことはできない。

## 6. 休職

1. 従業員が以下の各号のいずれかに該当するときは、休職を命じることがある。
   - 業務外の傷病により、連続して1ヶ月以上欠勤したとき
   - 私事により、1ヶ月以上欠勤するとき
   - その他、会社が休職を必要と認めたとき

2. 休職期間は、原則として以下の通りとする。
   - 業務外の傷病による休職：勤続年数に応じて3ヶ月〜1年
   - 私事による休職：3ヶ月以内

## 7. 退職

1. 従業員が以下の各号のいずれかに該当するときは、退職とする。
   - 自己都合により退職を申し出て、会社が承認したとき
   - 定年に達したとき
   - 休職期間が満了し、復職できないとき
   - 死亡したとき

2. 自己都合による退職の場合は、原則として退職予定日の1ヶ月前までに所定の退職届を提出しなければならない。

## 8. 定年

1. 従業員の定年は満60歳とし、定年に達した月の末日をもって退職とする。
2. 会社が必要と認めた場合は、本人の希望により65歳まで再雇用することがある。

## 9. 解雇

1. 会社は、従業員が以下の各号のいずれかに該当する場合は、解雇することがある。
   - 勤務成績または業務能率が著しく不良で、向上の見込みがないとき
   - 精神または身体の障害により、業務に耐えられないとき
   - 事業の縮小、廃止等やむを得ない経営上の理由があるとき
   - その他、前各号に準ずるやむを得ない事由があるとき

2. 解雇を行う場合は、少なくとも30日前に予告するか、または平均賃金の30日分の解雇予告手当を支払う。

## 10. 改定

本規定は、法令の改正や社会情勢の変化、または会社の経営状況等により、必要に応じて変更することがある。

```

```json:hr-policy-general.md.metadata.json
{
  "metadataAttributes": {
    "category": "HR",
    "title": "一般人事規定",
    "tag": ["人事", "規定", "雇用"],
    "is_public": true
  }
}

```
</details>


<details><summary>休暇制度規定（テストデータ）</summary>

```text:hr-policy-leave.md
# 休暇制度規定

## 1. 目的

本規定は、従業員の休暇に関する基本的事項を定め、従業員の心身の健康維持・増進およびワークライフバランスの実現を図ることを目的とする。

## 2. 適用範囲

本規定は、当社のすべての従業員に適用する。ただし、パートタイマーおよびアルバイトについては、別途定める規定に従うものとする。

## 3. 年次有給休暇

1. 会社は、6ヶ月間継続勤務し、所定労働日の8割以上出勤した従業員に対して、10日の年次有給休暇を付与する。
2. 以降は、1年間継続勤務するごとに、下記の日数を付与する。
   - 2年6ヶ月: 11日
   - 3年6ヶ月: 12日
   - 4年6ヶ月: 14日
   - 5年6ヶ月: 16日
   - 6年6ヶ月以上: 20日

3. 年次有給休暇は、従業員の請求する時季に与える。ただし、事業の正常な運営を妨げる場合は、他の時季に変更することがある。
4. 年次有給休暇の有効期間は、付与日から2年間とする。
5. 会社は、毎年5日間の年次有給休暇について、従業員ごとに時季を指定して取得させる。

## 4. 特別休暇

従業員が次の各号のいずれかに該当するときは、特別休暇を与える。

1. 結婚休暇
   - 本人の結婚: 連続5日間
   - 子の結婚: 2日間

2. 忌引休暇
   - 配偶者: 7日間
   - 父母、子: 5日間
   - 祖父母、兄弟姉妹: 3日間
   - 配偶者の父母: 3日間
   - その他の同居の親族: 1日間

3. 産前産後休暇
   - 産前休暇: 出産予定日の6週間前（多胎妊娠の場合は14週間前）から出産日まで
   - 産後休暇: 出産日の翌日から8週間

4. 育児休業
   - 子が1歳に達するまで（特別な事情がある場合は最長2歳まで）
   - 両親ともに育児休業を取得する場合は、子が1歳2ヶ月に達するまで（パパ・ママ育休プラス）

5. 介護休業
   - 対象家族1人につき、通算93日まで

6. 子の看護休暇
   - 小学校就学前の子を養育する従業員は、1年につき5日間（子が2人以上の場合は10日間）

7. 介護休暇
   - 要介護状態にある家族を介護する従業員は、1年につき5日間（対象家族が2人以上の場合は10日間）

8. リフレッシュ休暇
   - 勤続5年ごとに連続5日間

## 5. 休暇の申請手続き

1. 年次有給休暇を取得する場合は、原則として3日前までに所定の申請書を提出しなければならない。
2. 特別休暇を取得する場合は、事由発生後速やかに所定の申請書を提出しなければならない。
3. 傷病による休暇が連続5日以上に及ぶ場合は、医師の診断書を提出しなければならない。

## 6. 休暇中の賃金

1. 年次有給休暇期間中は、通常の賃金を支給する。
2. 特別休暇期間中の賃金については、各休暇制度ごとに別途定める。

## 7. 改定

本規定は、法令の改正や社会情勢の変化、または会社の経営状況等により、必要に応じて変更することがある。

```

```json:hr-policy-leave.md.metadata.json
{
  "metadataAttributes": {
    "category": "HR",
    "title": "休暇制度規定",
    "tag": ["人事", "休暇", "有給", "育児休業"],
    "is_public": true
  }
}
```
</details>

<details><summary>給与規定（テストデータ）</summary>

```text:hr-policy-salary.md
# 給与規定

## 1. 目的

本規定は、従業員の給与に関する事項を定め、適正な給与管理を行うことを目的とする。

## 2. 適用範囲

本規定は、当社のすべての従業員に適用する。ただし、パートタイマーおよびアルバイトについては、別途定める規定に従うものとする。

## 3. 給与の構成

給与は、基本給、諸手当および賞与で構成する。

1. 基本給
   - 職能給：職務遂行能力に応じて決定する部分
   - 役割給：役職・職責に応じて決定する部分

2. 諸手当
   - 役職手当：管理職に対して支給
   - 家族手当：配偶者および子に対して支給
   - 住宅手当：住宅費の負担を軽減するために支給
   - 通勤手当：通勤に要する実費を支給（上限あり）
   - 時間外勤務手当：法定時間外労働に対して支給
   - 深夜勤務手当：22時から翌5時までの勤務に対して支給
   - 休日勤務手当：法定休日の勤務に対して支給
   - 資格手当：会社が認める資格保有者に支給

3. 賞与
   - 原則として年2回（夏季・冬季）支給
   - 会社の業績および個人の勤務成績を考慮して決定

## 4. 給与の計算期間および支払日

1. 給与の計算期間は、毎月1日から末日までとする。
2. 給与の支払日は、翌月15日とする。ただし、支払日が休日の場合は、その前営業日に支払う。
3. 賞与の支給日は、原則として7月および12月とする。

## 5. 給与の支払方法

1. 給与は、従業員の指定する金融機関の口座に振り込むことにより支払う。
2. 給与から次の項目を控除する。
   - 所得税、住民税
   - 健康保険料、厚生年金保険料、雇用保険料
   - その他、従業員の同意に基づくもの

## 6. 昇給

1. 昇給は、原則として年1回、4月に実施する。
2. 昇給額は、人事評価、会社の業績等を考慮して決定する。
3. 次の各号のいずれかに該当する場合は、昇給を行わないことがある。
   - 人事評価が著しく低い場合
   - 懲戒処分を受けた場合
   - 休職中の場合

## 7. 降給

次の各号のいずれかに該当する場合は、降給を行うことがある。
1. 人事評価が著しく低い状態が続く場合
2. 懲戒処分を受けた場合
3. 職制の変更、降格等があった場合
4. 会社の業績が著しく悪化した場合

## 8. 休職中の給与

1. 業務上の傷病による休職の場合は、労災保険から給付を受けるものとする。
2. 業務外の傷病による休職の場合は、原則として基本給の70%を支給する。ただし、健康保険から傷病手当金が支給される場合は、その差額を支給する。
3. 私事による休職の場合は、給与を支給しない。

## 9. 退職時の給与

1. 退職者の給与は、退職日までの日割計算とする。
2. 退職金は、別途定める退職金規程に基づき支給する。

## 10. 改定

本規定は、法令の改正や社会情勢の変化、または会社の経営状況等により、必要に応じて変更することがある。
```

```json:hr-policy-salary.md.metadata.json
{
  "metadataAttributes": {
    "category": "HR",
    "title": "給与規定",
    "tag": ["人事", "給与", "賞与", "手当"],
    "is_public": true
  }
}
```
</details>

このテストデータをKnowledgeBaseに適用するためには、`npm run cdk:deploy`でCDKをデプロイ（自動でファイルもアップロードされる）して、AWSのコンソール画面からKnowledgeBaseをSyncする必要があります。こちらは、私自身が手動で実施しました。

実際にテストデータを使ってHRアシスタントの動作確認をしたところ、以下の通りテストデータを元に回答されていることが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/d77b5fe4-ae92-4b7a-a241-54902216e1df.png)

それでは、本題のメタデータのカテゴリが「HR」のドキュメントだけを検索するように修正していきます。今回は、以下の指示をしました。

```bash:Amazon Q Developer への指示
現在、HRアシスタントでは、KnowledgeBaseに登録されている全てのドキュメントが検索対象となります。人事規定のドキュメントはcategory="HR"で登録しているため、HRアシスタントでは固定でcategory="HR"の条件でドキュメントを検索する様にしてください。また、画面上からメタデータフィルタリングの設定をできない様にしてください。
```

```bash:実行結果サマリー

HRアシスタント機能を修正し、固定でcategory="HR"の条件でドキュメントを検索するようにしました。また、画面上からメタデータフィルタリングの設定をできないようにしました。

### 主な変更点

1. 固定フィルターの実装
   • getExtraDataFromFilters 関数を修正し、常に category="HR" のフィルターを返すようにしました
  
javascript
   const getExtraDataFromFilters = useCallback(() => {
     // 固定でcategory="HR"のフィルターを追加
     const hrCategoryFilter: RetrievalFilter = {
       metadataAttributes: {
         key: 'category',
         value: 'HR'
       }
     };

     // 固定フィルターをExtraDataとして返す
     return [
       {
         type: 'json',
         name: 'filter',
         source: {
           type: 'json',
           mediaType: 'application/json',
           data: JSON.stringify(hrCategoryFilter),
         },
       } as ExtraData
     ];
   }, []);
   


2. フィルター設定UIの削除
   • 設定ボタンと設定モーダルを削除
   • InputChatContentから setting と onSetting プロパティを削除
   • ModalDialogコンポーネントとその中身を削除

3. 不要なコードの削除
   • フィルター関連のステート管理を削除
   • フィルター変換関数を削除
   • 不要なインポートを削除

4. ステートの簡素化
   • filters ステートと setFilters 関数を削除
   • onReset 関数からフィルターリセット処理を削除

これらの変更により、HRアシスタントは常に人事規定（category="HR"）のドキュメントのみを検索対象とし、ユーザーはフィルター設定を変更できなくなりました。これにより、HRアシ
スタントは人事規定に特化した質問応答に集中できるようになりました。

```

上記の通り、コードの修正を行ってくれました。しかし、修正したファイルには以下のエラーがありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/325d6956-6d60-48a4-88a1-83226f102f3c.png)

```text:エラー内容
Object literal may only specify known properties, and 'metadataAttributes' does not exist in type 'RetrievalFilter'.ts(2353)
(property) metadataAttributes: {
    key: string;
    value: string;
}
```

こちらもCLIを使って、修正してもらいます。

```bash:Amazon Q Developer への指示
先ほど追加したコードでエラーが発生しているので、修正してください。
Object literal may only specify known properties, and 'metadataAttributes' does not exist in type 'RetrievalFilter'.ts(2353)
(property) metadataAttributes: {
    key: string;
    value: string;
}
```
```bash:実行結果サマリー

エラーを修正しました。RetrievalFilter 型の正しい形式に合わせてフィルターオブジェクトを修正しました。

### 修正内容

metadataAttributes プロパティは RetrievalFilter 型に存在しないため、正しい形式に変更しました。

修正前:
typescript
const hrCategoryFilter: RetrievalFilter = {
  metadataAttributes: {
    key: 'category',
    value: 'HR'
  }
};


修正後:
typescript
const hrCategoryFilter = {
  "category": {
    key: "category",
    value: "HR"
  }
};


この修正により、フィルターオブジェクトは以下の形式になります：
• 最上位のキーは属性名（"category"）
• その値は、key と value を持つオブジェクト
  • key は属性名と同じ（"category"）
  • value は検索したい値（"HR"）

また、型アノテーション（: RetrievalFilter）を削除して、TypeScriptが型推論を行うようにしました。これにより、型エラーが解消されます。

この修正により、HRアシスタントは引き続き人事規定（category="HR"）のドキュメントのみを検索対象とし、正しく動作するようになります。
```

上記の修正で、無事コードのエラーは解消されました。しかし、実際に動作確認を行ってみると、以下の通りサーバー側でエラーが発生しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/9c6b2fc6-3a4f-4bd7-9d57-c831fb86c7df.png)

上記の情報をもとに、以下の指示をして修正してもらいます。

```bash:Amazon Q Developer への指示
画面上から実行すると、サーバーから以下のエラーが返ってきました。修正してください。
エラーが発生しました。管理者に以下のエラーを報告してください。
TypeError: Cannot read properties of undefined (reading '0')
```

```bash:実行結果サマリー

サーバーから返ってきたエラー「Cannot read properties of undefined (reading '0')」を修正するため、フィルターの形式を変更しました。

### 修正内容

フィルターオブジェクトの構造を変更しました。Amazon Bedrock Knowledge Base のフィルター形式に合わせて、metadataAttributes をトップレベルのキーとして使用するように修正し
ました。

修正前:
javascript
const hrCategoryFilter = {
  category: {
    key: 'category',
    value: 'HR',
  },
};


修正後:
javascript
const hrCategoryFilter = {
  "metadataAttributes": {
    key: "category",
    value: "HR"
  }
};


この修正により、フィルターは以下の形式になります：
• トップレベルのキーは metadataAttributes
• その値は、key と value を持つオブジェクト
  • key は属性名（"category"）
  • value は検索したい値（"HR"）

この形式は Amazon Bedrock Knowledge Base API が期待する形式に合致しており、「Cannot read properties of undefined (reading '0')」エラーが解消されるはずです。

これにより、HRアシスタントは人事規定（category="HR"）のドキュメントのみを検索対象とし、正しく動作するようになります。
```

上記の通りエラーを修正したとのことですが、実際にはエラーは解消されておらず、引き続き同様のエラーが発生し続けてしまいます。次は、より具体的に修正指示を与えてみたいと思います。

```bash:Amazon Q Developer への指示
引き続き同様のエラーが発生します。メタデータフィルタリングの形式があっていないと思われます。RagKnowledgeBasePageと同じ形式になるように修正を行ってください。
```

```bash:実行結果サマリー
RagKnowledgeBasePageと同じフィルタリング形式に修正しました。Amazon Bedrock Knowledge Base APIの正しいフィルタリング形式を使用するようにしました。

### 修正内容

rag-knowledge-base.tsファイルを確認し、正しいフィルタリング形式を特定しました。Amazon Bedrock Knowledge Base APIでは、フィルタリングにequals、notEquals、in、notInなどの
演算子を使用します。

修正前:
javascript
const hrCategoryFilter = {
  "metadataAttributes": {
    key: "category",
    value: "HR"
  }
};


修正後:
javascript
const hrCategoryFilter = {
  equals: {
    key: 'category',
    value: 'HR'
  }
};


この修正により、フィルターは以下の形式になります：
• トップレベルのキーは演算子（equals）
• その値は、key と value を持つオブジェクト
  • key は属性名（"category"）
  • value は検索したい値（"HR"）

この形式は、RagKnowledgeBasePageで使用されているフィルタリング形式と同じであり、Amazon Bedrock Knowledge Base APIが期待する形式に合致しています。これにより、「Cannot 
read properties of undefined (reading '0')」エラーが解消されるはずです。

これで、HRアシスタントは人事規定（category="HR"）のドキュメントのみを検索対象とし、正しく動作するようになります。
```

より具体的にエラー修正の指示を与えたことで、先ほどとは異なるコードの修正を実行してくれました。
実際に動作確認を行うと、無事エラーが解消されました。この流れからも分かる通り、エラー原因のあたりがついている場合は、より具体的に指示をすることが重要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/7c314617-b3c6-42a7-a600-6a898f8e8208.png)

また、人事規定以外のことを質問した際に、正しく制御できるかどうかも試してみたところ、以下の通り、修正前には検索できていたカテゴリの異なるBedrockユーザーガイドはドキュメント検索できないことが確認できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/bec1d3b4-9aae-4cf5-84f2-e9601c58c9b8.png)

最後にもう1箇所カスタマイズを行なってみます。現在は、任意のモデルIDをユーザーが選択できますが、この機能を利用する人にとって利用する基盤モデルの種類はどうでも良くて、正しい回答を得られる方が重要です。基盤モデルに対する知識がないユーザーが無意識のうちに賢くないモデルを選択して、回答精度が下がるという事態は避けたいです。そのため、今回は固定で`us.anthropic.claude-3-5-sonnet-20241022-v2:0`を利用するように修正したいと思います。

```bash:Amazon Q Developer への指示
HRアシスタントでは、基盤モデルをユーザーに選択させない様にしたいです。画面上からモデル選択のドロップダウンを削除して、固定で「us.anthropic.claude-3-5-sonnet-20241022-v2:0」を利用する様に修正してください。
```

```bash:実行結果サマリー
HRアシスタントで基盤モデルをユーザーに選択させないように修正し、固定で「us.anthropic.claude-3-5-sonnet-20241022-v2:0」を使用するように変更しました。

### 主な変更点

1. モデル選択ドロップダウンの削除
   • Select コンポーネントのインポートを削除
   • 画面上のモデル選択ドロップダウンを削除

2. 固定モデルIDの設定
   • 固定モデルID us.anthropic.claude-3-5-sonnet-20241022-v2:0 を定義
  javascript
   const fixedModelId = 'us.anthropic.claude-3-5-sonnet-20241022-v2:0';
   

3. 不要なコードの削除
   • getModelId と availableModels の参照を削除
   • モデル選択に関連するコードを削除

4. useEffect の修正
   • 初期化時に固定モデルIDを設定するように変更
   • URL パラメータからモデルIDを取得する処理を削除

5. prompter の依存関係の修正
   • modelId への依存を削除し、固定値を使用するように変更

これらの変更により、HRアシスタントは常に「us.anthropic.claude-3-5-sonnet-20241022-v2:0」モデルを使用し、ユーザーはモデルを選択できなくなりました。画面からモデル選択ドロ
ップダウンも削除されたため、UIもシンプルになりました。

これで、HRアシスタントは人事規定（category="HR"）のドキュメントのみを検索対象とし、固定のモデルを使用して一貫した応答を提供するようになりました。
```

上記のように、モデルIDを固定で設定する様に修正してくれました。

以下の通り、モデル選択のドロップダウンリストが削除されました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/94b90045-2bc6-4f8d-a266-32f5ac621a33.png)

実際に質問してみると、「us.anthropic.claude-3-5-sonnet-20241022-v2:0」で回答が生成されていることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2434634/900423a9-d3fb-4bb4-b476-806283f47f94.png)

何度かエラーが発生しましたが、無事HRアシスタントをノーコーディングで開発することができました！

## さいごに

この挑戦をするまでは、Amazon Q Developer CLIだけでGenUのカスタマイズができるのかどうか不安だったのですが、無事ノーコーディングでカスタマイズをすることができました！

生成AIの急速な進化で、生成AIツールの開発者体験は日々向上していっている様に感じます。基盤モデルやツールが優秀だったとしても、曖昧な指示の場合は自分の思い通りにコード生成ができないことが多いです。生成AIツールを利用する際は、より具体的に指示をすることが大事です。具体的な指示を出すためには、開発に対する知見が必要な場面も多くあるので、生成AIに頼りすぎず自分の開発スキルを継続的に磨いていくことも大事ですね。

また、開発中は、生成AIがどの様なコードを生成したのかを把握しておくことが大事です。トラブルシュートや生成AIにより具体的な指示を与えるために、コードを理解しておくことはとても重要です。Gitを活用することで、コードの差分を効率的に把握できたり、`git stash`で生成したコードを一時領域に退避できたりと、開発者体験を上げることができます。生成AIツールを利用する際であっても、Gitを効果的に使う様にしましょう。

この記事で、Amazon Q Developer CLIや[GenU](https://aws-samples.github.io/generative-ai-use-cases-jp/)に興味を持った方がいらっしゃったら、ぜひ使ってみてください！