Partager via


Évaluer vos agents IA (aperçu)

Remarque

Ce document fait référence au portail Microsoft Foundry (classique).

🔄 Accédez à la documentation Microsoft Foundry (nouveau) si vous utilisez le nouveau portail.

Remarque

Ce document fait référence au portail Microsoft Foundry (nouveau).

Important

Les éléments marqués (aperçu) dans cet article sont actuellement en aperçu public. Cette version préliminaire est fournie sans contrat de niveau de service, et nous la déconseillons pour les charges de travail en production. Certaines fonctionnalités peuvent être limitées ou non prises en charge. Pour plus d’informations, consultez Conditions d’utilisation supplémentaires pour les préversions de Microsoft Azure.

Les agents IA sont des assistants de productivité puissants qui créent des flux de travail pour les besoins de l’entreprise. Toutefois, l’observabilité est difficile en raison de leurs modèles d’interaction complexes. Dans cet article, vous allez apprendre à évaluer des agents Microsoft Foundry ou d’autres agents à l’aide d’évaluateurs intégrés.

Pour créer des applications agentiques prêtes pour la production et garantir l’observabilité et la transparence, les développeurs ont besoin d’outils pour évaluer non seulement la sortie finale des flux de travail d’un agent, mais également la qualité et l’efficacité des flux de travail.

Un événement comme un utilisateur interrogeant « météo demain » déclenche un flux de travail agentique. Pour produire une réponse finale, le flux de travail inclut le raisonnement par le biais d’intentions utilisateur, d’outils d’appel et d’utilisation de la génération augmentée par récupération.

Remarque

Le Kit de développement logiciel (SDK) Microsoft Foundry pour l’évaluation et le portail Foundry sont en préversion publique, mais les API sont généralement disponibles pour l’évaluation du modèle et du jeu de données (l’évaluation de l’agent reste en préversion publique). Le kit de développement logiciel (SDK) Azure AI Evaluation et les évaluateurs marqués (aperçu) dans cet article sont actuellement en aperçu public.

Remarque

Le Kit de développement logiciel (SDK) Microsoft Foundry pour l’évaluation et le portail Foundry sont en préversion publique, mais les API sont généralement disponibles pour l’évaluation du modèle et du jeu de données (l’évaluation de l’agent reste en préversion publique). Les évaluateurs marqués comme (aperçu) dans cet article sont actuellement en version préliminaire publique dans toutes les régions.

Dans ce processus, l’évaluation de chaque étape du flux de travail et de la qualité et de la sécurité de la sortie finale est cruciale. Nous formulons ces aspects d’évaluation dans les évaluateurs suivants pour les agents :

Évaluez d’autres aspects de la qualité et de la sécurité de vos flux de travail agentiques à l’aide de notre suite complète d’évaluateurs intégrés. En général, les agents émettent des messages d’agent. La transformation des messages de l’agent en données d’évaluation correctes pour nos évaluateurs peut être difficile. Si vous créez votre agent à l’aide du service Foundry Agent, vous pouvez l’évaluer sans interruption via notre support du convertisseur. Si vous générez votre agent en dehors du service Foundry Agent, vous pouvez toujours utiliser nos évaluateurs selon les besoins de votre flux de travail agentique, en analysant vos messages d’agent dans les formats de données requis. Consultez des exemples d’évaluation d’autres agents.

En guise de meilleure pratique, il est essentiel d’effectuer les opérations suivantes :

  • Évaluation du système : évaluer la qualité globale et l’efficacité du flux de travail de l’agent ; et
  • Évaluation du processus : évaluez les étapes d’appel de l’outil du flux de travail.

Consultez les évaluateurs d’agents pour obtenir des informations détaillées sur le cas d’usage des deux pratiques et un échantillon de chaque évaluateur d’agent.

Vous pouvez également évaluer d’autres aspects de la qualité et de la sécurité de vos flux de travail agentiques, à l’aide de notre suite complète d’évaluateurs intégrés ou d’écriture d’évaluateurs personnalisés.

Si vous créez des agents Foundry, vous pouvez les évaluer en toute transparence.

Si vous générez vos agents en dehors de Foundry, vous pouvez toujours utiliser nos évaluateurs en fonction de votre flux de travail agentique, en analysant vos messages d’agent dans les formats de données requis. Consultez les détails de l’évaluation d’autres agents.

Commencez

Installez le package des évaluateurs à partir du Kit de développement logiciel (SDK) d’évaluation Azure AI :

pip install azure-ai-evaluation

Installez le package à partir du Kit de développement logiciel (SDK) d’évaluation Azure AI :

pip install "azure-ai-projects>=2.0.0b1" azure-identity python-dotenv

Définissez ces variables d’environnement avec vos valeurs dans un .env fichier :

