RAGアプリケーションの品質評価戦略


# RAGの品質評価の戦略

LLMアプリケーションを開発する際には、まずエンド・ツー・エンドの評価ワークフローを定義することが役立ちます。そして、失敗例やコーナーケースを収集し始め、何がうまくいっているのか、何はうまくいっていないの洞察を得たら、特定のコンポーネントの評価と改善に深入りすることができます。

- エンド・ツー・エンド(E2E)の評価(=統合テスト)
- コンポーネント別評価(=単体テスト)

ソフトウェアテストで例えるなら、統合テストと単体テストです。
個々のコンポーネント単位でユニットテストを書くべきですし、同様に、ユーザへの応答がうまくいっているかどうかを把握するのは、統合テストです。どちらも同じくらい重要です。


## E2Eの評価とコンポーネント別評価、どちらからはじめるべきか

もし、自分のシステムが現在どんな状態にあるのかを全体把握したいのであれば、E2Eの評価を中心としたコア機能の確認から始めましょう。RAG構成であれば、検索+合成のバッチ評価から始めることになるでしょうか。

もし、各コンポーネント単位で改善点の仮説が既にあるのであれば、コンポーネントごとの評価を行います。しかし、これは時期尚早の最適化、つまり全体的なアプリケーションのニーズを評価することなく、個別最適を行うというリスクを負うことになるかもしれません。

計測は何よりも優先的に大切です。もし計測ができていないのでれば、改善よりも前に計測を始めましょう。

# RAGの品質評価の評価単位

新規にRAGを構築する場合は、構成モジュールを段階的に結合してテストを進めます。

``` mermaid

graph TD
    subgraph LR5 [P1.本番モニタリング]
        log1[logs] -->I
        I[ダッシュボード] --> I1[システムパフォーマンス監視]
        I --> I2[ユーザーインタラクション分析]
        I --> I3[エラーログ分析]
        I --> I4[セキュリティ監視]
    end

    subgraph LR3 [T4. 統合テスト]
        subgraph LR2 [T3. 検索 + 生成モジュールのテスト]
            subgraph LR1 [T2. 情報検索モジュールのテスト]
              subgraph LR0 [T1. インデックス処理のテスト]
                A1[情報源データ] --> A2[前処理プロセス]
                A2 --> A3[チャンク分割プロセス]
                A3 --> A4[インデックスプロセス]
                A4 --> A5[ベクトルDB]
                end 
                A5 --> A[評価用クエリデータ]
            end

            A --> B[情報検索モジュール]
            B --> C[関連情報の取得]
            C --> D[生成モジュール]
            D --> E[応答の生成]
        end

        F[フロントエンド  UI] --> G
        G[バックエンドシステム] --> A
        E --> DB[ChatDB]
        DB --> G
    end

    G --> log1
    DB --> I


```

### T1. インデックス処理のテスト
- インデックスされる情報源データが完全かつ正確に処理されることを確認
- インデックス構築プロセスの速度と効率を評価
- 大規模なデータセットに対する検索クエリのパフォーマンスを評価
- データ量の増加に伴うインデックス処理のスケーラビリティを検証
- インデックスに新たなデータが追加または削除された場合の処理をテスト
- インデックス構築中にエラーが発生した場合のシステムの挙動を検証
- エラー発生時のロギングやアラート機能が適切に機能するかを確認

### T2. 検索モジュールのテスト
- 検索クエリの処理能力をテスト
- 関連情報を効率的かつ正確に取得できるかを検証
- 検索結果の関連性と精度を評価

### T3. 検索+生成モジュールのテスト
- 取得した情報を基に、適切な応答が生成されるかをテスト
- 生成されたテキストの自然さ、一貫性、関連性を評価
- 異なるクエリに対する応答の多様性と適切性を検証

### T4. 統合テスト
- バックエンド、データベースインタラクションのテスト
- エンドツーエンドでの性能評価
- ユーザークエリから応答までの処理時間を測定
- UI/UXのフィードバック
- システムのスケーラビリティと安定性をテスト


### P1. 本番モニタリング
- システムのレスポンスタイムと処理速度を常時監視
- ピーク時の負荷状態でもシステムが応答性を保持しているかを評価
- CPU、メモリ、ディスクI/O、ネットワーク帯域などのリソース利用率を監視
- システムエラー、例外、ログイン失敗などのエラーログを監視
- トランザクションの成功率やビジネスに重要な指標をリアルタイムで監視
- 不正アクセス試行、脆弱性の悪用、データ漏洩などのセキュリティ関連イベントを監視
- エンドユーザーの操作に関するパフォーマンスと体験を監視
- ページの読み込み時間やインタラクションの遅延など、ユーザー体験に影響する問題を特定




