📺

Amazon Bedrock Knowledge BasesとRAGASでRAGの評価をやってみた

に公開

はじめに

Fusicのレオナです。今回はAmazon Bedrock Knowledge BasesとRAGASでRAGの評価をしてみたいと思います。

Amazon Bedrock Knowledge Basesとは

Amazon Bedrock Knowledge Bases とは、Amazon Bedrockの機能のひとつであり、フルマネージドなベクトル検索サービスです。Amazon Bedrockで提供しているLLMと自社データソースからRAG (Retrieval Augmented Generation)を簡単に構築できる機能を提供しています。

RAGASとは

RAGASは、LLMを利用したアプリケーションの評価を簡単に行うためのライブラリです。その中でRAGの性能を様々な評価指標で定量的に評価する機能も提供されています。

  • Context Precision:
    検索結果上位k件に含まれる、質問に役立つ情報の割合を示します。上位に有用情報が多いほどスコアが1に近づき、無関係な情報が混ざるほどスコアが低下します。

  • Context Recall:
    回答に必要な全ての関連情報(ground-truthでマークされた根拠)が検索結果にどれだけ含まれているかを評価します。必要な情報が欠けずに含まれていればスコアが1に近づき、抜け漏れがあればスコアが低下します。

  • Context Entities Recall:
    回答で使われる固有名詞や数値などのエンティティが検索結果にどれだけ含まれているかを測定します。重要エンティティがすべて含まれていればスコアが1に近づき、抜け漏れがあればスコアが低下します。

  • Noise Sensitivity:
    検索結果に無関係な情報に引きずられて誤答をどれだけ生成するかを測定します。スコアが0に近いほどノイズ耐性が高く、1に近いほど影響を受けやすいことを示します。(0に近い方がパフォーマンスが良い)

  • Answer Relevancy:
    生成された回答がユーザーの質問にどれだけ沿っているかを評価します。スコアが1に近づくほど関連性が高く、抜け漏れがあればスコアが低下します。

  • Faithfulness:
    生成回答が検索結果の根拠と矛盾なく事実に忠実かを評価します。スコアが1に近づくほど全ての主張に根拠があり、根拠にない情報や誤情報を含むとスコアが低下します。

使用するデータセット

Hugging FaceでMITライセンスの公開されているallganize/RAG-Evaluation-Dataset-JAにある日本語ドキュメントと質問データと想定回答を使います。

モデルの有効化

