次の方法で共有


Azure AI Evaluation SDK (プレビュー) (クラシック) を使用して、生成 AI アプリケーションをローカルで評価する

このドキュメントでは、 Microsoft Foundry (クラシック) ポータルを参照します。

🔍 新しいポータルの詳細については、Microsoft Foundry (新しい) ドキュメント を参照してください。

Important

この記事で "(プレビュー)" と付記されている項目は、現在、パブリック プレビュー段階です。 このプレビューはサービス レベル アグリーメントなしで提供されており、運用環境ではお勧めしません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳細については、「 Microsoft Azure プレビューの追加使用条件」を参照してください。

大量のデータセットに適用することで、生成型 AI アプリケーションのパフォーマンスを十分に評価できます。 Azure AI Evaluation SDK を使用して、開発環境でアプリケーションを評価します。

テスト データセットまたはターゲットを指定すると、生成 AI アプリケーションの出力は、数学的ベースのメトリックと AI 支援品質および安全性エバリュエーターの両方で定量的に測定されます。 組み込みまたはカスタムのエバリュエーターを使用すると、アプリケーションの機能と制限に関する包括的な分析情報を得ることができます。

この記事では、1 行のデータに対してエバリュエーターを実行し、アプリケーション ターゲットで大規模なテスト データセットを実行する方法について説明します。 Azure AI Evaluation SDK をローカルで使用する組み込みのエバリュエーターを使用します。 次に、Foundry プロジェクトの結果と評価ログを追跡する方法について説明します。

概要

まず、Azure AI Evaluation SDK からエバリュエーター パッケージをインストールします。

pip install azure-ai-evaluation

組み込みエバリュエーター

組み込みの品質と安全性のメトリックは、クエリと応答のペアと、特定のエバリュエーターの追加情報を受け入れます。

カテゴリ エバリュエータ
汎用 CoherenceEvaluatorFluencyEvaluatorQAEvaluator
テキストの類似性 SimilarityEvaluatorF1ScoreEvaluatorBleuScoreEvaluatorGleuScoreEvaluatorRougeScoreEvaluatorMeteorScoreEvaluator
検索拡張生成 (RAG) RetrievalEvaluatorDocumentRetrievalEvaluatorGroundednessEvaluatorGroundednessProEvaluatorRelevanceEvaluatorResponseCompletenessEvaluator
リスクと安全性 ViolenceEvaluatorSexualEvaluatorSelfHarmEvaluatorHateUnfairnessEvaluatorIndirectAttackEvaluatorProtectedMaterialEvaluatorUngroundedAttributesEvaluatorCodeVulnerabilityEvaluatorContentSafetyEvaluator
Agentic IntentResolutionEvaluatorToolCallAccuracyEvaluatorTaskAdherenceEvaluator
Azure OpenAI AzureOpenAILabelGraderAzureOpenAIStringCheckGraderAzureOpenAITextSimilarityGraderAzureOpenAIGrader

組み込みのエバリュエータのデータ要件

組み込みのエバリュエーターは、クエリと応答のペア、JSON Lines (JSONL) 形式の会話の一覧、またはその両方を受け入れます。

エバリュエータ テキストの会話と単一ターンのサポート テキストおよび画像に対する会話とシングルターンのサポート テキストのみの一回限りのサポート 要求 ground_truth エージェント入力をサポート
品質評価者
IntentResolutionEvaluator
ToolCallAccuracyEvaluator
TaskAdherenceEvaluator
GroundednessEvaluator
GroundednessProEvaluator
RetrievalEvaluator
DocumentRetrievalEvaluator
RelevanceEvaluator
CoherenceEvaluator
FluencyEvaluator
ResponseCompletenessEvaluator
QAEvaluator
自然言語処理 (NLP) エバリュエーター
SimilarityEvaluator
F1ScoreEvaluator
RougeScoreEvaluator
GleuScoreEvaluator
BleuScoreEvaluator
MeteorScoreEvaluator
安全エバリュエーター
ViolenceEvaluator
SexualEvaluator
SelfHarmEvaluator
HateUnfairnessEvaluator
ProtectedMaterialEvaluator
ContentSafetyEvaluator
UngroundedAttributesEvaluator
CodeVulnerabilityEvaluator
IndirectAttackEvaluator
Azure OpenAI Graders
AzureOpenAILabelGrader
AzureOpenAIStringCheckGrader
AzureOpenAITextSimilarityGrader
AzureOpenAIGrader

