Evaluatie

Agent Framework bevat een ingebouwd evaluatieframework waarmee u de kwaliteit, veiligheid en juistheid van de agent kunt meten. U kunt tijdens de ontwikkeling snel lokale controles uitvoeren, de cloud-evaluatieprogramma's van Azure AI Foundry gebruiken voor evaluatie op productieniveau of beide combineren in één evaluatieuitvoering.

Het evaluatieframework is ontworpen rond enkele belangrijke principes:

  • Providerneutraal: kernevaluatietypen en indelingsfuncties werken samen met elke evaluatieprovider.
  • Geen wrijving : ga van 'Ik heb een agent' naar 'Ik heb evaluatieresultaten' met minimale code.
  • Progressieve openbaarmaking : eenvoudige scenario's vereisen bijna nul code. Geavanceerde scenario's bouwen voort op dezelfde primitieven.

Basisconcepten

Het evaluatieframework is gebaseerd op drie typen:

Typ Purpose
EvalItem Eén item om te evalueren — omvat het volledige gesprek en leidt query/antwoord af via een gesplitste strategie.
Evaluator Een provider die items beoordeelt: lokale controles, Azure AI Foundry of een aangepaste implementatie.
EvalResults Geaggregeerde resultaten van een evaluatieuitvoering: aantal geslaagde/mislukte pogingen, detailgegevens per item en optionele portalkoppelingen.

In .NET bouwt het evaluatieframework voort op Microsoft. Extensions.AI.Evaluation. Evaluatoren implementeren de IAgentEvaluator-interface en de orkestratie wordt geleverd via extensiemethoden op AIAgent en Run.

De kerntypen bevinden zich in de naamruimte Microsoft.Agents.AI:

using Microsoft.Agents.AI;

In Python maakt het evaluatieframework deel uit van het kernpakket agent_framework. Evaluators implementeren het Evaluator-protocol en orkestratie wordt geleverd via evaluate_agent()- en evaluate_workflow()-functies.

from agent_framework import (
    evaluate_agent,
    evaluate_workflow,
    EvalItem,
    EvalResults,
    LocalEvaluator,
)

Lokale beoordelaars

LocalEvaluator voert controles lokaal uit zonder API-aanroepen — ideaal voor inner-loop ontwikkeling, CI rooktests en snelle iteratie. Het accepteert een willekeurig aantal controlefuncties en past elke functie toe op elk item.

Ingebouwde controles

Agent Framework wordt geleverd met ingebouwde controles op veelvoorkomende scenario's:

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
);

Aangepaste functie-evaluators

Gebruik FunctionEvaluator.Create() om elke functie te omhullen als een controlemiddel. Er zijn meerdere overbelastingen beschikbaar, afhankelijk van de gegevens die u nodig hebt:

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))
);

Ingebouwde controles

Agent Framework wordt geleverd met ingebouwde controles op veelvoorkomende scenario's:

Controle Wat het doet
keyword_check(*keywords) Antwoord moet alle opgegeven trefwoorden bevatten
tool_called_check(*tool_names) Agent moet de opgegeven hulpprogramma's hebben aangeroepen
tool_calls_present Alle expected_tool_calls namen worden weergegeven in het gesprek (ongeordeerd, extra's OK)
tool_call_args_match Verwachte functie roept overeenkomst op naam en argumenten aan (subsetovereenkomst op args)
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
)

Aangepaste functie-evaluators

Gebruik de @evaluator decorator om elke functie in te pakken als een evaluatiecontrole. De parameternamen van de functie bepalen welke gegevens deze van EvalItem ontvangen.

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)

Ondersteunde parameternamen: query, response, expected_output, expected_tool_calls, conversation, , tools, . context

Retourtypen: bool, float (≥ 0,5 = pass), dict met score of passed sleutel of CheckResult. Asynchrone functies worden automatisch verwerkt.

Azure AI Foundry beoordelaars

FoundryEvals maakt verbinding met de evaluatieservice van Azure AI Foundry voor cloudgebaseerde LLM-as-judge-beoordeling. Resultaten zijn zichtbaar in de Foundry-portal met dashboards en vergelijkingsweergaven.

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],
)

FoundryEvals Standaard worden relevantie- en coherentie- en taakvervolgings evaluators uitgevoerd. Wanneer items hulpprogrammadefinities bevatten, wordt de nauwkeurigheid van de toolaanroep automatisch toegevoegd.

Beschikbare evaluatoren

FoundryEvals biedt constanten voor alle ingebouwde evaluatornamen:

