重要
この記事で "(プレビュー)" と付記されている項目は、現在、パブリック プレビュー段階です。 このプレビューはサービス レベル アグリーメントなしで提供されており、運用環境ではお勧めしません。 特定の機能はサポート対象ではなく、機能が制限されることがあります。 詳しくは、Microsoft Azure プレビューの追加使用条件に関するページをご覧ください。
AI エージェントは、ビジネス ニーズに合ったワークフローを作成するための強力な生産性アシスタントです。 ただし、複雑な相互作用パターンにより、可観測性に関する課題が発生します。 この記事では、単純なエージェント データまたはエージェント メッセージに対して組み込みのエバリュエーターをローカルで実行する方法について説明します。
運用対応のエージェント アプリケーションを構築し、可観測性と透明性を実現するには、開発者は、エージェントのワークフローからの最終的な出力だけでなく、ワークフロー自体の品質と効率を評価するツールが必要です。 たとえば、一般的なエージェント ワークフローを考えてみましょう。
ユーザー クエリ "weather tomorrow" のようなイベントは、エージェント ワークフローをトリガーします。 ユーザーの意図による推論、ツールの呼び出し、検索拡張生成を利用して最終的な応答を生成するなど、複数の手順の実行が開始されます。 このプロセスでは、ワークフローの各ステップと最終的な出力の品質と安全性を評価することが重要です。 具体的には、これらの評価の側面を、エージェントの次の評価者に定式化します。
- 意図の解決: エージェントがユーザーの意図を正しく識別するかどうかを測定します。
- ツール呼び出しの精度: エージェントがユーザーの要求に対して正しい関数ツール呼び出しを行ったかどうかを測定します。
- タスクの準拠: エージェントのシステム メッセージと前の手順に従って、エージェントの最終的な応答が割り当てられたタスクに準拠しているかどうかを測定します。
また、当社の包括的な組み込みエバリュエータースイートを使用して、エージェントワークフローの他の品質と安全性の側面を評価することもできます。 一般に、エージェントはエージェント メッセージを出力します。 エバリュエーターを使用するためにエージェント メッセージを適切な評価データに変換することは、困難なタスクになる可能性があります。 Azure AI Agent Service を使用してエージェントを構築する場合は、コンバーターのサポートを通じてシームレスに評価できます。 Azure AI Agent Service の外部でエージェントを構築する場合でも、エージェント メッセージを 必要なデータ形式に解析することで、エージェントワークフローに適したエバリュエーターを使用できます。 他のエージェントの 評価の例を参照してください。
作業の開始
まず、Azure AI 評価 SDK からエバリュエータ パッケージをインストールします。
pip install azure-ai-evaluation
Azure AI エージェントを評価する
ただし、 Azure AI Agent Service を使用する場合は、Azure AI エージェント スレッドと実行に対するコンバーター サポートを使用して、エージェントをシームレスに評価できます。 コンバーターからの Azure AI エージェント メッセージのエバリュエーターの一覧をサポートします。
- 品質:
IntentResolution
、ToolCallAccuracy
、TaskAdherence
、Relevance
、Coherence
、Fluency
- 安全性:
CodeVulnerabilities
、Violence
、Self-harm
、Sexual
、HateUnfairness
、IndirectAttack
、ProtectedMaterials
。
注
ToolCallAccuracyEvaluator
は Azure AI エージェントの関数ツールの評価のみをサポートしますが、組み込みのツールの評価はサポートしていません。 エージェント メッセージの評価には、少なくとも 1 つの Function Tool が実際に呼び出されている必要があります。
Azure AI エージェントをシームレスに構築して評価する例を次に示します。 評価とは別に、Azure AI Foundry Agent Service には、 pip install azure-ai-projects azure-identity
と Azure AI プロジェクト接続文字列とサポートされているモデルが必要です。
エージェント スレッドと実行プロセスの作成
import os, json
import pandas as pd
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from typing import Set, Callable, Any
from azure.ai.projects.models import FunctionTool, ToolSet
from dotenv import load_dotenv
load_dotenv()
# Define some custom python function
def fetch_weather(___location: str) -> str:
"""
Fetches the weather information for the specified ___location.
:param ___location (str): The ___location to fetch weather for.
:return: Weather information as a JSON string.
:rtype: str
"""
# In a real-world scenario, you'd integrate with a weather API.
# Here, we'll mock the response.
mock_weather_data = {"Seattle": "Sunny, 25°C", "London": "Cloudy, 18°C", "Tokyo": "Rainy, 22°C"}
weather = mock_weather_data.get(___location, "Weather data not available for this ___location.")
weather_json = json.dumps({"weather": weather})
return weather_json
user_functions: Set[Callable[..., Any]] = {
fetch_weather,
}
# Adding Tools to be used by Agent
functions = FunctionTool(user_functions)
toolset = ToolSet()
toolset.add(functions)
# Create the agent
AGENT_NAME = "Seattle Tourist Assistant"
project_client = AIProjectClient.from_connection_string(
credential=DefaultAzureCredential(),
conn_str=os.environ["PROJECT_CONNECTION_STRING"],
)
agent = project_client.agents.create_agent(
model=os.environ["MODEL_DEPLOYMENT_NAME"],
name=AGENT_NAME,
instructions="You are a helpful assistant",
toolset=toolset,
)
print(f"Created agent, ID: {agent.id}")
thread = project_client.agents.create_thread()
print(f"Created thread, ID: {thread.id}")
# Create message to thread
MESSAGE = "Can you fetch me the weather in Seattle?"
message = project_client.agents.create_message(
thread_id=thread.id,
role="user",
content=MESSAGE,
)
print(f"Created message, ID: {message.id}")
run = project_client.agents.create_and_process_run(thread_id=thread.id, agent_id=agent.id)
print(f"Run finished with status: {run.status}")
if run.status == "failed":
print(f"Run failed: {run.last_error}")
print(f"Run ID: {run.id}")
# display messages
for message in project_client.agents.list_messages(thread.id, order="asc").data:
print(f"Role: {message.role}")
print(f"Content: {message.content[0].text.value}")
print("-" * 40)
単一エージェントの実行を評価する
エージェントの実行を作成すると、コンバーターを使用して、Azure AI エージェントのスレッド データを、エバリュエーターが理解できる必要な評価データに簡単に変換できます。
import json, os
from azure.ai.evaluation import AIAgentConverter, IntentResolutionEvaluator
# Initialize the converter for Azure AI agents
converter = AIAgentConverter(project_client)
# Specify the thread and run id
thread_id = thread.id
run_id = run.id
converted_data = converter.convert(thread_id, run_id)
これで終わりです! 各エバリュエーターの入力要件を読み取り、それらを解析する作業を行う必要はありません。 エバリュエーターを選択し、この 1 回の実行でエバリュエーターを呼び出す必要があります。 モデルを選択する場合は、 o3-mini
や後でリリースされるモデルなどの強力な推論モデルをお勧めします。 quality_evaluators
とsafety_evaluators
で品質と安全性のエバリュエーターの一覧を設定し、複数のエージェントの実行またはスレッドの評価で参照します。
# specific to agentic workflows
from azure.ai.evaluation import IntentResolutionEvaluator, TaskAdherenceEvaluator, ToolCallAccuracyEvaluator
# other quality as well as risk and safety metrics
from azure.ai.evaluation import RelevanceEvaluator, CoherenceEvaluator, CodeVulnerabilityEvaluator, ContentSafetyEvaluator, IndirectAttackEvaluator, FluencyEvaluator
from azure.ai.projects.models import ConnectionType
from azure.identity import DefaultAzureCredential
import os
from dotenv import load_dotenv
load_dotenv()
model_config = project_client.connections.get_default(
connection_type=ConnectionType.AZURE_OPEN_AI,
include_credentials=True) \
.to_evaluator_model_config(
deployment_name="o3-mini",
api_version="2023-05-15",
include_credentials=True
)
quality_evaluators = {evaluator.__name__: evaluator(model_config=model_config) for evaluator in [IntentResolutionEvaluator, TaskAdherenceEvaluator, ToolCallAccuracyEvaluator, CoherenceEvaluator, FluencyEvaluator, RelevanceEvaluator]}
## Using Azure AI Foundry Hub
azure_ai_project = {
"subscription_id": os.environ.get("AZURE_SUBSCRIPTION_ID"),
"resource_group_name": os.environ.get("AZURE_RESOURCE_GROUP"),
"project_name": os.environ.get("AZURE_PROJECT_NAME"),
}
## Using Azure AI Foundry Development Platform, example: AZURE_AI_PROJECT=https://your-account.services.ai.azure.com/api/projects/your-project
azure_ai_project = os.environ.get("AZURE_AI_PROJECT")
safety_evaluators = {evaluator.__name__: evaluator(azure_ai_project=azure_ai_project, credential=DefaultAzureCredential()) for evaluator in[ContentSafetyEvaluator, IndirectAttackEvaluator, CodeVulnerabilityEvaluator]}
# reference the quality and safety evaluator list above
quality_and_safety_evaluators = {**quality_evaluators, **safety_evaluators}
for name, evaluator in quality_and_safety_evaluators.items():
try:
result = evaluator(**converted_data)
print(name)
print(json.dumps(result, indent=4))
except:
print("Note: if there is no tool call to evaluate in the run history, ToolCallAccuracyEvaluator will raise an error")
pass
出力形式
クエリと応答のペアに対する AI 支援型の品質エバリュエータの結果は、次を含むディクショナリになります。
{metric_name}
は、Likert スケール(整数 1 から 5)または 0 から 1 の間の浮動小数点数で数値スコアを提供します。{metric_name}_label
はバイナリ ラベルを提供します (メトリックが自然にバイナリ スコアを出力する場合)。{metric_name}_reason
は、データ ポイントごとに特定のスコアまたはラベルが与えられた理由を説明します。
理解可能性をさらに向上させるために、すべての評価者はバイナリしきい値を受け入れ(既にバイナリ出力をしていない場合)、2つの新しいキーを出力します。 二値化しきい値の場合、既定値が設定され、ユーザーはそれをオーバーライドできます。 2 つの新しいキーは次のとおりです。
{metric_name}_result
二値化の閾値に基づく "pass" または "fail" の文字列。{metric_name}_threshold
既定またはユーザーによって設定された数値の二値化しきい値。additional_details
には、1 つのエージェント実行の品質に関するデバッグ情報が含まれています。
一部のエバリュエーターの出力例:
{
"intent_resolution": 5.0, # likert scale: 1-5 integer
"intent_resolution_result": "pass", # pass because 5 > 3 the threshold
"intent_resolution_threshold": 3,
"intent_resolution_reason": "The assistant correctly understood the user's request to fetch the weather in Seattle. It used the appropriate tool to get the weather information and provided a clear and accurate response with the current weather conditions in Seattle. The response fully resolves the user's query with all necessary information.",
"additional_details": {
"conversation_has_intent": true,
"agent_perceived_intent": "fetch the weather in Seattle",
"actual_user_intent": "fetch the weather in Seattle",
"correct_intent_detected": true,
"intent_resolved": true
}
}
{
"task_adherence": 5.0, # likert scale: 1-5 integer
"task_adherence_result": "pass", # pass because 5 > 3 the threshold
"task_adherence_threshold": 3,
"task_adherence_reason": "The response accurately follows the instructions, fetches the correct weather information, and relays it back to the user without any errors or omissions."
}
{
"tool_call_accuracy": 1.0, # this is the average of all correct tool calls (or passing rate)
"tool_call_accuracy_result": "pass", # pass because 1.0 > 0.8 the threshold
"tool_call_accuracy_threshold": 0.8,
"per_tool_call_details": [
{
"tool_call_accurate": true,
"tool_call_accurate_reason": "The tool call is directly relevant to the user's query, uses the correct parameter, and the parameter value is correctly extracted from the conversation.",
"tool_call_id": "call_2svVc9rNxMT9F50DuEf1XExx"
}
]
}
複数のエージェントの実行またはスレッドを評価する
複数のエージェントの実行またはスレッドを評価するには、非同期評価にバッチ evaluate()
API を使用することをお勧めします。 まず、コンバーターサポートを使用して、エージェントスレッドデータをファイルに変換します。
import json
from azure.ai.evaluation import AIAgentConverter
# Initialize the converter
converter = AIAgentConverter(project_client)
# Specify a file path to save agent output (which is evaluation input data)
filename = os.path.join(os.getcwd(), "evaluation_input_data.jsonl")
evaluation_data = converter.prepare_evaluation_data(thread_ids=thread_id, filename=filename)
print(f"Evaluation data saved to {filename}")
1 行のコードで準備された評価データを使用して、エバリュエーターを選択してエージェントの品質を評価し、バッチ評価実行を送信できます。 ここでは、1 つのエージェントの実行を評価するセクションで、品質と安全性のエバリュエーターの同じ一覧を参照しますquality_and_safety_evaluators
。
import os
from dotenv import load_dotenv
load_dotenv()
# Batch evaluation API (local)
from azure.ai.evaluation import evaluate
response = evaluate(
data=filename,
evaluation_name="agent demo - batch run",
evaluators=quality_and_safety_evaluators,
# optionally, log your results to your Azure AI Foundry project for rich visualization
azure_ai_project={
"subscription_id": os.environ["AZURE_SUBSCRIPTION_ID"],
"project_name": os.environ["PROJECT_NAME"],
"resource_group_name": os.environ["RESOURCE_GROUP_NAME"],
}
)
# Inspect the average scores at a high-level
print(response["metrics"])
# Use the URL to inspect the results on the UI
print(f'AI Foundary URL: {response.get("studio_url")}')
URI に従って Foundry にリダイレクトされ、Azure AI プロジェクトで評価結果が表示され、アプリケーションがデバッグされます。 理由フィールドと合格/不合格を使用すると、アプリケーションの品質と安全性のパフォーマンスを簡単に評価できます。 複数の実行を実行して比較し、回帰や改善をテストできます。
Azure AI Evaluation SDK クライアント ライブラリを使用すると、コンバーター のサポートを通じて Azure AI エージェントをシームレスに評価できます。これにより、エージェントワークフローの可観測性と透明性を実現できます。
他のエージェントの評価
Azure AI Foundry Agent Service 以外のエージェントの場合でも、選択したエバリュエーターに適したデータを準備することで、それらを評価できます。
通常、エージェントは、ユーザーまたは他のエージェントとやり取りするメッセージを出力します。 組み込みのエバリュエーターは、query
に従って、response
、ground_truth
、内の文字列などの単純なデータ型を受け入れます。 ただし、エージェントメッセージからこれらの単純なデータを抽出することは、エージェントとフレームワークの違いの複雑な相互作用パターンのために困難になる可能性があります。 たとえば、前述のように、1 人のユーザー クエリでエージェント メッセージの長い一覧をトリガーできます。通常は、複数のツール呼び出しが呼び出されます。
この例に示すように、エージェント ワークフローのこれらの側面を評価するために、これらの組み込みのエバリュエーター IntentResolution
、 ToolCallAccuracy
、 TaskAdherence
に対して、エージェント メッセージのサポートを有効にしました。 これらのエバリュエーターは、エージェントに固有のパラメーターとして tool_calls
または tool_definitions
を受け取ります。
エバリュエータ | query |
response |
tool_calls |
tool_definitions |
---|---|---|---|---|
IntentResolutionEvaluator |
必須: Union[str, list[Message]] |
必須: Union[str, list[Message]] |
なし | 任意: list[ToolCall] |
ToolCallAccuracyEvaluator |
必須: Union[str, list[Message]] |
任意: Union[str, list[Message]] |
任意: Union[dict, list[ToolCall]] |
必須: list[ToolDefinition] |
TaskAdherenceEvaluator |
必須: Union[str, list[Message]] |
必須: Union[str, list[Message]] |
なし | 任意: list[ToolCall] |
Message
:dict
ユーザーとのエージェントの対話を記述する openai スタイルのメッセージです。ここで、query
最初のメッセージとしてシステム メッセージを含める必要があります。ToolCall
:dict
エージェントとユーザーの対話中に呼び出されるツール呼び出しを指定します。ToolDefinition
: エージェントで使用できるツールの説明をdict
します。
ToolCallAccuracyEvaluator
の場合は、response
またはtool_calls
を指定する必要があります。
ここでは、単純なエージェント データとエージェント メッセージという 2 つのデータ形式の例をいくつか示します。 ただし、これらのエバリュエーターの固有の要件により、各エバリュエーターの可能な入力パスを示す サンプル ノートブック を参照することをお勧めします。
他の組み込みAI支援品質評価ツールと同様に、IntentResolutionEvaluator
とTaskAdherenceEvaluator
はリッカートスケール(1から5までの整数で、数字が大きいほど優れていることを示します)でスコアを出力します。 ToolCallAccuracyEvaluator
は、ユーザー クエリに基づいて行われたすべてのツール呼び出しの受け渡し率 (0 から 1 の間の浮動小数点数) を出力します。 明瞭さをさらに向上させるために、すべてのエバリュエータはバイナリしきい値を受け入れ、2 つの新しいキーを出力します。 二値化しきい値の場合、既定値が設定され、ユーザーはそれをオーバーライドできます。 2 つの新しいキーは次のとおりです。
{metric_name}_result
二値化の閾値に基づく "pass" または "fail" の文字列。{metric_name}_threshold
既定またはユーザーによって設定された数値の二値化しきい値。
シンプルなエージェント データ
単純なエージェント データ形式では、 query
と response
は単純な Python 文字列です。 例えば次が挙げられます。
import os
import json
from azure.ai.evaluation import AzureOpenAIModelConfiguration
from azure.identity import DefaultAzureCredential
from azure.ai.evaluation import IntentResolutionEvaluator, ResponseCompletenessEvaluator
model_config = AzureOpenAIModelConfiguration(
azure_endpoint=os.environ["AZURE_OPENAI_ENDPOINT"],
api_key=os.environ["AZURE_OPENAI_API_KEY"],
api_version=os.environ["AZURE_OPENAI_API_VERSION"],
azure_deployment=os.environ["MODEL_DEPLOYMENT_NAME"],
)
intent_resolution_evaluator = IntentResolutionEvaluator(model_config)
# Evaluating query and response as strings
# A positive example. Intent is identified and understood and the response correctly resolves user intent
result = intent_resolution_evaluator(
query="What are the opening hours of the Eiffel Tower?",
response="Opening hours of the Eiffel Tower are 9:00 AM to 11:00 PM.",
)
print(json.dumps(result, indent=4))
出力 (詳細については 出力形式 を参照してください):
{
"intent_resolution": 5.0,
"intent_resolution_result": "pass",
"intent_resolution_threshold": 3,
"intent_resolution_reason": "The response provides the opening hours of the Eiffel Tower, which directly addresses the user's query. The information is clear, accurate, and complete, fully resolving the user's intent.",
"additional_details": {
"conversation_has_intent": true,
"agent_perceived_intent": "inquire about the opening hours of the Eiffel Tower",
"actual_user_intent": "inquire about the opening hours of the Eiffel Tower",
"correct_intent_detected": true,
"intent_resolved": true
}
}
tool_calls
のtool_definitions
とToolCallAccuracyEvaluator
の例:
import json
query = "How is the weather in Seattle?"
tool_calls = [{
"type": "tool_call",
"tool_call_id": "call_CUdbkBfvVBla2YP3p24uhElJ",
"name": "fetch_weather",
"arguments": {
"___location": "Seattle"
}
},
{
"type": "tool_call",
"tool_call_id": "call_CUdbkBfvVBla2YP3p24uhElJ",
"name": "fetch_weather",
"arguments": {
"___location": "London"
}
}]
tool_definitions = [{
"name": "fetch_weather",
"description": "Fetches the weather information for the specified ___location.",
"parameters": {
"type": "object",
"properties": {
"___location": {
"type": "string",
"description": "The ___location to fetch weather for."
}
}
}
}]
response = tool_call_accuracy(query=query, tool_calls=tool_calls, tool_definitions=tool_definitions)
print(json.dumps(response, indent=4))
出力 (詳細については 出力形式 を参照してください):
{
"tool_call_accuracy": 0.5,
"tool_call_accuracy_result": "fail",
"tool_call_accuracy_threshold": 0.8,
"per_tool_call_details": [
{
"tool_call_accurate": true,
"tool_call_accurate_reason": "The TOOL CALL is directly relevant to the user's query, uses appropriate parameters, and the parameter values are correctly extracted from the conversation. It is likely to provide useful information to advance the conversation.",
"tool_call_id": "call_CUdbkBfvVBla2YP3p24uhElJ"
},
{
"tool_call_accurate": false,
"tool_call_accurate_reason": "The TOOL CALL is not relevant to the user's query about the weather in Seattle and uses a parameter value that is not present or inferred from the conversation.",
"tool_call_id": "call_CUdbkBfvVBla2YP3p24uhElJ"
}
]
}
エージェント メッセージ
エージェント メッセージ形式では、 query
と response
は openai スタイルのメッセージの一覧です。 具体的には、 query
最後のユーザー クエリに至るまでの過去のエージェントとユーザーの対話を実行し、(エージェントの) システム メッセージを一覧の一番上に必要とします。 response
は、最後のユーザー クエリに応答してエージェントの最後のメッセージを伝達します。 例:
import json
# user asked a question
query = [
{
"role": "system",
"content": "You are a friendly and helpful customer service agent."
},
# past interactions omitted
# ...
{
"createdAt": "2025-03-14T06:14:20Z",
"role": "user",
"content": [
{
"type": "text",
"text": "Hi, I need help with the last 2 orders on my account #888. Could you please update me on their status?"
}
]
}
]
# the agent emits multiple messages to fulfill the request
response = [
{
"createdAt": "2025-03-14T06:14:30Z",
"run_id": "0",
"role": "assistant",
"content": [
{
"type": "text",
"text": "Hello! Let me quickly look up your account details."
}
]
},
{
"createdAt": "2025-03-14T06:14:35Z",
"run_id": "0",
"role": "assistant",
"content": [
{
"type": "tool_call",
"tool_call_id": "tool_call_20250310_001",
"name": "get_orders",
"arguments": {
"account_number": "888"
}
}
]
},
# many more messages omitted
# ...
# here is the agent's final response
{
"createdAt": "2025-03-14T06:15:05Z",
"run_id": "0",
"role": "assistant",
"content": [
{
"type": "text",
"text": "The order with ID 123 has been shipped and is expected to be delivered on March 15, 2025. However, the order with ID 124 is delayed and should now arrive by March 20, 2025. Is there anything else I can help you with?"
}
]
}
]
# An example of tool definitions available to the agent
tool_definitions = [
{
"name": "get_orders",
"description": "Get the list of orders for a given account number.",
"parameters": {
"type": "object",
"properties": {
"account_number": {
"type": "string",
"description": "The account number to get the orders for."
}
}
}
},
# other tool definitions omitted
# ...
]
result = intent_resolution_evaluator(
query=query,
response=response,
# optionally provide the tool definitions
tool_definitions=tool_definitions
)
print(json.dumps(result, indent=4))
出力 (詳細については 出力形式 を参照してください):
{
"tool_call_accuracy": 0.5,
"tool_call_accuracy_result": "fail",
"tool_call_accuracy_threshold": 0.8,
"per_tool_call_details": [
{
"tool_call_accurate": true,
"tool_call_accurate_reason": "The TOOL CALL is directly relevant to the user's query, uses appropriate parameters, and the parameter values are correctly extracted from the conversation. It is likely to provide useful information to advance the conversation.",
"tool_call_id": "call_CUdbkBfvVBla2YP3p24uhElJ"
},
{
"tool_call_accurate": false,
"tool_call_accurate_reason": "The TOOL CALL is not relevant to the user's query about the weather in Seattle and uses a parameter value that is not present or inferred from the conversation.",
"tool_call_id": "call_CUdbkBfvVBla2YP3p24uhElJ"
}
]
}
この評価スキーマは、Azure AI Foundry Agent Service の外部でエージェント データを解析するのに役立ちます。これにより、エバリュエーターを使用してエージェント ワークフローの可観測性をサポートできます。
サンプル ノートブック
これで、次の各エバリュエーターのサンプルを試す準備ができました。