Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Agent Framework include un framework di valutazione predefinito che consente di misurare la qualità, la sicurezza e la correttezza degli agenti. È possibile eseguire controlli locali rapidi durante lo sviluppo, usare gli analizzatori basati sul cloud di Azure AI Foundry per la valutazione di livello di produzione o combinare entrambi in una singola esecuzione di valutazione.
Il framework di valutazione è progettato in base a alcuni principi chiave:
- Provider indipendente : i tipi di valutazione di base e le funzioni di orchestrazione funzionano con qualsiasi provider di valutazione.
- Zero attrito — passare da "Ho un agente" a "Ho risultati della valutazione" con codice minimo.
- Divulgazione progressiva : gli scenari semplici richiedono codice quasi zero. Gli scenari avanzati si basano sulle stesse primitive.
Concetti di base
Il framework di valutazione è basato su tre tipi:
| Tipo | Scopo |
|---|---|
| EvalItem | Un singolo elemento da valutare: incapsula l'intera conversazione e deriva query/risposta tramite una strategia di divisione. |
| Valutatore | Provider che assegna punteggi agli elementi, ovvero controlli locali, Azure AI Foundry o qualsiasi implementazione personalizzata. |
| EvalResults | Risultati aggregati da un'esecuzione di valutazione: conteggi di pass/fail, dettagli per elemento e collegamenti facoltativi del portale. |
In .NET, il framework di valutazione si basa su Microsoft. Extensions.AI.Evaluation. I valutatori implementano l'interfaccia IAgentEvaluator, e l'orchestrazione viene fornita tramite metodi di estensione su AIAgent e Run.
I tipi di base si trovano nello spazio dei nomi Microsoft.Agents.AI:
using Microsoft.Agents.AI;
In Python, il framework di valutazione fa parte del pacchetto principale agent_framework. I valutatori implementano il Evaluator protocollo e l'orchestrazione viene fornita tramite le funzioni evaluate_agent() e evaluate_workflow().
from agent_framework import (
evaluate_agent,
evaluate_workflow,
EvalItem,
EvalResults,
LocalEvaluator,
)
Analizzatori locali
LocalEvaluator esegue controlli in locale senza chiamate API, ideale per lo sviluppo del ciclo interno, i test CI preliminari e le iterazioni rapide. Accetta un numero qualsiasi di funzioni check e applica ognuna a ogni elemento.
Controlli predefiniti
Agent Framework viene fornito con controlli predefiniti per scenari comuni:
using Microsoft.Agents.AI;
var local = new LocalEvaluator(
EvalChecks.KeywordCheck("weather", "temperature"), // Response must contain these keywords
EvalChecks.ToolCalledCheck("get_weather") // Agent must have called this tool
);
Analizzatori di funzioni personalizzate
Usare FunctionEvaluator.Create() per utilizzare qualsiasi funzione come controllo del valutatore. Sono disponibili diverse sovraccarichi a seconda dei dati di cui hai bisogno.
using Microsoft.Agents.AI;
var local = new LocalEvaluator(
// Simple: check only the response text
FunctionEvaluator.Create("is_concise",
(string response) => response.Split(' ').Length < 500),
// With expected output: compare against ground truth
FunctionEvaluator.Create("mentions_city",
(string response, string? expectedOutput) =>
expectedOutput != null && response.Contains(expectedOutput, StringComparison.OrdinalIgnoreCase)),
// Full context: access the complete EvalItem
FunctionEvaluator.Create("used_search",
(EvalItem item) => item.Conversation.Any(m =>
m.Text?.Contains("search", StringComparison.OrdinalIgnoreCase) == true))
);
Controlli predefiniti
Agent Framework viene fornito con controlli predefiniti per scenari comuni:
| Controllo | Funzionamento |
|---|---|
keyword_check(*keywords) |
La risposta deve contenere tutte le parole chiave specificate |
tool_called_check(*tool_names) |
L'agente deve aver chiamato gli strumenti specificati |
tool_calls_present |
Tutti i expected_tool_calls nomi vengono visualizzati nella conversazione (non ordinati, extra OK) |
tool_call_args_match |
Le chiamate degli strumenti previste corrispondono al nome e agli argomenti (corrispondenza parziale sugli argomenti) |
from agent_framework import (
LocalEvaluator,
keyword_check,
tool_called_check,
tool_calls_present,
tool_call_args_match,
)
local = LocalEvaluator(
keyword_check("weather", "temperature"), # Response must contain these keywords
tool_called_check("get_weather"), # Agent must have called this tool
tool_calls_present, # All expected tool call names were made
tool_call_args_match, # Expected tool calls match on name + args
)
Analizzatori di funzioni personalizzate
Usare il decoratore @evaluator per incapsulare qualsiasi funzione come verifica del valutatore. I nomi dei parametri della funzione determinano i dati ricevuti da EvalItem:
from agent_framework import evaluator, LocalEvaluator
@evaluator
def is_concise(response: str) -> bool:
"""Check response is under 500 words."""
return len(response.split()) < 500
@evaluator
def mentions_city(response: str, expected_output: str) -> bool:
"""Check response contains the expected city name."""
return expected_output.lower() in response.lower()
@evaluator
def used_tools(conversation: list, tools: list) -> float:
"""Score based on tool usage. Returns 0.0–1.0 (>= 0.5 passes)."""
tool_calls = [c for m in conversation for c in (m.contents or []) if c.type == "function_call"]
return min(len(tool_calls) / max(len(tools), 1), 1.0)
local = LocalEvaluator(is_concise, mentions_city, used_tools)
Nomi di parametri supportati: query, response, expected_outputexpected_tool_calls, conversation, , tools, context.
Tipi restituiti: bool, float (≥ 0,5 = pass), dict con score o chiave passed o CheckResult. Le funzioni asincrone vengono gestite automaticamente.
valutatori di Azure AI Foundry
FoundryEvals si connette al servizio di valutazione di Azure AI Foundry per la valutazione LLM-as-judge basata sul cloud. I risultati sono visualizzabili nel portale foundry con dashboard e visualizzazioni di confronto.
using Microsoft.Agents.AI.AzureAI;
var foundry = new FoundryEvals(chatConfiguration, FoundryEvals.Relevance, FoundryEvals.Coherence);
from agent_framework.foundry import FoundryEvals
evals = FoundryEvals(
project_client=project_client,
model="gpt-4o",
evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.COHERENCE],
)
Per impostazione predefinita, FoundryEvals esegue gli analizzatori di pertinenza, coerenza e conformità delle attività . Quando gli elementi contengono definizioni degli strumenti, aggiunge automaticamente l'accuratezza delle chiamate degli strumenti.
Analizzatori disponibili
FoundryEvals fornisce costanti per tutti i nomi predefiniti dell'analizzatore:
| Categoria | Valutatori |
|---|---|
| Comportamento dell'agente |
intent_resolution, task_adherence, task_completiontask_navigation_efficiency |
| Utilizzo degli strumenti |
tool_call_accuracy, tool_selection, tool_input_accuracy, , tool_output_utilization, tool_call_success |
| Qualità |
coherence, fluency, relevance, groundedness, response_completenesssimilarity |
| Safety |
violence, sexual, self_harmhate_unfairness |
Annotazioni
FoundryEvals richiede un progetto Azure AI Foundry con una distribuzione del modello di intelligenza artificiale. Il model parametro specifica il modello da usare come giudice LLM.
Valutare un agente
Lo scenario di valutazione più semplice esegue un agente su query di test e assegna punteggi alle risposte. Fornire più query diverse per una valutazione statisticamente significativa.
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Foundry;
var foundry = new FoundryEvals(chatConfiguration, FoundryEvals.Relevance, FoundryEvals.Coherence);
AgentEvaluationResults results = await agent.EvaluateAsync(
new[]
{
"What's the weather in Seattle?",
"Plan a weekend trip to Portland",
"What restaurants are near Pike Place?",
},
foundry);
results.AssertAllPassed(); // Throws if any item failed
EvaluateAsync è un metodo di estensione in AIAgent. Esegue l'agente una volta per ogni query, converte ogni interazione in un oggetto EvalItem e passa il batch all'analizzatore.
from agent_framework import evaluate_agent
from agent_framework.foundry import FoundryEvals
evals = FoundryEvals(
project_client=project_client,
model="gpt-4o",
evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.COHERENCE],
)
results = await evaluate_agent(
agent=my_agent,
queries=[
"What's the weather in Seattle?",
"Plan a weekend trip to Portland",
"What restaurants are near Pike Place?",
],
evaluators=evals,
)
for r in results:
print(f"{r.provider}: {r.passed}/{r.total}")
r.raise_for_status() # Raises EvalNotPassedError if any item failed
evaluate_agent esegue l'agente una volta per ogni query, converte ogni interazione in un EvalItem oggetto e passa il batch al valutatore. Restituisce un EvalResults per valutatore provider.
Misurare la coerenza con le ripetizioni
Eseguire ogni query più volte per rilevare un comportamento non deterministico:
AgentEvaluationResults results = await agent.EvaluateAsync(
new[] { "What's the weather in Seattle?" },
foundry,
numRepetitions: 3); // Each query runs 3 times independently
// Results contain 3 items (1 query × 3 repetitions)
results = await evaluate_agent(
agent=my_agent,
queries=["What's the weather in Seattle?"],
evaluators=evals,
num_repetitions=3, # Each query runs 3 times independently
)
# Results contain 3 items (1 query × 3 repetitions)
Valutare con i risultati previsti
Fornire risposte previste in base alla verità per valutare la correttezza. Gli output previsti vengono associati in modo posizionato alle query:
AgentEvaluationResults results = await agent.EvaluateAsync(
new[] { "What's 2+2?", "Capital of France?" },
foundry,
expectedOutput: new[] { "4", "Paris" });
È anche possibile specificare le chiamate previste agli strumenti:
AgentEvaluationResults results = await agent.EvaluateAsync(
new[] { "What's the weather in NYC?" },
new LocalEvaluator(EvalChecks.ToolCalledCheck("get_weather")),
expectedToolCalls: new[]
{
new[] { new ExpectedToolCall("get_weather") },
});
from agent_framework import evaluate_agent, ExpectedToolCall
results = await evaluate_agent(
agent=my_agent,
queries=["What's 2+2?", "Capital of France?"],
expected_output=["4", "Paris"],
evaluators=evals,
)
È anche possibile specificare le chiamate previste agli strumenti:
results = await evaluate_agent(
agent=my_agent,
queries=["What's the weather in NYC?"],
expected_tool_calls=[ExpectedToolCall("get_weather", {"location": "NYC"})],
evaluators=local,
)
Valutare le risposte preesistenti
Quando si dispone già di risposte dell'agente dai log o dalle esecuzioni precedenti, valutarle direttamente senza eseguire nuovamente l'agente:
var response = await agent.RunAsync(new[] { new ChatMessage(ChatRole.User, "What's the weather?") });
AgentEvaluationResults results = await agent.EvaluateAsync(
new[] { response },
new[] { "What's the weather?" },
foundry);
from agent_framework import Message, evaluate_agent
response = await agent.run([Message("user", ["What's the weather?"])])
results = await evaluate_agent(
agent=agent,
responses=response,
queries="What's the weather?",
evaluators=evals,
)
Strategie di suddivisione delle conversazioni
Le conversazioni a più turni devono essere suddivise in parti di query e risposte per la valutazione. La modalità di suddivisione determina quello che stai valutando.
| Strategia | Comportamento | Ideale per |
|---|---|---|
| Ultimo turno (impostazione predefinita) | Divisione all'ultimo messaggio utente. Tutto fino a quel punto è il contesto della query; tutto ciò che segue è la risposta. | Qualità della risposta in un punto specifico |
| Completo | Il primo messaggio dell'utente è la query; l'intero resto è la risposta. | Completamento delle attività e traiettoria complessiva |
| Per iterazione | Ogni interazione utente-assistente viene valutata in modo indipendente, tenendo conto del contesto cumulativo. | Analisi con granularità fine |
// Full conversation as context
AgentEvaluationResults results = await agent.EvaluateAsync(
new[] { "Plan a 3-day trip to Paris" },
foundry,
splitter: ConversationSplitters.Full);
// Per-turn: each exchange scored independently
var items = EvalItem.PerTurnItems(conversation);
var perTurnResults = await evaluator.EvaluateAsync(items);
È anche possibile implementare un splitter personalizzato implementando IConversationSplitter:
public class SplitBeforeToolCall : IConversationSplitter
{
public (IReadOnlyList<ChatMessage> QueryMessages, IReadOnlyList<ChatMessage> ResponseMessages) Split(
IReadOnlyList<ChatMessage> conversation)
{
// Custom split logic
for (int i = 0; i < conversation.Count; i++)
{
if (conversation[i].Text?.Contains("tool_call") == true)
return (conversation.Take(i).ToList(), conversation.Skip(i).ToList());
}
return ConversationSplitters.LastTurn.Split(conversation);
}
}
from agent_framework import evaluate_agent, ConversationSplit
# Full conversation as context
results = await evaluate_agent(
agent=agent,
queries=["Plan a 3-day trip to Paris"],
evaluators=evals,
conversation_split=ConversationSplit.FULL,
)
# Per-turn: each exchange scored independently
from agent_framework import EvalItem
items = EvalItem.per_turn_items(conversation)
# Pass items directly to an evaluator
per_turn_results = await evaluator.evaluate(items)
È anche possibile fornire uno splitter personalizzato, ovvero qualsiasi funzione chiamabile che accetta una conversazione e restituisce (query_messages, response_messages):
def split_before_memory(conversation):
"""Split just before a memory-retrieval tool call."""
for i, msg in enumerate(conversation):
for c in msg.contents or []:
if c.type == "function_call" and c.name == "retrieve_memory":
return conversation[:i], conversation[i:]
# Fallback to default
return EvalItem._split_last_turn_static(conversation)
results = await evaluate_agent(
agent=agent,
queries=queries,
evaluators=evals,
conversation_split=split_before_memory,
)
Valutare i flussi di lavoro
Valutare i flussi di lavoro multi-agente con suddivisione per agente. Il framework estrae le interazioni di ogni sub-agente e le valuta singolarmente, insieme all'output complessivo del flusso di lavoro.
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.AzureAI;
Run run = await workflowRunner.RunAsync(workflow, "Plan a trip to Paris");
AgentEvaluationResults results = await run.EvaluateAsync(
new FoundryEvals(chatConfiguration, FoundryEvals.Relevance));
Console.WriteLine($"Overall: {results.Passed}/{results.Total}");
// Per-agent breakdown
if (results.SubResults != null)
{
foreach (var (name, sub) in results.SubResults)
{
Console.WriteLine($" {name}: {sub.Passed}/{sub.Total}");
}
}
results.AssertAllPassed();
from agent_framework import evaluate_workflow
from agent_framework.foundry import FoundryEvals
evals = FoundryEvals(project_client=project_client, model="gpt-4o")
result = await workflow.run("Plan a trip to Paris")
eval_results = await evaluate_workflow(
workflow=workflow,
workflow_result=result,
evaluators=evals,
)
for r in eval_results:
print(f"{r.provider}: {r.passed}/{r.total}")
for name, sub in r.sub_results.items():
print(f" {name}: {sub.passed}/{sub.total}")
È anche possibile passare queries direttamente e il framework eseguirà il flusso di lavoro per l'utente:
eval_results = await evaluate_workflow(
workflow=workflow,
queries=["Plan a trip to Paris", "Book a flight to London"],
evaluators=evals,
)
Combinare più analizzatori
Eseguire i controlli locali e gli analizzatori basati sul cloud insieme in una singola valutazione. Ogni analizzatore produce un proprio EvalResults.
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.AzureAI;
IReadOnlyList<AgentEvaluationResults> results = await agent.EvaluateAsync(
new[] { "What's the weather in Seattle?" },
evaluators: new IAgentEvaluator[]
{
new LocalEvaluator(
EvalChecks.KeywordCheck("weather"),
FunctionEvaluator.Create("is_helpful", (string r) => r.Split(' ').Length > 10)),
new FoundryEvals(chatConfiguration, FoundryEvals.Relevance, FoundryEvals.Coherence),
});
// results[0] = local evaluator results
// results[1] = Foundry evaluator results
foreach (var r in results)
{
Console.WriteLine($"{r.Provider}: {r.Passed}/{r.Total}");
}
from agent_framework import evaluate_agent, evaluator, LocalEvaluator, keyword_check
from agent_framework.foundry import FoundryEvals
@evaluator
def is_helpful(response: str) -> bool:
return len(response.split()) > 10
foundry = FoundryEvals(
project_client=project_client,
model="gpt-4o",
evaluators=[FoundryEvals.RELEVANCE, FoundryEvals.COHERENCE],
)
results = await evaluate_agent(
agent=agent,
queries=["What's the weather in Seattle?"],
evaluators=[
LocalEvaluator(is_helpful, keyword_check("weather")),
foundry,
],
)
# results[0] = local evaluator results
# results[1] = Foundry evaluator results
for r in results:
print(f"{r.provider}: {r.passed}/{r.total}")
Valutatori MEAI
Il framework di valutazione .NET si integra direttamente con Microsoft.Extensions.AI.Evaluation evaluators. Gli analizzatori di qualità e sicurezza di MEAI funzionano senza adattatori:
using Microsoft.Extensions.AI.Evaluation;
using Microsoft.Extensions.AI.Evaluation.Quality;
using Microsoft.Extensions.AI.Evaluation.Safety;
// Quality evaluators
AgentEvaluationResults results = await agent.EvaluateAsync(
new[] { "What's the weather?" },
new CompositeEvaluator(
new RelevanceEvaluator(),
new CoherenceEvaluator(),
new GroundednessEvaluator()),
chatConfiguration: new ChatConfiguration(evalClient));
// Safety evaluators
AgentEvaluationResults safetyResults = await agent.EvaluateAsync(
new[] { "What's the weather?" },
new ContentHarmEvaluator(),
chatConfiguration: new ChatConfiguration(evalClient));
Suggerimento
Quando si utilizzano gli analizzatori MEAI, fornire un parametro chatConfiguration con un client di chat configurato per il modello di valutazione. Questo client viene usato dagli analizzatori LLM-as-judge per assegnare punteggi alle risposte.
Annotazioni
Il supporto per questa funzionalità sarà presto disponibile. Vedere il repository di Agent Framework Go per lo stato più aggiornato.
Passaggi successivi
Contenuti correlati
- Osservabilità
- Sicurezza dell'agente
- Panoramica della valutazione Azure AI Foundry