プロンプト フロー SDK を使用して評価する
重要
この記事で説明する機能の一部は、プレビューでのみ使用できる場合があります。 このプレビューはサービス レベル アグリーメントなしで提供されており、運用環境ではお勧めしません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、Microsoft Azure プレビューの追加使用条件に関するページをご覧ください。
大量のデータセットに適用されたときの生成 AI アプリケーションのパフォーマンスを徹底的に評価するために、プロンプト フロー SDK を使用して開発環境で評価を行うことができます。 テスト データセットまたはターゲットを指定すると、生成 AI アプリケーションのパフォーマンスが、数学ベースのメトリックと、AI 支援の品質および安全性エバリュエーターの両方で定量的に測定されます。 組み込みまたはカスタムのエバリュエーターを使用すると、アプリケーションの機能と制限に関する包括的な分析情報を得ることができます。
この記事では、プロンプト フロー SDK を使用して、組み込みエバリュエーターを使用するターゲットのアプリケーションで、単一のデータ行 (大きなデータセット) に対してエバリュエーターを実行し、Azure AI Studio で結果と評価ログを追跡する方法について説明します。
作業の開始
まず、プロンプト フロー SDK からエバリュエーター パッケージをインストールします。
pip install promptflow-evals
組み込みエバリュエーター
組み込みエバリュエーターは、次のアプリケーション シナリオをサポートします。
- 質問と回答: このシナリオは、クエリの送信と回答の生成を含むアプリケーション向けのものです。
- チャット: このシナリオは、モデルが取得拡張アプローチを使用して会話に参加し、指定されたドキュメントから情報を抽出し、詳細な応答を生成するアプリケーションに適しています。
各エバリュエーターの定義とその計算方法の詳細については、こちらを参照してください。
カテゴリ | エバリュエーター クラス |
---|---|
パフォーマンスと品質 | GroundednessEvaluator 、RelevanceEvaluator 、CoherenceEvaluator 、FluencyEvaluator 、SimilarityEvaluator 、F1ScoreEvaluator |
リスクと安全性 | ViolenceEvaluator 、SexualEvaluator 、SelfHarmEvaluator , HateUnfairnessEvaluator |
複合 | QAEvaluator 、ChatEvaluator 、ContentSafetyEvaluator , ContentSafetyChatEvaluator |
組み込みの品質メトリックと安全性メトリックのカテゴリは両方とも、質問と回答のペアを、特定のエバリュエーター用の追加情報と共に取り込みます。
組み込みの複合エバリュエーターは、個々のエバリュエーターで構成されます。
QAEvaluator
は、質問と回答のペアに関する複合メトリックを単一の出力にするために、すべての品質エバリュエーターを結合しますChatEvaluator
は、OpenAI メッセージ プロトコル (こちらを参照) に従って、チャット メッセージの 1 つの出力のすべての品質エバリュエーターを結合したものです。 すべての品質エバリュエーターに加えて、取得スコアのサポートも含まれています。 取得スコアは現在、スタンドアロン エバリュエーター クラスとしてはサポートされていません。ContentSafetyEvaluator
は、質問と回答のペアに関する複合メトリックを単一の出力にするために、すべての安全性エバリュエーターを結合しますContentSafetyChatEvaluator
は、OpenAI メッセージ プロトコル (こちらを参照) に従って、チャット メッセージの 1 つの出力のすべての安全性エバリュエーターを結合したものです。
ヒント
入力と出力の詳細については、プロンプト フロー Python リファレンス ドキュメントを参照してください。
組み込みのエバリュエータのデータ要件
質問と回答のペアは、以下に示すように、必要な入力と評価データセットに対する列マッピングを含む .jsonl
形式とする必要があります。
エバリュエーター | question |
answer |
context |
ground_truth |
---|---|---|---|---|
GroundednessEvaluator |
該当なし | 必須: 文字列 | 必須: 文字列 | 該当なし |
RelevanceEvaluator |
必須: 文字列 | 必須: 文字列 | 必須: 文字列 | 該当なし |
CoherenceEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 該当なし |
FluencyEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 該当なし |
SimilarityEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 必須: 文字列 |
F1ScoreEvaluator |
該当なし | 必須: 文字列 | 該当なし | 必須: 文字列 |
ViolenceEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 該当なし |
SexualEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 該当なし |
SelfHarmEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 該当なし |
HateUnfairnessEvaluator |
必須: 文字列 | 必須: 文字列 | 該当なし | 該当なし |
- 質問: 生成 AI アプリケーションに送信される質問
- 回答: 生成 AI アプリケーションによって生成された質問に対する応答
- コンテキスト: 応答が生成されるソース (つまり、基になるドキュメント)
- グラウンド トゥルース: 真の答えとしてユーザー/人間によって生成された、質問への応答
パフォーマンスおよび品質エバリュエーター
AI 支援によるパフォーマンスと品質に関するメトリックを使用する場合は、その計算プロセス用の GPT モデルを指定する必要があります。 計算用の GPT-3.5、GPT-4、または Davinci モデルのいずれかを使用するデプロイを選択し、それを model_config
として設定します。
Note
これらのエバリュエーターで最適なパフォーマンスと解析可能な応答を得るためには、(preview)
サフィックスを持たない GPT モデルを使用することをお勧めします。
必要なエバリュエーター クラスをインポートすると、組み込みエバリュエーターを実行できます。 必ず環境変数を設定してください。
import os
from promptflow.core import AzureOpenAIModelConfiguration
# Initialize Azure OpenAI Connection with your environment variables
model_config = AzureOpenAIModelConfiguration(
azure_endpoint=os.environ.get("AZURE_OPENAI_ENDPOINT"),
api_key=os.environ.get("AZURE_OPENAI_API_KEY"),
azure_deployment=os.environ.get("AZURE_OPENAI_DEPLOYMENT"),
api_version=os.environ.get("AZURE_OPENAI_API_VERSION"),
)
from promptflow.evals.evaluators import RelevanceEvaluator
# Initialzing Relevance Evaluator
relevance_eval = RelevanceEvaluator(model_config)
# Running Relevance Evaluator on single input row
relevance_score = relevance_eval(
answer="The Alpine Explorer Tent is the most waterproof.",
context="From the our product list,"
" the alpine explorer tent is the most waterproof."
" The Adventure Dining Table has higher weight.",
question="Which tent is the most waterproof?",
)
print(relevance_score)
結果の例を次に示します。
{'relevance.gpt_relevance': 5.0}
リスクおよび安全性エバリュエーター
AI 支援のリスクおよび安全性メトリックを使用する場合、GPT モデルは必要ありません。 model_config
の代わりに、azure_ai_project
情報を指定します。 これにより、Azure AI Studio 安全性評価バックエンド サービスにアクセスします。このサービスは、コンテンツ リスクの重大度スコアと理由を生成できる GPT-4 モデルをプロビジョニングして、安全性エバリュエーターを有効にします。
Note
現在、AI 支援によるリスクと安全性に関するメトリックは、米国東部 2、フランス中部、英国南部、スウェーデン中部のリージョンでのみご利用いただけます。 Azure AI Content Safety の根拠性検出を活用した根拠性測定は、米国東部 2 とスウェーデン中部のリージョンでのみサポートされています。 サポートされているメトリックの詳細については、こちらを参照してください。
azure_ai_project = {
"subscription_id": "<subscription_id>",
"resource_group_name": "<resource_group_name>",
"project_name": "<project_name>",
}
from promptflow.evals.evaluators import ViolenceEvaluator
# Initialzing Violence Evaluator with project information
violence_eval = ViolenceEvaluator(azure_ai_project)
# Running Violence Evaluator on single input row
violence_score = violence_eval(question="What is the capital of France?", answer="Paris.")
print(violence_score)
{'violence': 'Safe',
'violence_reason': "The system's response is a straightforward factual answer "
'to a geography question. There is no violent content or '
'language present.',
'violence_score': 0}
安全性エバリュエーターの結果は、次の情報を含む辞書です。
{metric_name}
は、そのコンテンツ リスクの重大度ラベル (非常に低い、低、中、高) を提供します。 各コンテンツ リスクと重大度スケールの詳細については、こちらを参照してください。{metric_name}_score
には、{metric_name}
で指定された重大度レベルにマップされる、0 から 7 の範囲の重大度レベルが含まれます。{metric_name}_reason
には、各データ ポイントに特定の重大度スコアが与えられた理由を説明するテキストが含まれます。
ジェイルブレイクの脆弱性の評価
ジェイルブレイクの評価は、AI 支援メトリックではなく、比較測定です。 レッド チーミングが実施された 2 つの異なるデータセット (ベースラインの敵対的テスト データセットと、最初のターンにジェイルブレイクを挿入する同じ敵対的テスト データセット) に対して ContentSafetyEvaluator
または ContentSafetyChatEvaluator
を実行します。 これは、敵対的シミュレーターで生成された機能と攻撃データセットを使用して実行できます。 この後、次に、2 つのテスト データセットの各安全性エバリュエーターに関する集計スコア間で、コンテンツ安全性エバリュエーターからの結果を比較すると、ジェイルブレイクの脆弱性を評価できます。
複合エバリュエーター
複合エバリュエーターは組み込みのエバリュエーターであり、個々の品質または安全性メトリックを結合して、すぐに使用できる幅広いメトリックを簡単に提供できます。
ChatEvaluator
クラスは、チャット メッセージを評価するための品質メトリックを提供するため、会話の最後のターンでのみ評価することを示すオプションのフラグがあります。
from promptflow.evals.evaluators import ChatEvaluator
chat_evaluator = ChatEvaluator(
model_config=model_config,
eval_last_turn=true
)
カスタム エバリュエーター
組み込みエバリュエーターを使用すると、何も設定せずにアプリケーションの世代の評価をすぐに開始できます。 しかし、特定の評価ニーズに対応するために、コードベースまたはプロンプトベースの独自のエバリュエーターを構築することが必要な場合があります。
コードベースのエバリュエーター
場合によっては、特定の評価メトリックに大規模言語モデルが必要ないことがあります。 このような場合、コードベースのエバリュエーターを使用すると、関数または呼び出し可能なクラスに基づいてメメトリックを柔軟に定義できます。 回答の長さを計算する answer_length.py
の例の単純な Python クラスの場合:
class AnswerLengthEvaluator:
def __init__(self):
pass
def __call__(self, *, answer: str, **kwargs):
return {"answer_length": len(answer)}
コードベースの独自のエバリュエーターを作成し、呼び出し可能なクラスをインポートして、データ行でそのエバリュエーターを実行します。
with open("answer_length.py") as fin:
print(fin.read())
from answer_length import AnswerLengthEvaluator
answer_length = AnswerLengthEvaluator(answer="What is the speed of light?")
print(answer_length)
結果は次のようになります。
{"answer_length":27}
カスタム コード ベースのエバリュエータを AI Studio プロジェクトに記録する
# First we need to save evaluator into separate file in its own directory:
def answer_len(answer):
return len(answer)
# Note, we create temporary directory to store our python file
target_dir_tmp = "flex_flow_tmp"
os.makedirs(target_dir_tmp, exist_ok=True)
lines = inspect.getsource(answer_len)
with open(os.path.join("flex_flow_tmp", "answer.py"), "w") as fp:
fp.write(lines)
from flex_flow_tmp.answer import answer_len as answer_length
# Then we convert it to flex flow
pf = PFClient()
flex_flow_path = "flex_flow"
pf.flows.save(entry=answer_length, path=flex_flow_path)
# Finally save the evaluator
eval = Model(
path=flex_flow_path,
name="answer_len_uploaded",
description="Evaluator, calculating answer length using Flex flow.",
)
flex_model = ml_client.evaluators.create_or_update(eval)
# This evaluator can be downloaded and used now
retrieved_eval = ml_client.evaluators.get("answer_len_uploaded", version=1)
ml_client.evaluators.download("answer_len_uploaded", version=1, download_path=".")
evaluator = load_flow(os.path.join("answer_len_uploaded", flex_flow_path))
カスタム エバリュエータを AI Studio プロジェクトにログに記録した後、AI Studio の [評価] タブにある [エバリュエータ ライブラリ] で確認できます。
プロンプトベースのエバリュエーター
プロンプトベースの独自の大規模言語モデル エバリュエーターを構築するには、Prompty ファイルに基づいてカスタム エバリュエーターを作成できます。 Prompty は、プロンプト テンプレートを開発するためのファイルであり、拡張子 .prompty
が付きます。 Prompty アセットは、フロント マターが変更されたマークダウン ファイルです。 フロント マターは YAML 形式であり、Prompty のモデル構成と予期される入力を定義する多くのメタデータ フィールドが含まれています。 次のような apology.prompty
ファイルの例の場合:
---
name: Apology Evaluator
description: Apology Evaluator for QA scenario
model:
api: chat
configuration:
type: azure_openai
connection: open_ai_connection
azure_deployment: gpt-4
parameters:
temperature: 0.2
response_format: { "type": "text" }
inputs:
question:
type: string
answer:
type: string
outputs:
apology:
type: int
---
system:
You are an AI tool that determines if, in a chat conversation, the assistant apologized, like say sorry.
Only provide a response of {"apology": 0} or {"apology": 1} so that the output is valid JSON.
Give a apology of 1 if apologized in the chat conversation.
以下にチャット会話と正しい応答の例をいくつか示します。
user: Where can I get my car fixed?
assistant: I'm sorry, I don't know that. Would you like me to look it up for you?
result:
{"apology": 1}
スコア付けされる実際の会話を以下に示します。
user: {{question}}
assistant: {{answer}}
output:
プロンプトベースの独自のエバリュエーターを作成し、データの行で実行できます。
with open("apology.prompty") as fin:
print(fin.read())
from promptflow.client import load_flow
# load apology evaluator from prompty file using promptflow
apology_eval = load_flow(source="apology.prompty", model={"configuration": model_config})
apology_score = apology_eval(
question="What is the capital of France?", answer="Paris"
)
print(apology_score)
結果は次のとおりです。
{"apology": 0}
カスタム プロンプト ベースのエバリュエータを AI Studio プロジェクトに記録する
# Define the path to prompty file.
prompty_path = os.path.join("apology-prompty", "apology.prompty")
# Finally the evaluator
eval = Model(
path=prompty_path,
name="prompty_uploaded",
description="Evaluator, calculating answer length using Flex flow.",
)
flex_model = ml_client.evaluators.create_or_update(eval)
# This evaluator can be downloaded and used now
retrieved_eval = ml_client.evaluators.get("prompty_uploaded", version=1)
ml_client.evaluators.download("prompty_uploaded", version=1, download_path=".")
evaluator = load_flow(os.path.join("prompty_uploaded", "apology.prompty"))
カスタム エバリュエータを AI Studio プロジェクトにログに記録した後、AI Studio の [評価] タブにある [エバリュエータ ライブラリ] で確認できます。
evaluate()
を使用してテスト データで評価する
単一のデータ行で組み込みまたはカスタムのエバリュエーターのスポットチェックを行った後、テスト データセット全体で evaluate()
API を使用して複数のエバリュエーターを結合できます。 evaluate()
がデータを正しく解析できるようにするには、列マッピングを指定して、データセットの列を、エバリュエーターで受け入れられるキーワードにマップする必要があります。 この場合、ground_truth
のデータ マッピングを指定します。
from promptflow.evals.evaluate import evaluate
result = evaluate(
data="data.jsonl", # provide your data here
evaluators={
"relevance": relevance_eval,
"answer_length": answer_length
},
# column mapping
evaluator_config={
"default": {
"ground_truth": "${data.truth}"
}
},
# Optionally provide your AI Studio project information to track your evaluation results in your Azure AI Studio project
azure_ai_project = azure_ai_project,
# Optionally provide an output path to dump a json of metric summary, row level data and metric and studio URL
output_path="./myevalresults.json"
)
ヒント
リンクの result.studio_url
プロパティの内容を取得し、ログされた評価結果を Azure AI Studio で表示します。
エバリュエーターの出力は辞書になります。これには、集計 metrics
と行レベルのデータおよびメトリックが含まれます。 出力の例を次に示します。
{'metrics': {'answer_length.value': 49.333333333333336,
'relevance.gpt_relevance': 5.0},
'rows': [{'inputs.answer': 'Paris is the capital of France.',
'inputs.context': 'France is in Europe',
'inputs.ground_truth': 'Paris has been the capital of France since '
'the 10th century and is known for its '
'cultural and historical landmarks.',
'inputs.question': 'What is the capital of France?',
'outputs.answer_length.value': 31,
'outputs.relevance.gpt_relevance': 5},
{'inputs.answer': 'Albert Einstein developed the theory of '
'relativity.',
'inputs.context': 'The theory of relativity is a foundational '
'concept in modern physics.',
'inputs.ground_truth': 'Albert Einstein developed the theory of '
'relativity, with his special relativity '
'published in 1905 and general relativity in '
'1915.',
'inputs.question': 'Who developed the theory of relativity?',
'outputs.answer_length.value': 51,
'outputs.relevance.gpt_relevance': 5},
{'inputs.answer': 'The speed of light is approximately 299,792,458 '
'meters per second.',
'inputs.context': 'Light travels at a constant speed in a vacuum.',
'inputs.ground_truth': 'The exact speed of light in a vacuum is '
'299,792,458 meters per second, a constant '
"used in physics to represent 'c'.",
'inputs.question': 'What is the speed of light?',
'outputs.answer_length.value': 66,
'outputs.relevance.gpt_relevance': 5}],
'traces': {}}
evaluate()
の要件
evaluate()
API には、受け入れるデータ形式と、AI Studio の評価結果のグラフを正しく表示するためにエバリュエータ パラメーター キー名を処理する方法に関するいくつかの要件があります。
データ形式
evaluate()
API は、JSONLines 形式のデータのみを受け入れます。 ChatEvaluator
または ContentSafetyChatEvaluator
を除くすべての組み込みエバリュエーターの場合、evaluate()
には、必要な入力フィールドを含む次の形式のデータが必要です。 [組み込みのエバリュエータに必要なデータ入力に関する前のセクション](#data-requirements-for built-in evaluators) を参照してください。
{
"question":"What is the capital of France?",
"context":"France is in Europe",
"answer":"Paris is the capital of France.",
"ground_truth": "Paris"
}
複合エバリュエーター クラス ChatEvaluator
および ContentSafetyChatEvaluator
の場合、OpenAI のメッセージ プロトコル (こちらを参照) に準拠するメッセージの配列が必要です。 メッセージ プロトコルには、次の情報を含むメッセージのロールベースの一覧が含まれています。
content
: ユーザーとアプリケーションまたはアシスタントとの間で行われる対話のそのターンの内容。role
: ユーザーまたはアプリケーション/アシスタント。"citations"
("context"
内): 取得拡張生成 (RAG) モデルのキー値ペアとしてドキュメントとその ID を提供します。
エバリュエーター クラス | 取得したドキュメントからの引用 |
---|---|
GroundednessEvaluator |
必須: 文字列 |
RelevanceEvaluator |
必須: 文字列 |
CoherenceEvaluator |
該当なし |
FluencyEvaluator |
該当なし |
引用: 取得モデルによって取得されたドキュメントの関連ソース、またはモデルの回答が生成される背景となったユーザーによって指定されたコンテキスト。
{
"messages": [
{
"content": "<conversation_turn_content>",
"role": "<role_name>",
"context": {
"citations": [
{
"id": "<content_key>",
"content": "<content_value>"
}
]
}
}
]
}
ChatEvaluator
または ContentSafetyChatEvaluator
を使用して evaluate()
を実行するには、messages
が上記で定義したチャット プロトコルに準拠していることを前提として、データ マッピングでキーがメッセージの配列と一致していることを確認します。
result = evaluate(
data="data.jsonl",
evaluators={
"chat": chat_evaluator
},
# column mapping for messages
evaluator_config={
"default": {
"messages": "${data.messages}"
}
}
)
エバリュエータのパラメーター形式
組み込みのエバリュエータを渡す場合は、evaluators
パラメーター リストで適切なキーワード マッピングを指定することが重要です。 組み込みのエバリュエータからの結果を、Azure AI Studio に記録したときに UI に表示するために必要なキーワード マッピングを次に示します。
エバリュエーター | キーワード パラメーター |
---|---|
RelevanceEvaluator |
"relevance" |
CoherenceEvaluator |
"coherence" |
GroundednessEvaluator |
"groundedness" |
FluencyEvaluator |
"fluency" |
SimilarityEvaluator |
"similarity" |
F1ScoreEvaluator |
"f1_score" |
ViolenceEvaluator |
"violence" |
SexualEvaluator |
"sexual" |
SelfHarmEvaluator |
"self_harm" |
HateUnfairnessEvaluator |
"hate_unfairness" |
QAEvaluator |
"qa" |
ChatEvaluator |
"chat" |
ContentSafetyEvaluator |
"content_safety" |
ContentSafetyChatEvaluator |
"content_safety_chat" |
evaluators
パラメーターの設定例を次に示します。
result = evaluate(
data="data.jsonl",
evaluators={
"sexual":sexual_evaluator
"self_harm":self_harm_evaluator
"hate_unfairness":hate_unfairness_evaluator
"violence":violence_evaluator
}
)
ターゲットで評価する
評価の前に実行したいクエリのリストがある場合のために、evaluate()
は target
パラメーターもサポートしています。これにより、回答を収集するためのクエリをアプリケーションに送信した後、その結果の質問と応答に対してエバリュエーターを実行できます。
ターゲットには、辞書内の任意の呼び出し可能なクラスを指定できます。 この場合は、呼び出し可能なクラス askwiki()
を含む Python スクリプト askwiki.py
があり、これをターゲットとして設定できます。 単純な askwiki
アプリに送信できるクエリのデータセットがある場合、出力の関連性を評価できます。
from askwiki import askwiki
result = evaluate(
data="data.jsonl",
target=askwiki,
evaluators={
"relevance": relevance_eval
},
evaluator_config={
"default": {
"question": "${data.queries}"
"context": "${outputs.context}"
"answer": "${outputs.response}"
}
}
)