AZURE_AI_PROJECT_ENDPOINT="<your-endpoint>" # The Azure AI Project project endpoint, as found in the Home page of your Microsoft Foundry portal.
AZURE_AI_MODEL_DEPLOYMENT_NAME="<your-model-deployment-name>" # The deployment name of the AI model, as found under the "Build" page in the "Models" tab in your Foundry project.

Évaluer les agents Microsoft Foundry

Si vous utilisez le service de l’agent Foundry, vous pouvez évaluer vos agents sans interruption à l'aide de notre prise en charge des convertisseurs pour les agents Microsoft Foundry et les agents Semantic Kernel. Les évaluateurs suivants prennent en charge les données d’évaluation retournées par le convertisseur : IntentResolution, , ToolCallAccuracyTaskAdherence, Relevance, et Groundedness.

Remarque

Si vous créez d’autres agents qui génèrent un autre schéma, convertissez-les en schéma de message d’agent de style OpenAI général et utilisez les évaluateurs précédents. Plus généralement, si vous pouvez analyser les messages de l’agent dans les formats de données requis, vous pouvez également utiliser tous nos évaluateurs.

Prise en charge des modèles pour les évaluateurs assistés par l’IA

Les modèles de raisonnement AzureOpenAI et OpenAI et les modèles sans raisonnement prennent en charge le juge LLM selon les évaluateurs :

Programmes d’évaluation Modèles de raisonnement en tant que juge (exemple : modèles de série o d’Azure OpenAI / OpenAI) Modèles de non-raisonnement comme juge (exemple : gpt-4.1, gpt-4o, etc.) Pour activer
IntentResolution, TaskAdherence, ToolCallAccuracy, ResponseCompleteness, Coherence, Fluency, Similarity, Groundedness, Retrieval, Relevance Soutenu Soutenu Définir un paramètre is_reasoning_model=True supplémentaire dans l’initialisation des évaluateurs
Autres évaluateurs Non pris en charge Soutenu --

Pour une évaluation complexe qui nécessite un raisonnement affiné, utilisez un modèle de raisonnement fort comme 4.1-mini pour un équilibre des performances du raisonnement et de l’efficacité des coûts.

Prise en charge de l’évaluation des appels d’outil

ToolCallAccuracyEvaluator prend en charge l’évaluation dans Microsoft Foundry Agent pour les outils suivants :

  • Recherche de fichiers
  • Recherche d’IA Azure
  • Bing Grounding
  • Recherche personnalisée Bing
  • Mise à la terre de SharePoint
  • Interpréteur de code
  • Agent de données Fabric
  • OpenAPI
  • Outil de fonction (outils définis par l’utilisateur)

Toutefois, si vous utilisez un outil non pris en charge dans l’exécution de l’agent, l’évaluateur génère un « pass » et une raison pour laquelle l’évaluation des outils appelés n’est pas prise en charge, afin de faciliter le filtrage de ces cas. Pour activer l’évaluation, enveloppez les outils non pris en charge en tant qu’outils personnalisés.

Cet exemple montre comment générer et évaluer un agent Microsoft Foundry. Séparément de l’évaluation, le Service de l’agent Foundry nécessite pip install azure-ai-projects azure-identity, une chaîne de connexion de projet Foundry et les modèles pris en charge.

Créer des threads et des exécutions d’agent

Les agents peuvent utiliser des outils. Voici un exemple de création d’outils personnalisés pour l’agent à utiliser (à l’aide d’une fonction météo fictif comme exemple) :

from azure.ai.projects.models import FunctionTool, ToolSet
from typing import Set, Callable, Any
import json

# Define a 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.
    # In the following code snippet, we 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,
}

# Add tools that the agent will use. 
functions = FunctionTool(user_functions)

toolset = ToolSet()
toolset.add(functions)

AGENT_NAME = "Seattle Tourist Assistant"

Si vous utilisez un projet Foundry (non hub), créez un agent avec l’ensemble d’outils comme suit :

Remarque

Si vous utilisez un projet Basé sur Foundry Hub (qui prend uniquement en charge les versions inférieures de ), nous vous recommandons vivement de migrer vers azure-ai-projects<1.0.0b10 azure-ai-agents<1.0.0b10 avec un projet Foundry configuré pour la journalisation des résultats d’évaluation par lots.

Créez un agent avec l’ensemble d’outils comme suit :

import os
from azure.ai.projects import AIProjectClient
from azure.identity import DefaultAzureCredential
from dotenv import load_dotenv

load_dotenv()

# Create an Azure AI Client from an endpoint, copied from your Foundry project.
# You need to login to Azure subscription via Azure CLI and set the environment variables
# Foundry project endpoint, example: AZURE_AI_PROJECT=https://your-account.services.ai.azure.com/api/projects/your-project
project_endpoint = os.environ["AZURE_AI_PROJECT"]  # Ensure the PROJECT_ENDPOINT environment variable is set