SimilarityEvaluatorを除く AI 支援品質エバリュエーターには、理由フィールドが含まれます。 彼らは、考え方の連鎖推論などの手法を使用して、スコアの説明を生成します。

評価品質が向上した結果、生成時により多くのトークン使用量が消費されます。 具体的には、エバリュエーター生成の max_token は、ほとんどの AI 支援エバリュエーターで 800 に設定されます。 RetrievalEvaluatorの場合は値 1600、長い入力に対応するToolCallAccuracyEvaluatorの場合は 3000 です。

Azure OpenAI の採点者には、入力列が、採点者が使用する 実際 の入力にどのように変換されるかを説明するテンプレートが必要です。 たとえば、 クエリ応答と呼ばれる 2 つの入力と、 {{item.query}}形式のテンプレートがある場合は、クエリのみが使用されます。 同様に、会話入力を受け入れる {{item.conversation}} のようなものを持つことができますが、システムが処理する機能は、その入力を期待するように他のグレーダーを構成する方法によって異なります。

エージェント エバリュエーターのデータ要件の詳細については、「 AI エージェントの評価」を参照してください

テキストの1回限りのサポート

すべての組み込みエバリュエーターは、単一ターン入力を文字列内のクエリと応答のペアとして受け取ります。 例えば次が挙げられます。

from azure.ai.evaluation import RelevanceEvaluator

query = "What is the capital of life?"
response = "Paris."

# Initialize an evaluator:
relevance_eval = RelevanceEvaluator(model_config)
relevance_eval(query=query, response=response)

ローカル評価を使用してバッチ 評価 を実行するか、 データセットをアップロードしてクラウド評価を実行するには、JSONL 形式でデータセットを表します。 前の単一ターン データ (クエリと応答のペア) は、次の例のようなデータセットの行に相当し、次の 3 行を示しています。

{"query":"What is the capital/major city of France?","response":"Paris."}
{"query":"What atoms compose water?","response":"Hydrogen and oxygen."}
{"query":"What color is my shirt?","response":"Blue."}

評価テスト データセットには、各組み込みエバリュエーターの要件に応じて、次の要素を含めることができます。

  • クエリ: 生成 AI アプリケーションに送信されるクエリ。
  • 応答: 生成 AI アプリケーションによって生成されたクエリへの応答。
  • コンテキスト: 生成された応答の基になるソース。 つまり、基礎となるドキュメントです。
  • 地上の真実: ユーザーまたは人間が真の答えとして生成した応答。

各エバリュエーターに必要なものを確認するには、「 組み込みのエバリュエーター」を参照してください。

テキストの会話サポート

テキストの会話をサポートするエバリュエーターの場合は、入力として conversation を指定できます。 この入力には、messagescontent、必要に応じてroleを含む、contextの一覧を含む Python ディクショナリが含まれます。

Python での次の 2 ターン会話を参照してください。

conversation = {
        "messages": [
        {
            "content": "Which tent is the most waterproof?", 
            "role": "user"
        },
        {
            "content": "The Alpine Explorer Tent is the most waterproof",
            "role": "assistant", 
            "context": "From the our product list the alpine explorer tent is the most waterproof. The Adventure Dining Table has higher weight."
        },
        {
            "content": "How much does it cost?",
            "role": "user"
        },
        {
            "content": "The Alpine Explorer Tent is $120.",
            "role": "assistant",
            "context": None
        }
        ]
}

ローカル評価を使用してバッチ 評価 を実行するか、 データセットをアップロードしてクラウド評価を実行するには、データセットを JSONL 形式で表す必要があります。 前の会話は、次の例のような JSONL ファイル内のデータセット行と同じです。