もしモデルの有効化ができていない場合は以下の手順でモデルの有効化を行って下さい。

  • マネジメントコンソールから、Amazon Bedrock を開く -> 左ナビゲーションから`モデルアクセスをクリック
  • モデルアクセスを変更ボタンをクリック
  • 使用したいLLMを選択して次へボタンをクリック後、画面が変わるので送信ボタンをクリック
  • 今回はTitan Text Embeddings V2Claude 3.5 Sonnetを使用します

マネジメントコンソールでAmazon Bedrock Knowledge Basesを作る

  • 今回はS3をデータソースとするので、取得したPDFをバケットに格納して下さい

    • kb-docs-devとしてバケットを作成しました
  • マネジメントコンソールから、Amazon Bedrock を開く -> 左ナビゲーションからナレッジベースを選択

  • 作成ボタンをクリック、ベクトルストアを含むナレッジベースを選択

  • Query EngineがAmazon S3が選択された状態で次

  • データソースを選択画面になったらS3 sourceのセクションでBrowse S3ボタンをクリック

  • 作成したS3バケットを選択 (自分の場合はkb-docs-devを選択しています。)

  • 選択したら次へ

  • Configure data storage and processingの画面でモデルを選択をクリック

  • モデルはTitan Text Embeddings V2を選択して適用ボタンをクリック

  • 選択し適用ボタンをクリック、次へ

  • ナレッジベースを作成画面になるのでナレッジベースを作成ボタンをクリック (作成に時間がかかります)

  • 作成が終わったら画像の通りになります

  • データソースのセクションで同期ボタンをクリック

  • ステータスが利用可能になるまで待つ

検索と回答生成と評価の実装

今回はAnswer Relevancyを用いて評価を行います。

pip install boto3 langchain langchain-core langchain-aws ragas
import boto3
import json
import time
from ragas.llms import LangchainLLMWrapper
from ragas.embeddings import LangchainEmbeddingsWrapper
from ragas.metrics import (
   answer_relevancy
)
from ragas.dataset_schema import EvaluationDataset
from ragas import evaluate
from datasets import Dataset
from langchain_community.chat_models import BedrockChat
from langchain_community.embeddings import BedrockEmbeddings

# 初期設定
region = "ap-northeast-1"
bedrock_agent = boto3.client('bedrock-agent-runtime', region_name=region)
bedrock_runtime = boto3.client('bedrock-runtime', region_name=region)
llm_model_id = "anthropic.claude-3-5-sonnet-20240620-v1:0"
embed_model_id = "amazon.titan-embed-text-v2:0"
kb_id = "UTVJFIIDQC" # 作成されたナレッジベースID

def retrieve_and_generate(
    query,
    knowledge_base_id=kb_id,
    llm_model_id=llm_model_id,
    num_results=5
):
    model_arn = f"arn:aws:bedrock:ap-northeast-1::foundation-model/{llm_model_id}"
    response = bedrock_agent.retrieve_and_generate(
        input={"text": query},
        retrieveAndGenerateConfiguration={
            "knowledgeBaseConfiguration": {
                "knowledgeBaseId": knowledge_base_id,
                "modelArn": model_arn,
                "retrievalConfiguration": {
                    "vectorSearchConfiguration": {"numberOfResults": num_results}
                },
            },
            "type": "KNOWLEDGE_BASE",
        },
    )
    return response['output']['text']


def run_rag_evaluation(
    queries,
    references,
    knowledge_base_id=kb_id,
    llm_model_id=llm_model_id,
):
    results = []
    for query, ref in zip(queries, references):
        generated = retrieve_and_generate(query, knowledge_base_id, llm_model_id)
        results.append({
            'user_input': query,
            'response': generated,
            'reference': ref
        })

    # 評価用データセットの作成
    dataset = Dataset.from_dict({
        "user_input": [r['user_input'] for r in results],
        "response": [r['response'] for r in results],
        "reference": [r['reference'] for r in results]
    })
    eval_data = EvaluationDataset.from_list(dataset.to_list())

    llm = BedrockChat(
        model_id=llm_model_id,
        client=bedrock_runtime,
        region_name=region
    )
    embeddings = BedrockEmbeddings(
        model_id=embed_model_id,
        client=bedrock_runtime,
        region_name=region
    )

    # RAGASで使うメトリクス
    metrics = [
        answer_relevancy,
    ]

    result = evaluate(
        eval_data,
        metrics,
        llm=LangchainLLMWrapper(llm),
        embeddings=LangchainEmbeddingsWrapper(embeddings)
    )
    return result


if __name__ == "__main__":
    evaluation_queries = [
        "火災保険の収益悪化の要因は?",
        "東京海上の気候変動に対する取り組みを教えてください",
        "保険会社のDXについて教えてください"
    ]
    evaluation_references = [
        "火災保険の収益悪化には長期契約による保険料の固定化、自然災害の増加による支払いの増加、再保険料の上昇などが要因として挙げられます。",
        "東京海上は気候変動対策として、温室効果ガス排出量の削減目標を設定し、再生可能エネルギー保険の提供、気候関連財務情報開示タスクフォース(TCFD)の提言に基づく情報開示、社内のカーボンニュートラル化を推進しています。",
        "保険会社のDXには、顧客向けのデジタルインターフェース改善、AIによる査定の自動化、ビッグデータ活用によるリスク評価の精緻化、ブロックチェーンを活用した契約管理などがあります。"
    ]

    eval_result = run_rag_evaluation(evaluation_queries, evaluation_references)

結果

eval_result.scores
[{'answer_relevancy': np.float64(0.8834135757111398)},
 {'answer_relevancy': np.float64(0.0)},
 {'answer_relevancy': np.float64(0.43012294566844894)}]

まとめ

Amazon Bedrock KnowledgeBasesとRAGASを組み合わせて、RAGの評価を定量的に測定できるようになりました。RAGASによって忠実度や関連性などの評価指標を数値化し、パイプラインに組み込めるため、RAGアプリケーションを継続的にモニタリングできるようになると思います。

Fusic 技術ブログ

Discussion