# Create an AIProjectClient instance
project_client = AIProjectClient(
    endpoint=project_endpoint,
    credential=DefaultAzureCredential(),  # Use Azure Default Credential for authentication
)


# Create an agent with the toolset 
agent = project_client.agents.create_agent(
    model=os.environ["MODEL_DEPLOYMENT_NAME"],  # Model deployment name
    name="my-agent",  # Name of the agent
    instructions="You are a helpful agent",  # Instructions for the agent
    toolset=toolset
)
print(f"Created agent, ID: {agent.id}")

# Create a thread for communication
thread = project_client.agents.threads.create()
print(f"Created thread, ID: {thread.id}")

# Add a message to the thread
message = project_client.agents.messages.create(
    thread_id=thread.id,
    role="user",  # Role of the message sender
    content="What is the weather in Seattle today?",  # Message content
)
print(f"Created message, ID: {message['id']}")

# Create and process an agent run
run = project_client.agents.runs.create_and_process(thread_id=thread.id, agent_id=agent.id)
print(f"Run finished with status: {run.status}")

# Check if the run failed
if run.status == "failed":
    print(f"Run failed: {run.last_error}")

# Fetch and log all messages
messages = project_client.agents.messages.list(thread_id=thread.id)
for message in messages:
    print(f"Role: {message.role}, Content: {message.content}")

Évaluer une exécution unique de l’agent

Une fois que vous avez créé un agent, vous pouvez utiliser notre convertisseur pour transformer les données de thread de l’agent Microsoft Foundry en données d’évaluation requises que les évaluateurs peuvent comprendre.

import json, os
from azure.ai.evaluation import AIAgentConverter, IntentResolutionEvaluator

# Initialize the converter for Microsoft Foundry 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)

C’est tout ! converted_data contient toutes les entrées requises pour ces évaluateurs. Vous n’avez pas besoin de lire les exigences d’entrée pour chaque évaluateur ou d’effectuer un travail pour analyser les entrées. Sélectionnez votre évaluateur et appelez-le lors de cette exécution unique. Nous prenons en charge les modèles de raisonnement Azure OpenAI ou OpenAI et les modèles sans raisonnement pour le juge, en fonction des critères des évaluateurs :

Programmes d’évaluation Modèles de raisonnement en tant que juge (exemple : modèles de série o d’Azure OpenAI / OpenAI) Modèles de non-raisonnement comme juge (exemple : gpt-4.1, gpt-4o, etc.) Pour activer
Tous les évaluateurs de qualité à l’exception de GroundednessProEvaluator Soutenu Soutenu Définir un paramètre is_reasoning_model=True supplémentaire dans l’initialisation des évaluateurs
GroundednessProEvaluator L’utilisateur n’a pas besoin de prendre en charge le modèle L’utilisateur n’a pas besoin de prendre en charge le modèle --

Pour les tâches complexes qui nécessitent un raisonnement affiné pour l’évaluation, nous recommandons un modèle de raisonnement fort comme o3-mini ou les mini-modèles de série o publiés par la suite avec un équilibre des performances de raisonnement et de l’efficacité des coûts.

Nous avons configuré une liste d'évaluateurs de qualité et de sécurité dans quality_evaluators et safety_evaluators, et nous les référencerons dans (l’évaluation de plusieurs exécutions d’agents ou d’un thread).

# This is specific to agentic workflows.
from azure.ai.evaluation import IntentResolutionEvaluator, TaskAdherenceEvaluator, ToolCallAccuracyEvaluator 
# Other quality, risk, and safety metrics:
from azure.ai.evaluation import RelevanceEvaluator, CoherenceEvaluator, CodeVulnerabilityEvaluator, ContentSafetyEvaluator, IndirectAttackEvaluator, FluencyEvaluator
from azure.identity import DefaultAzureCredential

import os
from dotenv import load_dotenv
load_dotenv()

model_config = {
    "azure_deployment": os.getenv("AZURE_DEPLOYMENT_NAME"),
    "api_key": os.getenv("AZURE_API_KEY"),
    "azure_endpoint": os.getenv("AZURE_ENDPOINT"),
    "api_version": os.getenv("AZURE_API_VERSION"),
}

# example config for a reasoning model
reasoning_model_config = {
    "azure_deployment": "o3-mini",
    "api_key": os.getenv("AZURE_API_KEY"),
    "azure_endpoint": os.getenv("AZURE_ENDPOINT"),
    "api_version": os.getenv("AZURE_API_VERSION"),
}

# Evaluators you might want to use with reasoning models 
quality_evaluators = {evaluator.__name__: evaluator(model_config=reasoning_model_config, is_reasoning_model=True) for evaluator in [IntentResolutionEvaluator, TaskAdherenceEvaluator, ToolCallAccuracyEvaluator]}