{"conversation":
    {
        "messages": [
        {
            "content": "Which tent is the most waterproof?", 
            "role": "user"
        },
        {
            "content": "The Alpine Explorer Tent is the most waterproof",
            "role": "assistant", 
            "context": "From the our product list the alpine explorer tent is the most waterproof. The Adventure Dining Table has higher weight."
        },
        {
            "content": "How much does it cost?",
            "role": "user"
        },
        {
            "content": "The Alpine Explorer Tent is $120.",
            "role": "assistant",
            "context": null
        }
        ]
    }
}

エバリュエータは、会話の最初のターンで query から有効な usercontext から assistantresponse から assistant がクエリと応答の形式で提供されることを理解します。 会話は次に、ターンごとに評価され、結果は会話スコアのすべてのターンで集計されます。

2 番目のターンでは、 contextnull またはキーがない場合でも、エバリュエーターはエラーで失敗するのではなく、ターンを空の文字列として解釈し、誤解を招く可能性があります。

データ要件に準拠するよう、評価データの有効性を検証することを強くお勧めします。

会話モードの場合、GroundednessEvaluator の例は次のようになります。

# Conversation mode:
import json
import os
from azure.ai.evaluation import GroundednessEvaluator, AzureOpenAIModelConfiguration

model_config = AzureOpenAIModelConfiguration(
    azure_endpoint=os.environ.get("AZURE_ENDPOINT"),
    api_key=os.environ.get("AZURE_API_KEY"),
    azure_deployment=os.environ.get("AZURE_DEPLOYMENT_NAME"),
    api_version=os.environ.get("AZURE_API_VERSION"),
)

# Initialize the Groundedness evaluator:
groundedness_eval = GroundednessEvaluator(model_config)

conversation = {
    "messages": [
        { "content": "Which tent is the most waterproof?", "role": "user" },
        { "content": "The Alpine Explorer Tent is the most waterproof", "role": "assistant", "context": "From the our product list the alpine explorer tent is the most waterproof. The Adventure Dining Table has higher weight." },
        { "content": "How much does it cost?", "role": "user" },
        { "content": "$120.", "role": "assistant", "context": "The Alpine Explorer Tent is $120."}
    ]
}

# Alternatively, you can load the same content from a JSONL file.
groundedness_conv_score = groundedness_eval(conversation=conversation)
print(json.dumps(groundedness_conv_score, indent=4))

会話の出力の場合、ターンごとの結果は一覧に格納され、会話の全体的なスコア 'groundedness': 4.0 はターン全体で平均されます。

{
    "groundedness": 5.0,
    "gpt_groundedness": 5.0,
    "groundedness_threshold": 3.0,
    "evaluation_per_turn": {
        "groundedness": [
            5.0,
            5.0
        ],
        "gpt_groundedness": [
            5.0,
            5.0
        ],
        "groundedness_reason": [
            "The response accurately and completely answers the query by stating that the Alpine Explorer Tent is the most waterproof, which is directly supported by the context. There are no irrelevant details or incorrect information present.",
            "The RESPONSE directly answers the QUERY with the exact information provided in the CONTEXT, making it fully correct and complete."
        ],
        "groundedness_result": [
            "pass",
            "pass"
        ],
        "groundedness_threshold": [
            3,
            3
        ]
    }
}

より多くのエバリュエーター モデルをサポートするには、プレフィックスのないキーを使用します。 たとえば、 groundedness.groundednessを使用します。

画像とマルチモーダル テキストと画像の会話サポート

画像とマルチモーダルの画像とテキストの会話をサポートするエバリュエーターの場合は、画像 URL または Base64 でエンコードされたイメージを conversationで渡すことができます。

サポートされるシナリオは次のとおりです。

  • 画像またはテキスト生成へのテキスト入力を含む複数の画像。
  • 画像の生成に対するテキストのみの入力。
  • テキスト生成への画像のみの入力。
from pathlib import Path
from azure.ai.evaluation import ContentSafetyEvaluator
import base64

# Create an instance of an evaluator with image and multi-modal support.
safety_evaluator = ContentSafetyEvaluator(credential=azure_cred, azure_ai_project=project_scope)