Categorie Beoordelaars
Agentgedrag intent_resolution,task_adherence,task_completion,task_navigation_efficiency
Gebruik van hulpprogramma's tool_call_accuracy tool_selection, tool_input_accuracy, tool_output_utilizationtool_call_success
Kwaliteit coherence, fluency, relevance, groundedness, response_completeness, similarity
Safety violence,sexual,self_harm,hate_unfairness

Opmerking

FoundryEvals vereist een Azure AI Foundry-project met een AI-modelimplementatie. De model parameter geeft aan welk model moet worden gebruikt als de LLM-rechter.

Een agent evalueren

In het eenvoudigste evaluatiescenario wordt een agent uitgevoerd tegen testvragen en worden de antwoorden beoordeeld. Bied meerdere verschillende query's voor statistisch zinvolle evaluatie.

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 is een extensiemethode op AIAgent. De agent wordt eenmaal per query uitgevoerd, elke interactie wordt geconverteerd naar een EvalItemen de batch wordt doorgegeven aan de evaluator.

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 voert de agent eenmaal per query uit, converteert elke interactie naar een EvalItemen geeft de batch door aan de evaluator. Er wordt één EvalResults per evaluatorprovider geretourneerd.

Consistentie meten met herhalingen

Voer elke query meerdere keren uit om niet-deterministisch gedrag te detecteren:

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)

Evalueren met verwachte uitvoeringen

Geef referentie-antwoorden om de juistheid te evalueren. Verwachte uitvoer wordt positioneel gekoppeld aan query's:

AgentEvaluationResults results = await agent.EvaluateAsync(
    new[] { "What's 2+2?", "Capital of France?" },
    foundry,
    expectedOutput: new[] { "4", "Paris" });

U kunt ook verwachte hulpprogramma-aanroepen opgeven:

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,
)

U kunt ook verwachte hulpprogramma-aanroepen opgeven:

results = await evaluate_agent(
    agent=my_agent,
    queries=["What's the weather in NYC?"],
    expected_tool_calls=[ExpectedToolCall("get_weather", {"location": "NYC"})],
    evaluators=local,
)

Bestaande antwoorden evalueren

Wanneer u al agentreacties van logboeken of eerdere uitvoeringen hebt, evalueert u deze rechtstreeks zonder de agent opnieuw uit te voeren:

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ën voor het splitsen van gesprekken

Gesprekken met meerdere beurten moeten worden gesplitst in query- en antwoordhelften voor evaluatie. Hoe u splitst , bepaalt wat u evalueert.

Strategie Gedrag Ideaal voor
Laatste beurt (standaard) Splitsen bij het laatste gebruikersbericht. Alles tot dat punt is querycontext; alles daarna is het antwoord. Antwoordkwaliteit op een specifiek punt
Vol Eerste gebruikersbericht is de query; het resterende deel is het antwoord. Taakvoltooiing en algemeen verloop
Per beurt Elke gebruiker→assistant-uitwisseling wordt onafhankelijk beoordeeld met in achtneming van de cumulatieve context. Gedetailleerde analyse
// 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);

U kunt ook een aangepaste splitsfunctie implementeren door het volgende te implementeren 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)

U kunt ook een aangepaste splitsfunctie opgeven — elke functie die een gesprek accepteert en (query_messages, response_messages) retourneert.

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,
)

Werkstromen evalueren

Evalueer werkstromen met meerdere agents met uitsplitsing per agent. Het framework extraheert de interacties van elke subagent en evalueert deze afzonderlijk, samen met de algehele uitvoer van de werkstroom.

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}")

U kunt ook rechtstreeks doorgeven queries en het framework voert de werkstroom voor u uit:

eval_results = await evaluate_workflow(
    workflow=workflow,
    queries=["Plan a trip to Paris", "Book a flight to London"],
    evaluators=evals,
)

Meerdere evaluators combineren

Voer lokale controles en cloudevaluaties samen uit in één evaluatie. Elke evaluator produceert een eigen 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}")

MEAI-evaluators

Het .NET evaluatieframework kan rechtstreeks worden geïntegreerd met Microsoft. Extensions.AI.Evaluation evaluators. Kwaliteits- en veiligheids evaluators van MEAI werken zonder adapter:

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));

Aanbeveling

Wanneer u MEAI-evaluators gebruikt, geeft u een chatConfiguration parameter op met een chatclient die is geconfigureerd voor het evaluatiemodel. Deze client wordt gebruikt door de LLM-as-judge-evaluatoren om antwoorden te beoordelen.

Opmerking

Ondersteuning voor deze functie is binnenkort beschikbaar. Zie de opslagplaats Agent Framework Go voor de meest recente status.

Volgende stappen