# Other evaluators you might NOT want to use with reasoning models 
quality_evaluators.update({ evaluator.__name__: evaluator(model_config=model_config) for evaluator in [CoherenceEvaluator, FluencyEvaluator, RelevanceEvaluator]})

## Using Foundry (non-Hub) project endpoint, 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():
    result = evaluator(**converted_data)
    print(name)
    print(json.dumps(result, indent=4)) 

Format de sortie

Les évaluateurs de qualité assistées par l’IA retournent un résultat pour une paire de requêtes et de réponses. Le résultat est un dictionnaire qui inclut :

  • {metric_name}: fournit un score numérique, sur une échelle Likert (entier 1 à 5) ou un float compris entre 0 et 1.
  • {metric_name}_label: fournit une étiquette binaire (si la métrique génère naturellement un score binaire).
  • {metric_name}_reason: explique pourquoi un certain score ou une étiquette a été donné pour chaque point de données.
  • details : sortie optionnelle contenant des informations de débogage sur la qualité d’une seule exécution d’agent.

Pour améliorer la clarté, tous les évaluateurs acceptent un seuil binaire (sauf si leurs sorties sont déjà binaires) et génèrent deux nouvelles clés. Pour le seuil de binarisation, une valeur par défaut est définie, que l’utilisateur peut remplacer. Les deux nouvelles clés sont les suivantes :

  • {metric_name}_result : chaîne de caractères « pass » ou « fail » en fonction d’un seuil de binarisation.
  • {metric_name}_threshold: seuil de binarisation numérique défini par défaut ou par l’utilisateur.

Consultez l’exemple de sortie suivant pour certains évaluateurs :

{
    "intent_resolution": 5.0, # likert scale: 1-5 integer 
    "intent_resolution_threshold": 3,
    "intent_resolution_result": "pass", # pass because 5 > 3 the threshold
    "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."
}
{
    "task_adherence": 5.0, # likert scale: 1-5 integer 
    "task_adherence_threshold": 3,
    "task_adherence_result": "pass", # pass because 5 > 3 the threshold
    "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": 5,  # a score between 1-5, higher is better
    "tool_call_accuracy_threshold": 3,
    "tool_call_accuracy_result": "pass", # pass because 5 > 3 the threshold
    "details": { ... } # helpful details for debugging the tool calls made by the agent
}

Évaluer plusieurs exécutions ou threads d’agent

Pour évaluer plusieurs exécutions ou threads d’agent, utilisez l’API batch evaluate() pour l’évaluation asynchrone. Tout d’abord, convertissez vos données de thread d’agent en fichier à l’aide de notre outil de conversion :

import json
from azure.ai.evaluation import AIAgentConverter

# Initialize the converter.
converter = AIAgentConverter(project_client)

# Specify a file path to save the agent output (evaluation input data) to.
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}")

Avec les données d’évaluation préparées dans une ligne de code, vous pouvez sélectionner les évaluateurs pour évaluer la qualité de l’agent et soumettre une exécution d’évaluation par lot. Dans l’exemple suivant, nous faisons référence à la même liste d’évaluateurs de qualité et de sécurité dans la section Évaluer une seule exécution d’agentquality_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 Foundry project for rich visualization 
    azure_ai_project=os.environ.get("AZURE_AI_PROJECT"),  # example: https://your-account.services.ai.azure.com/api/projects/your-project
)
# Inspect the average scores at a high level.
print(response["metrics"])
# Use the URL to inspect the results on the UI.
print(f'Foundry URL: {response.get("studio_url")}')

Après avoir sélectionné l’URL, vous êtes redirigé vers Foundry. Affichez vos résultats d’évaluation dans votre projet Foundry et déboguez votre application. Utilisez les champs de motif et les résultats de succès/échec pour évaluer la qualité et la sécurité de vos applications. Vous pouvez exécuter et comparer plusieurs exécutions pour tester la régression ou les améliorations.

Utilisez la bibliothèque cliente du Kit de développement logiciel (SDK) Azure AI Evaluation pour évaluer vos agents Microsoft Foundry avec prise en charge du convertisseur, ce qui permet l’observabilité et la transparence dans les flux de travail de l’agent.

Vous pouvez évaluer de manière fluide les agents Foundry à l’aide d’évaluateurs dans les évaluateurs d’agents et les évaluateurs RAG. Cette section vous guide tout au long de la création d’un agent et de son évaluation.

Remarque

Si vous créez d’autres agents qui génèrent un autre schéma, convertissez-les en schéma de message d’agent de style OpenAI général et utilisez les évaluateurs précédents. Plus généralement, si vous pouvez analyser les messages de l’agent dans les formats de données requis, vous pouvez également utiliser tous nos évaluateurs.

Prerequisites

import json
from azure.ai.projects.models import Tool, FunctionTool

# Define a function tool for the model to use
func_tool = fetch_weather(
    name="fetch_weather",
    parameters={
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "The location to fetch weather for.",
            },
        },
        "required": ["location"],
        "additionalProperties": False,
    },
    description="Get the current weather for a location.",
    strict=True,
)