## 品質評価の方法

NLPの分野が進化するにつれ、評価方法も進化してきました。

強力な基盤モデル(GPT)が人間のアノテーターよりも優れたアノテーションタスクを実行するようになっており、評価に関するベストプラクティスは常に変化しています。BLEUやF1のような以前の評価方法は、人間の判断との相関性が低いことが示されており、慎重に適用する必要があります。

自由形式のタスクや、判断や意見を必要とするものは、主観的な性質のため、事実に基づいた質問よりも自動評価が難しいです。特定のシナリオにおいてどの方法が適切かについて、より多くのガイドとケーススタディを提供することを目指してデータセットづくりが必要になります。

### 標準指標
注釈付きの評価用データセットに対しては、いくつかの標準的な測定基準があります。

- **Exact Match (EM)**：正確に回答されたクエリの割合。
- **回収率**：返された答えの数に関係なく、正しく答えられたクエリの割合。
- **精度**：正しく回答されたクエリの割合を、返された回答数で割ったもの。
- **F1**:F1スコアは精度と想起の調和平均である。したがって、偽陽性と偽陰性の両方を考慮し、1つの指標で精度と想起の両方を対称的に表す。



# エンド・ツー・エンド評価

## 評価データセット
最初は小さいけれども多様なクエリのセットから始め、問題のあるクエリやインタラクションを発見するにつれて、より多くの例を積み上げていくことが有用です。

**参考記事**

https://github.com/microsoft/promptflow-resource-hub/blob/main/sample_gallery/golden_dataset/copilot-golden-dataset-creation-guidance.md

## 評価指標

定量的評価と定性的評価を適切に使い分けることは、アプリケーションやサービスの性能を適切に把握し、改善するために重要です。

### 定量的評価
定量的評価は、数値で測定可能な結果を提供し、特定の基準や目標に対するパフォーマンスを正確に評価できます。アプリケーションの正確性、効率、パフォーマンスなどがこのカテゴリに入ります。

- **メトリクスの使用**: 特定の数値指標（レスポンスタイム、スループット、エラー率など）を利用して、システムのパフォーマンスを測定します。
- **ツールの選択と入力の検証**: 入力データとアウトプット結果が予定通りかどうかを数値で評価します。例えば、特定の計算が期待した通りの結果を返しているか、特定のスキーマに沿ったJSONフィールドが正しく生成されているかなどです。


https://qiita.com/ymgc3/items/89993d4479f3080bb853

### 定性的評価
定性的評価は、数値では測定しづらい側面を評価するために使用され、主観的な意見や感想を取り入れることが多いです。特に、長文の回答生成やクリエイティブなコンテンツの評価に有効です。

- **長文回答の生成**: GPT-4などの高価なモデルでは、正確さだけでなく、生成されたテキストの自然さや文脈への適合度、読者に与える影響など、定性的な側面が重要になります。
- **人間による評価**: 生成された応答がユーザーにどのように受け入れられるか、または特定の意図をどの程度伝えられているかなど、人間の評価者によるフィードバックを取り入れることが重要です。

## 評価の手法

### 感度テスト

複雑なパイプラインで結果に影響を与える部分を特定するためには、感度テストや他の分析手法が有効です。これらの手法は、システム内の個別のコンポーネントやデータセットの特定の部分が結果にどのように影響を及ぼしているかを理解するのに役立ちます。

**感度テストの利点**
- **コンポーネントの影響分析**: パイプラインの各コンポーネントが出力に与える影響を個別に評価することで、最も影響力のある部分を特定できます。
- **データセットの問題点の特定**: 特定のクエリやデータポイントが予期せぬ結果を引き起こしている場合、それらを特定し、修正することができます。
- **パフォーマンスの最適化**: 最も影響力のあるコンポーネントを調整することで、全体的なパフォーマンスを向上させることが可能です。

### メトリクス・アンサンブル (metrics-ensembling)

開発セットが大きくなると、GPT-4を使って評価を行うのはコストが高くつきます。

メトリクス・アンサンブルは、弱いシグナル（完全一致、F1、ROUGE、BLEU、BERT-NLI、BERT-similarity）のアンサンブルを使用して、ゴールド・ラベル（ヒューマン・ラベル/GPT-4）に近い、より高価な評価手法の出力を予測します。

