Muistiinpano
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää kirjautua sisään tai vaihtaa hakemistoa.
Tämän sivun käyttö edellyttää valtuutusta. Voit yrittää vaihtaa hakemistoa.
Important
Items marked (preview) in this article are currently in public preview. This preview is provided without a service-level agreement, and we don't recommend it for production workloads. Certain features might not be supported or might have constrained capabilities. For more information, see Supplemental Terms of Use for Microsoft Azure Previews.
Use the azd ai eval extension to add a measured quality loop to an agent built with Microsoft Foundry. You scaffold an evaluation next to your project, optionally generate a dataset and a rubric evaluator, run the evaluation against your agent, and read the results without leaving the terminal.
The same evaluation can run from a pipeline, and --fail-on turns its results into a build gate.
This article covers the first evaluation with azd ai eval init and azd ai eval run start.
Prerequisites
- An Azure subscription with access to Microsoft Foundry.
- The Azure Developer CLI (
azd), version 1.27.1 or later. For installation instructions, see Install the Azure Developer CLI. - The
azd ai evalextension:azd extension install azure.ai.evaluations. Runazd extension list --installedto check the installed version. - An authenticated
azdsession. To check your authentication status, runazd auth status. If you're not signed in, runazd auth login. - The
Foundry Userrole on the Foundry resource (previously namedAzure AI User). For more information, see Role-based access control for Microsoft Foundry. - A Foundry project, and an agent to evaluate. To let
initdetect the target, the agent must be declared as a service in the project'sazure.yaml, asazd ai agent initdoes. Otherwise name it with--target. For hosted agents, see Hosted agents. - A model deployment that supports chat completions in the same project. The graders judge with it.
- Optional: a JSONL dataset of representative examples, if you don't want
generateto synthesize one.
How azd evaluations work
An evaluation is described by a file, evals/azure.eval.yaml, that you can read, edit, and commit. The commands either write that file or act on what it declares.
azd ai eval init # scaffold the configuration. Makes no service calls
azd ai eval generate # optional: synthesize a dataset and a rubric evaluator
azd ai eval create # register the eval in the Foundry project
azd ai eval run start # run it and summarize the results
| Item | Description |
|---|---|
init |
Scaffolds evals/azure.eval.yaml for an agent and adds an evaluation service to azure.yaml. Makes no service calls. |
generate |
Synthesizes a dataset, a rubric evaluator, or both, downloads them, and adds a catalog entry for each to the configuration. Submits billed generation jobs. |
evals/azure.eval.yaml |
The evaluation recipe: what is evaluated, where the rows come from, and which evaluators grade them. |
create |
Registers the declared datasets, evaluators, and the eval itself in the project. |
run start |
Starts a run and, by default, waits for it and prints a per-evaluator summary. |
run output list |
The per-sample results behind that summary. |
dataset, evaluator |
Manage registered datasets and evaluators directly, including versions list. |
job |
Inspect, cancel, and delete the generation jobs generate submits. |
Every command accepts -o json for scripting and --debug for diagnostics. Every command except init accepts --project-endpoint.
Choose where the rows come from
An evaluation grades rows. They come from one of two places, and this is the first decision:
--source tracesevaluates what your agent already did, read from the traces it emitted. Nothing to author.--source datasetevaluates a fixed set of examples, either yours or generated. Repeatable and comparable across agent versions.
Trace-sourced evaluations need an agent that emits traces. Dataset-sourced evaluations need a .jsonl file or a registered dataset.
Scaffold the evaluation
Run init from your project root:
azd ai eval init
Without flags, init detects the agent when azure.yaml declares one, prompts when it declares several, and asks which model deployment the graders judge with and which evaluators to use. It writes evals/azure.eval.yaml and adds an evaluation service to azure.yaml. It makes no service calls, so it's safe to run before anything is deployed.
In a project that declares no agent service, init stops rather than guess:
ERROR: this project declares no agent service to evaluate. Add one, or name an existing agent with --target
Name the agent yourself in that case, with --target.
For scripted use, pass the decisions directly:
azd ai eval init \
--source traces \
--target support-agent \
--judge-model gpt-4.1-nano \
--name support-trace-eval \
--no-prompt
To evaluate a dataset you already have:
azd ai eval init \
--source dataset \
--target support-agent \
--dataset ./tests/support-golden.jsonl \
--evaluator builtin.intent_resolution,builtin.task_adherence \
--judge-model gpt-4.1-nano
--dataset takes a local .jsonl path or the name of a registered dataset. --evaluator is repeatable and comma-separated; builtin.<name> references a built-in evaluator, and a bare name references a custom evaluator registered in the project. Passing --evaluator replaces the defaults, so it also opts out of rubric generation.
To discover the built-in names:
azd ai eval evaluator list --builtin
Generate a dataset and an evaluator
If you don't have a dataset, or you want a rubric written for this agent rather than a generic one, generate them:
azd ai eval generate \
--target support-agent \
--generation-model gpt-4.1-nano \
--agent-instruction "Handles support requests. Test triage, policy adherence, and escalation."
By default this generates both a dataset and a rubric evaluator, downloads them under evals/, and adds a catalog entry for each to evals/azure.eval.yaml. Narrow it with --dataset or --evaluator to generate only one, and cap the rows with --max-samples (15 to 1000, default 15).
generate submits jobs that cost model calls. The instruction matters: it's what the service uses to decide what the rows and rubric are about, so describe what the agent does and what should be tested.
A catalog entry declares the artifact; it doesn't decide which evaluation uses it. After generate, open evals/azure.eval.yaml and check that the eval you intend to run references what was produced — a trace-sourced eval reads traces, so a generated dataset is only used once an eval names it:
datasets:
- name: support-agent-dataset
source: ./datasets/support-agent-dataset.jsonl
evals:
- name: support-agent-eval
dataset: support-agent-dataset # point the eval at the generated dataset
To submit the jobs and come back later:
azd ai eval generate --target support-agent --generation-model gpt-4.1-nano --no-wait
azd ai eval job list --dataset
azd ai eval job show <job-id> --dataset
--dataset and --evaluator on job choose which collection to act on, and one of them is required.
Review azure.eval.yaml
init writes a file you're meant to read. A trace-sourced evaluation looks like this:
evals:
- name: support-trace-eval
description: Basic quality evaluation for support-agent
source:
type: traces
max_traces: 20
agent_name: support-agent
evaluation_level: turn
evaluators:
- evaluator: builtin.task_adherence
initialization_parameters:
model: gpt-4.1-nano
A dataset-sourced evaluation names the dataset instead of a trace source, and records the agent it targets:
datasets:
- name: support-golden
source: ../tests/support-golden.jsonl
evals:
- name: support-agent-eval
description: Basic quality evaluation for support-agent
dataset: support-golden
evaluation_level: turn
evaluators:
- evaluator: builtin.intent_resolution
initialization_parameters:
model: gpt-4.1-nano
- evaluator: builtin.task_adherence
initialization_parameters:
model: gpt-4.1-nano
target:
type: agent
name: support-agent
Paths under source: are relative to the configuration file. The generated .jsonl and evaluator JSON are ordinary files: edit them, then run create again to register a new version.
Commit this file. It's the reproducible part of the evaluation.
Create the eval and run it
Use create to register everything the configuration declares — datasets, evaluators, and the eval itself:
azd ai eval create
Then run it:
azd ai eval run start
run start waits for the run by default and prints a per-evaluator table with a pass rate and a mean score, plus a link to the run in the portal. Use --no-wait to submit and return, and --max-samples to cap the rows sent.
If the configuration declares more than one eval, name the one you mean:
azd ai eval run start --eval support-trace-eval
Inspect the results
The summary tells you whether quality moved. The per-sample rows tell you why:
azd ai eval run output list --eval support-trace-eval
azd ai eval run output list --eval support-trace-eval --failed-only
To see runs over time, and what the service holds for one eval:
azd ai eval list
azd ai eval run list --eval support-trace-eval
azd ai eval show support-trace-eval
show returns the eval's identity in the project — ID, name, and when it was created. What the eval does is in your evals/azure.eval.yaml.
run list carries one pass rate per run. The per-evaluator breakdown is in -o json, under per_testing_criteria_results, because a column per evaluator stops being readable once runs score different evaluators.
To take the results elsewhere:
azd ai eval run output list --eval support-trace-eval --output-file rows.json
azd ai eval run output export --eval support-trace-eval --format csv --output-file summary.csv
The two differ, and the difference matters: run output list --output-file writes the per-sample rows, while run output export writes one line per run — the totals behind the summary.
Gate a build
Pass --fail-on to turn the run into a check. It exits non-zero when the run misses the threshold, which is how a pipeline fails a change that regressed quality:
azd ai eval run start --fail-on pass-rate=0.8
azd ai eval run start --fail-on any-failure
Without --fail-on, a completed run with failing samples still exits 0. Failing samples are the expected output of a working evaluation, not a tool error, so gating is opt-in.
pass-rate takes a number between 0 and 1. A threshold that isn't one is refused before the run is submitted, so a mistyped gate costs nothing.
--fail-on needs a run that has finished. On run show, pair it with --wait.
Deploy evaluations with the rest of the project
init adds an evaluation service to azure.yaml, so the eval is part of the project rather than a side artifact:
azd up
That provisions the project and registers the declared datasets, evaluators, and evals, the same work azd ai eval create does on its own.
Change the agent and re-evaluate
After you change and redeploy the agent, run the same evaluation again:
azd deploy
azd ai eval run start --eval support-trace-eval
Reusing the same eval keeps the dataset, evaluators, and thresholds fixed, so the comparison is about the agent.
To change what the evaluation measures, edit evals/azure.eval.yaml or the generated artifacts under evals/, then run create again. create registers a new version of anything that changed and leaves earlier runs pinned to the versions they used.
Best practices
- Start with
--source tracesif the agent already runs and emits traces. It measures what happened, and there's nothing to author. - Move to
--source datasetonce you want a fixed set of cases you can compare across versions. - Read the generated dataset and rubric before trusting the scores.
generateseeds them from the instruction you give it, so a vague instruction produces vague rows. - Use more than one evaluator. A single criterion moves the number without telling you why.
- Commit
evals/azure.eval.yamland the generated artifacts, so the evaluation is reviewable. - Gate with
--fail-onin CI, and keep the threshold where a real regression trips it.
Limitations
- The extension is in preview, and the command surface can change.
generatesubmits billed jobs. Datasets and evaluators aren't created byazd provision.- A trace-sourced evaluation can only read traces the agent already emitted.
azdcollapses an extension's exit code, so a gate breach and an operational failure both surface as a non-zero exit. Read the gate message to tell them apart.