tools: list[Tool] = [func_tool]

# Define a custom Python function.
async 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.
    # In the following code snippet, we 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

Configurez un agent avec l’ensemble d’outils et créez une exécution de réponse à évaluer.

Créez un agent avec l’ensemble d’outils comme suit :

import os
import json
from dotenv import load_dotenv
from azure.ai.projects import AIProjectClient
from azure.ai.projects.models import PromptAgentDefinition
from azure.identity import DefaultAzureCredential
from openai.types.responses.response_input_param import FunctionCallOutput, ResponseInputParam

credential = DefaultAzureCredential()


project_client = AIProjectClient(
    endpoint=os.environ["AZURE_AI_PROJECT_ENDPOINT"],
    credential=DefaultAzureCredential(),
)

with project_client:

    openai_client = project_client.get_openai_client()

    agent = await project_client.agents.create_version(
        agent_name="MyAgent",
        definition=PromptAgentDefinition(
            model=os.environ["AZURE_AI_MODEL_DEPLOYMENT_NAME"],
            instructions="You are a helpful assistant that can use function tools.",
            tools=tools,
        ),
    )

    print(f"Agent created (id: {agent.id}, name: {agent.name}, version: {agent.version})")

    conversation = openai_client.conversations.create(
        items=[{"type": "message", "role": "user", "content": "What is the weather in Seattle?"}],
    )
    print(f"Created conversation with initial user message (id: {conversation.id})")

    response = openai_client.responses.create(
        conversation=conversation.id,
        extra_body={"agent": {"name": agent.name, "type": "agent_reference"}},
    )
    print(f"Response output: {response.output_text} (id: {response.id})")


    # Now create evaluation for the response
    data_source_config = {"type": "azure_ai_source", "scenario": "responses"}

    # add your desired evaluators here
    testing_criteria = [
        {"type": "azure_ai_evaluator", "name": "task_adherence", "evaluator_name": "builtin.task_adherence"},
        {"type": "azure_ai_evaluator", "name": "groundedness", "evaluator_name": "builtin.groundedness"},
    ]
    eval_object = openai_client.evals.create(
        name="Agent Response Evaluation",
        data_source_config=data_source_config,
        testing_criteria=testing_criteria,
    )
    print(f"Evaluation created (id: {eval_object.id}, name: {eval_object.name})")

    data_source = {
        "type": "azure_ai_responses",
        "item_generation_params": {
            "type": "response_retrieval",
            "data_mapping": {"response_id": "{{item.resp_id}}"},
            "source": {"type": "file_content", "content": [{"item": {"resp_id": response.id}}]},
        },
    }

    response_eval_run = openai_client.evals.runs.create(
        eval_id=eval_object.id, name=f"Evaluation Run for Agent {agent.name}", data_source=data_source
    )
    print(f"Evaluation run created (id: {response_eval_run.id})")

    while response_eval_run.status not in ["completed", "failed"]:
        response_eval_run = openai_client.evals.runs.retrieve(run_id=response_eval_run.id, eval_id=eval_object.id)
        print(f"Waiting for eval run to complete... current status: {response_eval_run.status}")
        time.sleep(5)

    if response_eval_run.status == "completed":
        print("\n✓ Evaluation run completed successfully!")
        print(f"Result Counts: {response_eval_run.result_counts}")
        print(f"Eval Run Report URL: {response_eval_run.report_url}")
        output_items = list(
            openai_client.evals.runs.output_items.list(run_id=response_eval_run.id, eval_id=eval_object.id)
        )
        print(f"\nOUTPUT ITEMS (Total: {len(output_items)})")
        print(f"{'-'*60}")
        pprint(output_items)
        print(f"{'-'*60}")
    else:
        print("\n✗ Evaluation run failed.")

Interprétation des résultats

Pour un exemple de données unique, tous les évaluateurs génèrent toujours le schéma suivant :

  • Étiquette : étiquette binaire « pass » ou « fail », similaire à la sortie d’un test unitaire. Utilisez ce résultat pour faciliter les comparaisons entre les évaluateurs.
  • Score : score de l’échelle naturelle de chaque évaluateur. Certains évaluateurs utilisent une grille affinée, un scoring sur une échelle de 5 points (évaluateurs de qualité) ou une échelle de 7 points (évaluateurs de sécurité du contenu). D’autres, comme les évaluateurs de similarité textuelle, utilisent des scores F1, qui sont flottants entre 0 et 1. Le champ « label » binarise tout « score » non binaire pour « passer » ou « échouer » en fonction du « seuil ».
  • Seuil : tous les scores non binaires sont binarisés pour « passer » ou « échouer » en fonction d’un seuil par défaut, que vous pouvez remplacer dans l’expérience du Kit de développement logiciel (SDK).
  • Motif : Pour améliorer l’intelligibilité, tous les évaluateurs LLM-juge génèrent également un champ de raisonnement pour expliquer pourquoi un certain score est donné.
  • Détails : (facultatif) Pour certains évaluateurs, tels que tool_call_accuracy, il peut y avoir un champ ou des indicateurs « détails » qui contiennent des informations supplémentaires pour aider les utilisateurs à déboguer leurs applications. Pour obtenir des résultats agrégés sur plusieurs exemples de données (un jeu de données), le taux moyen des exemples avec un « réussi » forme le taux de réussite pour ce jeu de données.