# Example of a conversation with an image URL:
conversation_image_url = {
    "messages": [
        {
            "role": "system",
            "content": [
                {"type": "text", "text": "You are an AI assistant that understands images."}
            ],
        },
        {
            "role": "user",
            "content": [
                {"type": "text", "text": "Can you describe this image?"},
                {
                    "type": "image_url",
                    "image_url": {
                        "url": "https://cdn.britannica.com/68/178268-050-5B4E7FB6/Tom-Cruise-2013.jpg"
                    },
                },
            ],
        },
        {
            "role": "assistant",
            "content": [
                {
                    "type": "text",
                    "text": "The image shows a man with short brown hair smiling, wearing a dark-colored shirt.",
                }
            ],
        },
    ]
}

# Example of a conversation with base64 encoded images:
base64_image = ""

with Path.open("Image1.jpg", "rb") as image_file:
    base64_image = base64.b64encode(image_file.read()).decode("utf-8")

conversation_base64 = {
    "messages": [
        {"content": "create an image of a branded apple", "role": "user"},
        {
            "content": [{"type": "image_url", "image_url": {"url": f"data:image/jpg;base64,{base64_image}"}}],
            "role": "assistant",
        },
    ]
}

# Run the evaluation on the conversation to output the result.
safety_score = safety_evaluator(conversation=conversation_image_url)

現在、イメージエバリュエーターとマルチモーダル エバリュエーターでは次のものがサポートされています。

  • 1 ターンのみ: 会話に含めることができるユーザー メッセージは 1 つだけで、アシスタント メッセージは 1 つだけです。
  • システム メッセージが 1 つしかない会話。
  • 画像を含め、10 MB 未満の会話ペイロード。
  • 絶対 URL と Base64 でエンコードされたイメージ。
  • 1 回のターンで複数の画像。
  • JPG/JPEG、PNG、GIF ファイル形式。

セットアップ

GroundednessProEvaluator プレビューを除く AI 支援品質エバリュエータの場合、gpt-35-turbo で GPT モデル (gpt-4gpt-4-turbogpt-4ogpt-4o-minimodel_config のいずれか) を指定する必要があります。 GPT モデルは、評価データをスコア付けするためのジャッジとして機能します。 Azure OpenAI と OpenAI の両方のモデル構成スキーマがサポートされています。 エバリュエーターで最適なパフォーマンスと解析可能な応答を得る場合は、プレビュー段階ではない GPT モデルを使用することをお勧めします。

gpt-3.5-turboをエバリュエーター モデルのgpt-4o-miniに置き換えます。 OpenAIによると、gpt-4o-miniは安価で、能力が高く、高速です。

API キーを使用して推論呼び出しを行うには、少なくとも Azure OpenAI リソースの Cognitive Services OpenAI User ロールがあることを確認します。 アクセス許可の詳細については、「 Azure OpenAI リソースのアクセス許可」を参照してください。

リスクと安全性のすべてのエバリュエーターと GroundednessProEvaluator (プレビュー) については、model_config での GPT のデプロイではなく、azure_ai_project の情報を提供する必要があります。 これにより、Foundry プロジェクトを使用してバックエンド評価サービスにアクセスします。

AI 支援組み込みエバリュエーターのプロンプト

透明性を確保するために、エバリュエーター ライブラリと Azure AI Evaluation Python SDK リポジトリの品質エバリュエーターのプロンプトをオープン ソースで提供します。ただし、安全性エバリュエーターと GroundednessProEvaluatorは、Azure AI Content Safety を利用します。 これらのプロンプトは、評価タスクを実行するための言語モデルの指示として機能します。これには、メトリックとそれに関連するスコアリング ルーブリックの人間にわかりやすい定義が必要です。 シナリオ固有の定義と採点ルーブリックをカスタマイズすることを強くお勧めします。 詳細については、「 カスタム エバリュエーター」を参照してください。

複合評価者

複合エバリュエーターは、個々の品質または安全性メトリックを組み合わせた組み込みのエバリュエーターです。 クエリ応答ペアまたはチャット メッセージの両方に対して、さまざまなメトリックをすぐに使用できます。

