Amazon Bedrockを使って、RAGを構築　 - ドメイン知識のインプット補助ツールを作りたい -

:::note info
この記事は[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico) カレンダー1 の 18日目の記事です
:::

# はじめに

最近は、生成AIのカバー範囲が以前より広くなったと思います
児童福祉に関して、質問した場合も、良い回答が返ってくるようになりました


<details><summary>例）実際に生成AIに児童福祉に関して質問してみた<br />Q: 児童指導員等配置加算と専門的支援加算の違いは？</summary>

A: 児童指導員等配置加算と専門的支援加算は、どちらも放課後等デイサービスや児童発達支援などの
児童福祉サービスに関連する加算ですが、目的や要件、加算額などが異なります。それぞれの加算の違いについて説明します。

1. 児童指導員等配置加算
    - 目的： 児童指導員等配置加算は、施設における専門的な支援が提供できる人材を確保し、適切な支援を行うための加算です。特に、児童指導員の配置を強化することを目的としています。

    - 要件：
        - 児童指導員、保育士、社会福祉士、精神保健福祉士、作業療法士、理学療法士、言語聴覚士などの専門職を一定数以上配置していることが求められます。
        - 配置されている職員が、所定の資格を有していることが前提です。
        - 定員に応じた配置基準が設定されており、施設の規模に応じた人数が必要です。

2. 専門的支援加算
    - 目的：
        - 専門的支援加算は、支援が特に難しいケースに対して、専門的な支援を行うことを目的とした加算です。これは、障害の重い子どもや特別な支援が必要な場合に、専門的な知識や技術を有するスタッフが支援を行うことを評価するための加算です

    - 要件：
        - 支援が特に難しいとされる事例（例えば、重度の障害を持つ子どもや、行動面で特別な支援が必要な子ども）に対して、専門的な支援が行われていることが求められます。
        - 支援内容に応じて、作業療法士、言語聴覚士、心理士など、より高度な専門的知識を持つ職員が関与していることが求められる場合があります。
        - 具体的な支援内容や、どのような専門職が関与しているかに応じて、加算額が決定される場合があります。
</details>


ただ、ドメイン知識を要する質問の場合、内容が正しいかどうかの確認に時間がかかること、回答が一見すると正しそうなので見落として間違えて理解してしまうリスクがあると感じておりました。特に、生成AIの性質上、3年に一度の法改正で変更された内容が回答に正しく反映されているかどうかは、確認も大変で、不安が残る状態でした

そこで、RAGを活用することで、上記課題が解決するか試しました

# RAGとファインチューニングの違い

RAGと同じように、生成AIの回答精度を向上させる仕組みとして、ファインチューニングがあります
RAGとファインチューニングでは同じ回答精度を向上させるでも、アプローチに大きな違いがあり、どういった方向で回答精度を向上させたいによって向き不向きがあります


<details><summary>参考）生成AIに違いを聞いてみた<br/>Q: RAGとファインチューニングの違いは何ですか？</summary>

A: RAG（Retriever-augmented Generation）とファインチューニングは、どちらも機械学習や自然言語処理（NLP）における技術ですが、その目的やアプローチは異なります。それぞれの違いについて詳しく説明します。

1. RAG（Retriever-augmented Generation）
    - RAGは、生成モデルと情報検索（Retriever）を組み合わせたアーキテクチャです。具体的には、与えられたクエリに対して外部の知識ベースやデータベースから関連する情報を検索し、その情報を元に応答を生成する仕組みです。
    - 特徴：
        - 検索と生成の融合：RAGは「検索（Retriever）」と「生成（Generator）」を組み合わせたモデルです。まず、検索エンジンのように関連する情報を外部の知識ベースから引っ張ってきて、その情報を元にテキストを生成します。
        - 外部データの活用：通常、生成モデルは訓練データに基づいて応答を生成しますが、RAGでは外部のドキュメントやデータベースを動的に検索し、取得した情報を基に生成を行います。これにより、モデルが持つ知識の範囲を超えた、より正確で最新の情報を使用できるようになります。
        - 双方向のプロセス：RAGは、情報検索（Retriever）とテキスト生成（Generator）の2つの段階を含んでおり、これらが互いに連携して動作します。

2. ファインチューニング
    - ファインチューニング（Fine-tuning）は、事前学習された大規模なモデルを特定のタスクに合わせて微調整する手法です。モデルは一般的な知識を持っていますが、ファインチューニングを通じて、特定のドメインやタスクに特化したパフォーマンスを向上させます。

    - 特徴：
        - 事前学習からの調整：ファインチューニングは、事前に大規模なコーパス（例えば、インターネットから収集したテキスト）で訓練されたモデルに、特定のデータセットを使って追加の訓練を行うプロセスです。これにより、モデルは特定のタスク（例えば、感情分析、翻訳、質問応答など）に特化します。
        - データセットに特化：ファインチューニングの際には、特定のデータセット（例えば、特定の業界や分野のデータ）を使い、そのデータに関連する知識をモデルに加えます。
        - 通常は生成モデルの微調整：生成系のタスクでは、例えばGPTのようなモデルをファインチューニングして、特定の質問に対して正確な応答を返せるように調整します。