Après l’URL, vous êtes redirigé vers Foundry. Vous pouvez afficher vos résultats d’évaluation dans votre projet Foundry et déboguer votre application. Utilisez les champs « raison » et les critères de réussite/échec pour évaluer la qualité et la sécurité de vos applications. Vous pouvez exécuter et comparer plusieurs exécutions pour tester la régression ou les améliorations.

Utilisez la bibliothèque de client Python du Kit de développement logiciel (SDK) Microsoft Foundry pour évaluer vos agents Microsoft Foundry, ce qui permet l’observabilité et la transparence dans les flux de travail de l’agent.

Évaluer d’autres agents

Si vous utilisez des agents en dehors du service d’agent, vous pouvez toujours les évaluer en préparant les données appropriées pour les évaluateurs de votre choix.

Les agents émettent généralement des messages pour interagir avec un utilisateur ou d’autres agents. Les évaluateurs intégrés acceptent des types de données simples tels que des chaînes dans query, responseet ground_truth en fonction des exigences d’entrée de données à tour unique. Toutefois, l’extraction de ces types de données simples à partir de messages d’agent peut être difficile en raison des modèles d’interaction complexes des agents et des différences de framework. Par exemple, une requête utilisateur unique peut déclencher une longue liste de messages d’agent, généralement avec plusieurs appels d’outils appelés.

Les agents émettent généralement des messages pour interagir avec un utilisateur ou d’autres agents. Nos évaluateurs intégrés peuvent accepter des types de données simples tels que des chaînes dans query, responseet ground_truth en fonction des exigences d’entrée de données à tour unique. Toutefois, il peut s’avérer difficile d’extraire ces types de données simples à partir de messages d’agent, en raison des modèles d’interaction complexes des agents et des différences de framework. Par exemple, une requête utilisateur unique peut déclencher une longue liste de messages d’agent, généralement avec plusieurs appels d’outils appelés. Nous affichons des exemples de schéma de message d’agent dans le schéma de message agent avec tool_definitions et tool_calls incorporés dans query et response.

Comme illustré dans l’exemple suivant, nous allons activer la prise en charge des messages de l’agent pour les évaluateurs intégrés suivants afin d’évaluer ces aspects du flux de travail agentique. Ces évaluateurs peuvent prendre tool_calls ou tool_definitions en tant que paramètres uniques aux agents lors de l’évaluation des agents.

Évaluateur query response tool_calls tool_definitions
IntentResolutionEvaluator Obligatoire: Union[str, list[Message]] Obligatoire: Union[str, list[Message]] Ne s’applique pas Optionnel: list[ToolCall]
ToolCallAccuracyEvaluator Obligatoire: Union[str, list[Message]] Optionnel: Union[str, list[Message]] Optionnel: Union[dict, list[ToolCall]] Obligatoire: list[ToolDefinition]
TaskAdherenceEvaluator Obligatoire: Union[str, list[Message]] Obligatoire: Union[str, list[Message]] Ne s’applique pas Optionnel: list[ToolCall]
GroundednessEvaluator Obligatoire: Union[str, list[Message]] Obligatoire: Union[str, list[Message]] Ne s’applique pas Obligatoire: list[ToolCall]
  • Message: dict message de style OpenAI qui décrit les interactions de l’agent avec un utilisateur, où le query message système doit inclure un message système comme premier message.
  • ToolCall: dict qui spécifie les appels d’outil appelés pendant les interactions de l’agent avec un utilisateur.
  • ToolDefinition: dict qui décrit les outils disponibles pour un agent.

Pour ToolCallAccuracyEvaluator, vous devez fournir soit response soit tool_calls.

GroundednessEvaluator exige tool_definitions d’évaluer le fondement des réponses de l’agent par rapport aux résultats des outils que l’agent reçoit.

Les exemples suivants montrent les deux formats de données : les données d'agent simples et les messages d'agent. Toutefois, en raison des exigences uniques de ces évaluateurs, nous vous recommandons de faire référence aux exemples de notebooks, qui illustrent les chemins d’entrée possibles pour chaque évaluateur.

Tous les évaluateurs de qualité intégrés assistés par l’IA produisent un résultat de réussite ou d’échec pour chaque entrée.

Données d’agent simples