複合エバリュエータ Contains [説明]
QAEvaluator GroundednessEvaluatorRelevanceEvaluatorCoherenceEvaluatorFluencyEvaluatorSimilarityEvaluatorF1ScoreEvaluator クエリと応答ペア向けに組み合わされたメトリックの単一の出力用に、すべての品質エバリュエータを組み合わせます
ContentSafetyEvaluator ViolenceEvaluatorSexualEvaluatorSelfHarmEvaluatorHateUnfairnessEvaluator クエリと応答ペア向けに組み合わされたメトリックの単一の出力用に、すべての安全性エバリュエータを組み合わせます

evaluate() を使用したテスト データセットのローカル評価

単一のデータ行で組み込みまたはカスタムのエバリュエーターのスポットチェックを行った後、テスト データセット全体で evaluate() API を使用して複数のエバリュエーターを結合できます。

Microsoft Foundry プロジェクトの前提条件の設定手順

このセッションが初めての評価実行であり、Foundryプロジェクトへのログ記録も初めての場合は、次のセットアップ手順を行う必要があります。

  1. リソース レベルでストレージ アカウントを作成し、Foundry プロジェクトに接続します。 この bicep テンプレートは、キー認証を用いてストレージ アカウントを設定し、Foundry プロジェクトに接続します。
  2. 接続されているストレージ アカウントがすべてのプロジェクトにアクセスできることを確認します。
  3. Microsoft Entra ID を使用してストレージ アカウントを接続した場合は、Azure portal のアカウントと Foundry プロジェクト リソースの両方に 、ストレージ BLOB データ所有者 に対する Microsoft ID アクセス許可を付与してください。

データセットで評価し、結果を Foundry に記録する

evaluate() API がデータを正しく解析できるようにするには、列マッピングを指定して、データセットの列をエバリュエーターが受け入れるキーワードにマップする必要があります。 この例では、 queryresponse、および contextのデータ マッピングを指定します。

from azure.ai.evaluation import evaluate

result = evaluate(
    data="data.jsonl", # Provide your data here:
    evaluators={
        "groundedness": groundedness_eval,
        "answer_length": answer_length
    },
    # Column mapping:
    evaluator_config={
        "groundedness": {
            "column_mapping": {
                "query": "${data.queries}",
                "context": "${data.context}",
                "response": "${data.response}"
            } 
        }
    },
    # Optionally, provide your Foundry project information to track your evaluation results in your project portal.
    azure_ai_project = azure_ai_project,
    # Optionally, provide an output path to dump a JSON file of metric summary, row-level data, and the metric and Foundry project URL.
    output_path="./myevalresults.json"
)

ヒント

Foundry プロジェクトでログに記録された評価結果を表示するためのリンクの result.studio_url プロパティの内容を取得します。

エバリュエーターの出力結果は、集計 metrics と行レベルのデータとメトリックを含むディクショナリになります。 次の出力例を参照してください。

{'metrics': {'answer_length.value': 49.333333333333336,
             'groundedness.gpt_groundeness': 5.0, 'groundedness.groundeness': 5.0},
 'rows': [{'inputs.response': 'Paris is the capital/major city of France.',
           'inputs.context': 'Paris has been the capital/major city of France since '
                                  'the 10th century and is known for its '
                                  'cultural and historical landmarks.',
           'inputs.query': 'What is the capital/major city of France?',
           'outputs.answer_length.value': 31,
           'outputs.groundeness.groundeness': 5,
           'outputs.groundeness.gpt_groundeness': 5,
           'outputs.groundeness.groundeness_reason': 'The response to the query is supported by the context.'},
          {'inputs.response': 'Albert Einstein developed the theory of '
                            'relativity.',
           'inputs.context': 'Albert Einstein developed the theory of '
                                  'relativity, with his special relativity '
                                  'published in 1905 and general relativity in '
                                  '1915.',
           'inputs.query': 'Who developed the theory of relativity?',
           'outputs.answer_length.value': 51,
           'outputs.groundeness.groundeness': 5,
           'outputs.groundeness.gpt_groundeness': 5,
           'outputs.groundeness.groundeness_reason': 'The response to the query is supported by the context.'},
          {'inputs.response': 'The speed of light is approximately 299,792,458 '
                            'meters per second.',
           'inputs.context': 'The exact speed of light in a vacuum is '
                                  '299,792,458 meters per second, a constant '
                                  "used in physics to represent 'c'.",
           'inputs.query': 'What is the speed of light?',
           'outputs.answer_length.value': 66,
           'outputs.groundeness.groundeness': 5,
           'outputs.groundeness.gpt_groundeness': 5,
           'outputs.groundeness.groundeness_reason': 'The response to the query is supported by the context.'}],
 'traces': {}}