**目的**
- 開発段階において、大規模なデータセットの変更を安価かつ迅速に評価
- 生産モニタリング段階で、さらなる評価（GPT-4 / 人による警告）のために異常値にフラグを立てる

また、メトリクスのアンサンブルは解釈可能であることを望みます。
相関スコアと重み付けスコアは、どのメトリクスが評価基準を最もよく捉えているかを示すものでなければなりません。

バッチで複数評価を実行します。

https://docs.llamaindex.ai/en/stable/examples/evaluation/batch_eval.html


# コンポーネント別評価
パイプラインをより詳細に評価するには、個々のコンポーネントの評価に分解することが有効です。

例えば、ある失敗ケースは、正しい文書を検索できなかったことと、LLMが文脈を誤解して誤った結果を幻視したことが組み合わさっていることが原因かもしれません。これらの問題を個別に切り分けて対処することができれば、複雑さを軽減し、より満足のいく全体的な結果へと段階的に導くことができます。

## 検索の評価

### BEIRデータセット
BEIR（Benchmarking IR）は、様々な検索タスクに対する情報検索システムの性能を測定するためのベンチマークであり、特にゼロショットのシナリオにおいてモデルがどの程度一般化できるかを評価するのに役立ちます。以下に、BEIRを使用する際の重要なポイントをまとめました。

### BEIRを使用する際の重要なポイント

1. **ファインチューニング後のパフォーマンス評価**:
モデルを特定のデータセット上でファインチューニングした後、BEIRを使用してそのモデルが他のドメインにどの程度適応できるかを評価することができます。これは、モデルが特定のタスクに過度に適合しているか、または一般化能力が保たれているかを把握するのに有効です。

2. **ゼロショット設定での評価**:
BEIRは、訓練されていないドメインに対してモデルがどの程度効果的に機能するかを評価することを目的としています。これは、実際のアプリケーションにおいて非常に重要で、予期せぬデータやドメインに対しても堅牢なモデルが求められるためです。

3. **データドリフトへの対応力の評価**:
データの分布が時間とともに変化する（データドリフト）場合、その影響を評価することが重要です。BEIRを使用して、モデルがトレーニング分布と異なる新しいドキュメントにどの程度うまく適応するかを評価することで、実際の運用環境における検索精度の変化を予測できます。

## クエリエンジンのコンポーネントの評価

クエリエンジンや検索パイプラインの特定のコンポーネントを評価することは、そのシステム全体の性能を理解し、改善点を特定するのに役立ちます。特に、サブクエスチョン生成やフォローアップクエスチョン生成のような高度な機能を評価することは、検索システムが複雑な情報ニーズにどれだけ効果的に応えることができるかを理解するために重要です。

### コンポーネントの評価における重要なポイント

1. **評価指標の選定**:
性能を測定するためには、適切な評価指標を選ぶ必要があります。精度、リコール、F1スコアなどの従来の指標から、応答時間、ユーザ満足度などの実用的な指標まで、評価の目的に応じて指標を選択します。

2. **ベースラインとの比較**:
評価の有効性を確保するためには、他の標準的なシステムやモデルとの比較、改善前の指標との比較が必要です。これにより、評価対象のシステムがどの程度進んでいるか、あるいは遅れているかを客観的に判断できます。

3. **ユースケースに基づく評価**:
特定のユースケースやシナリオにおけるシステムのパフォーマンスを評価することで、その実用性をより具体的に理解できます。特に、サブクエスチョンやフォローアップクエスチョンの生成能力を評価する際には、実際の情報ニーズを模倣したシナリオを用いることが重要です。

4. **詳細な分析**:
単に性能指標を報告するだけでなく、どのコンポーネントが性能に影響を与えているのか、またその理由は何かを詳細に分析することが重要です。これにより、システムのどの部分を改善すべきかを特定し、より効果的な改善策を立案できます。

5. **ロバストネスとスケーラビリティの評価**:
システムのロバストネス（堅牢性）とスケーラビリティを評価することも重要です。特に、異なる種類のクエリや大量のクエリに対して、システムが一貫して高い性能を維持できるかを評価することは、実用的な運用において非常に重要です。


パイプラインの個別分析には、WandbのTracesが便利です。

https://docs.wandb.ai/ja/guides/prompts


# 参考資料

https://docs.llamaindex.ai/en/stable/optimizing/evaluation/evaluation.html