Au format de données d'agent simple, query et response sont des chaînes Python simples. Par exemple:

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)

# Evaluate the query and response as strings.
# The following is 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))

Consultez la sortie suivante (reportez-vous au format de sortie pour plus d’informations) :

{
    "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.",
}

Appels et définitions de l’outil d'agent

Consultez les exemples suivants de tool_calls et tool_definitions pour 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."
                            }
                        }
                    }
                }]

from azure.ai.evaluation import ToolCallAccuracyEvaluator

tool_call_accuracy = ToolCallAccuracyEvaluator(model_config) # reuse the config defined above
response = tool_call_accuracy(query=query, tool_calls=tool_calls, tool_definitions=tool_definitions)
print(json.dumps(response, indent=4))

Consultez la sortie suivante ( format de sortie de référence pour plus d’informations) :

{
    "tool_call_accuracy": 3,  # a score between 1-5, higher is better
    "tool_call_accuracy_result": "fail",
    "tool_call_accuracy_threshold": 4,
    "details": { ... } # helpful details for debugging the tool calls made by the agent
}

Consultez les exemples suivants de tool_calls et tool_definitions pour tool_call_accuracy :

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."
                            }
                        }
                    }
                }]

Schéma de message de l’agent

Dans le format de messages de l’agent, query et response constituent une liste de messages de style OpenAI. Plus précisément, query porte les interactions passées de l’agent-utilisateur menant à la dernière requête utilisateur et nécessite le message système (de l’agent) en haut de la liste. response porte le dernier message de l’agent en réponse à la dernière requête utilisateur.

Le format d’entrée attendu pour les évaluateurs est une liste Python de messages comme suit :

[
  {
    "role": "system" | "user" | "assistant" | "tool",
    "createdAt": "ISO 8601 timestamp",     // Optional for 'system'
    "run_id": "string",                    // Optional, only for assistant/tool in tool call context
    "tool_call_id": "string",              // Optional, only for tool/tool_result
    "name": "string",                      // Present if it's a tool call
    "arguments": { ... },                  // Parameters passed to the tool (if tool call)
    "content": [
      {
        "type": "text" | "tool_call" | "tool_result",
        "text": "string",                  // if type == text
        "tool_call_id": "string",         // if type == tool_call
        "name": "string",                 // tool name if type == tool_call
        "arguments": { ... },             // tool args if type == tool_call
        "tool_result": { ... }            // result if type == tool_result
      }
    ]
  }
]

Exemples d’objets de requête et de réponse :