</details>

ファインチューニングは、Q&Aのデータセットを用意し、モデル自体を追加訓練します。用意したQ&Aは理想とする受け答えとして、自分たちの求める回答が返ってきやすいモデルになり、回答精度が向上する形です

それに対して、RAGは、モデル自体はチューニングせず、外部の知識ベースを生成し、その情報を元に回答が生成されます

今回の課題解決におけるRAGの一番のメリットは、最新情報の反映が容易であることです
前述の通り、ファインチューニングは、Q&Aデータセットを用意しモデルも追加訓練しますので、ほしい回答を返してくれるようになるまで、時間が必要です

法改正のタイミングでは、情報が逐次アップデートされていきますので、とても、データセットの用意、モデルの追加訓練を行う余裕はありません

その点、RAGの場合は、知識ベースを更新できれば良いので、ファインチューニングより新しい情報に対応しやすくなります

RAGのデメリットとして、知識ベースと生成AIを連携する部分の構築が複雑であるという点があるのですが、Amazon Bedrockを活用すると、容易に構築することができます

# Amazon Bedrockの構築手順

[公式のチュートリアル](https://catalog.us-east-1.prod.workshops.aws/workshops/a4bdb007-5600-4368-81c5-ff5b4154f518/en-US)は、情報量が多い分、敷居が高く感じます

もちろん、ガッツリと、Amazon Bedrockを使っていきたいという方にはじっくり読んでいただきたいのですが、簡単に試す分には以下の手順で構築いただければと思います

1. アカウントの設定（使い始める際に）
    1. [AWSアカウント作成](https://aws.amazon.com/jp/)
    1. IAMユーザーとロールの設定
        - AmazonBedrockFullAccess
            - Bedrockの利用に必要な権限
        - AmazonS3FullAccess
            - Bedrockで知識ベースに使う元データを格納するためにS3ストレージを利用）
1. Bedrockのモデルの設定
    - 複数のモデルから選べる、今回は、Claude 2を使用しました
    - また、リージョンによって、使えるモデルが増減しますので、必要に応じてリージョンを変更してください
1. 知識ベースの作成
    1. S3に知識ベースの元となる情報を格納
    1. Bedrockのコンソールメニューから、ナレッジベースを選択し、新規作成ボタンを押下
    1. ナレッジベース名と、サービスロールを設定
    1. 先ほど格納したS3をデータソースで選択
    1. 埋め込みモデルとベクトルストアを設定
        - ベクトルストアは、推奨される新しいベクトルストアをクイック作成でOK
1. 知識ベースのテスト
    - この時点で対話形式の確認ができるので、質問したいことを投げ込んで確認するだけでOK
1. エージェントを作成

RAGを試すだけなら、ノーコードでいけます！
作成したエージェントを自分のシステムに組み込みたい場合は、[Bedrock API](https://docs.aws.amazon.com/bedrock/latest/APIReference/welcome.html)を活用すると便利です

# RAGの精度向上

前述の手順で、簡単に構築したRAGでもかなり良い結果を返してくれます
ただ、ここから、より良い回答精度を求める上では、いくつか注意が必要です

当たり前に聞こえるかもしれませんが、BedrockでRAGを構築する場合は、特に注意が必要です
何故ならば、前述の手順で見ていただいた通り、S3に格納したデータがそのまま知識ベース構築に使われるからです

ここで注意が必要なのは、どこから情報を取得するかだけではなく、取得した情報に、余計なデータが含まれていないかです

今回の場合だと、文章データを格納したわけですが、情報ソースの多い方が良いと考えて、複数の情報ソースから取得した場合、同じ内容でも書き味や表現が違うことってありますよね

また、直接、回答制度に関係ない文章などもそのままでは含まれ、ノイズとなり、検索性能の低下や精度の低下につながります。可能な限り元の情報ソースから必要部分を抜き出し、複数の情報ソースで内容が同じになっているか確認しましょう

上記のように、知識ベースの元となる情報ソースに前処理をしてあげることで、RAGの精度向上が可能です

## 前処理のコストと最新情報反映のバランスに関して

精度向上のためには、前述の通り、前処理が重要なのですが、この前処理を手作業で行うと、せっかくのRAGのメリットである最新情報の反映までのリードタイムがのびてしまいますよね

ここは非常に悩ましい問題です
ただ、前述の通り、Bedrockでは、知識ベースの作成が容易ですので、少ないコストで前処理を始めてみて、コストとリターンのバランスを図っていくのが良いと思います

また、前処理自体にも、生成AIの活用が可能です

- 2つの文章の比較
- 文章の要約、重要な内容の切り出し

完全に自動化するのは怖い部分がありますが、前処理自体も生成AIを活用して、それをベースに確認、修正をするとコスト的にはかなり良かったです

# 終わりに

今回の記事を書くにあたって、記事の折りたたみ部分では、実際に作成したRAGを含むエージェントに質問し、回答してもらいました

かなり簡単に試せるようになっておりますので、ご自身の興味のある内容でRAGを構築してみると面白いのではないでしょうか