evaluate() の要件

evaluate() API では、Foundry プロジェクトの評価結果グラフを正しく表示するために、特定のデータ形式とエバリュエーター パラメーター キー名が必要です。

データ形式

evaluate() API は JSONL 形式のデータのみを受け入れます。 すべての組み込みエバリュエーターに対して、 evaluate() には、必要な入力フィールドを含む次の形式のデータが必要です。 組み込みのエバリュエーターに必要なデータ入力については、前のセクションを参照してください。 次のコード スニペットは、1 行の例です。

{
  "query":"What is the capital/major city of France?",
  "context":"France is in Europe",
  "response":"Paris is the capital/major city of France.",
  "ground_truth": "Paris"
}

エバリュエータのパラメーター形式

組み込みのエバリュエーターを渡す場合は、 evaluators パラメーター リストで適切なキーワード マッピングを指定します。 次の表は、組み込みのエバリュエーターからの結果が Foundry プロジェクトに記録されたときに UI に表示するために必要なキーワード マッピングを示しています。

エバリュエータ キーワード パラメーター
GroundednessEvaluator "groundedness"
GroundednessProEvaluator "groundedness_pro"
RetrievalEvaluator "retrieval"
RelevanceEvaluator "relevance"
CoherenceEvaluator "coherence"
FluencyEvaluator "fluency"
SimilarityEvaluator "similarity"
F1ScoreEvaluator "f1_score"
RougeScoreEvaluator "rouge"
GleuScoreEvaluator "gleu"
BleuScoreEvaluator "bleu"
MeteorScoreEvaluator "meteor"
ViolenceEvaluator "violence"
SexualEvaluator "sexual"
SelfHarmEvaluator "self_harm"
HateUnfairnessEvaluator "hate_unfairness"
IndirectAttackEvaluator "indirect_attack"
ProtectedMaterialEvaluator "protected_material"
CodeVulnerabilityEvaluator "code_vulnerability"
UngroundedAttributesEvaluator "ungrounded_attributes"
QAEvaluator "qa"
ContentSafetyEvaluator "content_safety"

evaluators パラメーターを設定する方法の例を次に示します。

result = evaluate(
    data="data.jsonl",
    evaluators={
        "sexual":sexual_evaluator,
        "self_harm":self_harm_evaluator,
        "hate_unfairness":hate_unfairness_evaluator,
        "violence":violence_evaluator
    }
)

ターゲットのローカル評価

実行して評価するクエリの一覧がある場合、 evaluate() API では target パラメーターもサポートされます。 このパラメーターは、クエリをアプリケーションに送信して回答を収集し、結果のクエリと応答に対してエバリュエーターを実行します。

ターゲットには、辞書内の任意の呼び出し可能なクラスを指定できます。 この例では、ターゲットとして設定された呼び出し可能なクラス askwiki.pyを含む Python スクリプト askwiki()があります。 単純な askwiki アプリに送信できるクエリのデータセットがある場合は、出力の根拠を評価できます。 "column_mapping"内のデータに適切な列マッピングを指定してください。 "default" を使用して、すべてのエバリュエータの列マッピングを指定できます。

"data.jsonl"の内容を次に示します。

{"query":"When was United States found ?", "response":"1776"}
{"query":"What is the capital/major city of France?", "response":"Paris"}
{"query":"Who is the best tennis player of all time ?", "response":"Roger Federer"}
from askwiki import askwiki

result = evaluate(
    data="data.jsonl",
    target=askwiki,
    evaluators={
        "groundedness": groundedness_eval
    },
    evaluator_config={
        "default": {
            "column_mapping": {
                "query": "${data.queries}",
                "context": "${outputs.context}",
                "response": "${outputs.response}"
            } 
        }
    }
)