query = [
    {
        "role": "system",
        "content": "You are an AI assistant interacting with Azure Maps services to serve user requests."
    },
    {
        "createdAt": "2025-04-25T23:55:43Z",
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": "Find the address for coordinates 41.8781,-87.6298."
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:45Z",
        "run_id": "run_DGE8RWPS8A9SmfCg61waRx9u",
        "role": "assistant",
        "content": [
            {
                "type": "tool_call",
                "tool_call_id": "call_nqNyhOFRw4FmF50jaCCq2rDa",
                "name": "azure_maps_reverse_address_search",
                "arguments": {
                    "lat": "41.8781",
                    "lon": "-87.6298"
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:47Z",
        "run_id": "run_DGE8RWPS8A9SmfCg61waRx9u",
        "tool_call_id": "call_nqNyhOFRw4FmF50jaCCq2rDa",
        "role": "tool",
        "content": [
            {
                "type": "tool_result",
                "tool_result": {
                    "address": "300 South Federal Street, Chicago, IL 60604",
                    "position": {
                        "lat": "41.8781",
                        "lon": "-87.6298"
                    }
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:48Z",
        "run_id": "run_DGE8RWPS8A9SmfCg61waRx9u",
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "The address for the coordinates 41.8781, -87.6298 is 300 South Federal Street, Chicago, IL 60604."
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:50Z",
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": "What timezone corresponds to 41.8781,-87.6298?"
            }
        ]
    },
]

response = [
    {
        "createdAt": "2025-04-25T23:55:52Z",
        "run_id": "run_DmnhUGqYd1vCBolcjjODVitB",
        "role": "assistant",
        "content": [
            {
                "type": "tool_call",
                "tool_call_id": "call_qi2ug31JqzDuLy7zF5uiMbGU",
                "name": "azure_maps_timezone",
                "arguments": {
                    "lat": 41.878100000000003,
                    "lon": -87.629800000000003
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:54Z",
        "run_id": "run_DmnhUGqYd1vCBolcjjODVitB",
        "tool_call_id": "call_qi2ug31JqzDuLy7zF5uiMbGU",
        "role": "tool",
        "content": [
            {
                "type": "tool_result",
                "tool_result": {
                    "ianaId": "America/Chicago",
                    "utcOffset": None,
                    "abbreviation": None,
                    "isDaylightSavingTime": None
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:55Z",
        "run_id": "run_DmnhUGqYd1vCBolcjjODVitB",
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "The timezone for the coordinates 41.8781, -87.6298 is America/Chicago."
            }
        ]
    }
]

Remarque

L’évaluateur affiche un avertissement si la requête (l’historique des conversations jusqu’à l’exécution actuelle) ou la réponse de l’agent (la réponse à la requête) n’est pas au format attendu.

Consultez un exemple d’évaluation des messages de l’agent avec ToolCallAccuracyEvaluator:

import json

# The user asked a question.
query = [
    {
        "role": "system",
        "content": "You are a friendly and helpful customer service agent."
    },
    # Past interactions are 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 are 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 are omitted. 
    # ...
]

result = tool_call_accuracy(
    query=query,
    response=response,
    tool_definitions=tool_definitions 
)
print(json.dumps(result, indent=4))

Consultez la sortie suivante ( format de sortie de référence pour plus d’informations) :

{
    "tool_call_accuracy": 2,  # a score between 1-5, higher is better
    "tool_call_accuracy_result": "fail",
    "tool_call_accuracy_threshold": 3,
    "details": { ... } # helpful details for debugging the tool calls made by the agent
}
query = [
    {
        "role": "system",
        "content": "You are an AI assistant interacting with Azure Maps services to serve user requests."
    },
    {
        "createdAt": "2025-04-25T23:55:43Z",
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": "Find the address for coordinates 41.8781,-87.6298."
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:45Z",
        "run_id": "run_DGE8RWPS8A9SmfCg61waRx9u",
        "role": "assistant",
        "content": [
            {
                "type": "tool_call",
                "tool_call_id": "call_nqNyhOFRw4FmF50jaCCq2rDa",
                "name": "azure_maps_reverse_address_search",
                "arguments": {
                    "lat": "41.8781",
                    "lon": "-87.6298"
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:47Z",
        "run_id": "run_DGE8RWPS8A9SmfCg61waRx9u",
        "tool_call_id": "call_nqNyhOFRw4FmF50jaCCq2rDa",
        "role": "tool",
        "content": [
            {
                "type": "tool_result",
                "tool_result": {
                    "address": "300 South Federal Street, Chicago, IL 60604",
                    "position": {
                        "lat": "41.8781",
                        "lon": "-87.6298"
                    }
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:48Z",
        "run_id": "run_DGE8RWPS8A9SmfCg61waRx9u",
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "The address for the coordinates 41.8781, -87.6298 is 300 South Federal Street, Chicago, IL 60604."
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:50Z",
        "role": "user",
        "content": [
            {
                "type": "text",
                "text": "What timezone corresponds to 41.8781,-87.6298?"
            }
        ]
    },
]

response = [
    {
        "createdAt": "2025-04-25T23:55:52Z",
        "run_id": "run_DmnhUGqYd1vCBolcjjODVitB",
        "role": "assistant",
        "content": [
            {
                "type": "tool_call",
                "tool_call_id": "call_qi2ug31JqzDuLy7zF5uiMbGU",
                "name": "azure_maps_timezone",
                "arguments": {
                    "lat": 41.878100000000003,
                    "lon": -87.629800000000003
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:54Z",
        "run_id": "run_DmnhUGqYd1vCBolcjjODVitB",
        "tool_call_id": "call_qi2ug31JqzDuLy7zF5uiMbGU",
        "role": "tool",
        "content": [
            {
                "type": "tool_result",
                "tool_result": {
                    "ianaId": "America/Chicago",
                    "utcOffset": None,
                    "abbreviation": None,
                    "isDaylightSavingTime": None
                }
            }
        ]
    },
    {
        "createdAt": "2025-04-25T23:55:55Z",
        "run_id": "run_DmnhUGqYd1vCBolcjjODVitB",
        "role": "assistant",
        "content": [
            {
                "type": "text",
                "text": "The timezone for the coordinates 41.8781, -87.6298 is America/Chicago."
            }
        ]
    }
]

Remarque

L’évaluateur lève un avertissement indiquant qu’il ne peut pas analyser la requête (l’historique des conversations jusqu’à l’exécution actuelle) ou la réponse de l’agent (la réponse à la requête) lorsque leur format n’est pas celui attendu.

Autres exemples de messages d’agent :

import json

# The user asked a question.
query = [
    {
        "role": "system",
        "content": "You are a friendly and helpful customer service agent."
    },
    # Past interactions are 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 are 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 are omitted. 
    # ...
]

Ce schéma d’évaluation permet d’analyser les données de l’agent en dehors du service d’agent, ce qui permet d’utiliser des évaluateurs intégrés pour prendre en charge l’observabilité dans les flux de travail de l’agent.

Exemples de notebooks

Essayez un exemple pour chacun de ces évaluateurs :

Essayez un échantillon pour chacun de ces évaluateurs dans le répertoire d'échantillons.