Gli evaluator di qualità rispondono alla domanda «la risposta è buona?». Quelli di rischio e sicurezza rispondono a una domanda diversa e più scomoda: «questa risposta fa danno?». Sono due famiglie con meccanica differente — la seconda non usa il tuo modello giudice ma modelli ospitati dal servizio — e si configurano in modo diverso. La seconda metà dell’unità riguarda il punto che distingue un MLOps engineer da chi valuta a mano prima del rilascio: portare tutto questo dentro una pipeline, con una soglia capace di far fallire una build.

Gli evaluator di rischio e sicurezza

Sono prodotti dal servizio di valutazione di Microsoft Foundry, che impiega modelli propri addestrati a riconoscere ciascun rischio. Conseguenza pratica: non prendono deployment_name, ma pretendono le informazioni del progetto Foundry e una regione supportata. Il catalogo copre builtin.hate_unfairness, builtin.sexual, builtin.violence, builtin.self_harm, builtin.protected_material, builtin.code_vulnerability, builtin.ungrounded_attributes e builtin.indirect_attack, quest’ultimo applicabile ai soli modelli; per gli agenti esistono inoltre builtin.prohibited_actions e builtin.sensitive_data_leakage, in preview, che vogliono anche i tool_calls in input.

La scala è il dettaglio che l’esame ama. I quattro evaluator di contenuto dannoso usano una severità da 0 a 7, raggruppata in Very Low (0-1), Low (2-3), Medium (4-5) e High (6-7). Con la soglia predefinita di 3 l’esito è pass quando il punteggio è pari o inferiore alla soglia, fail altrimenti: logica invertita rispetto alle metriche di qualità, dove alto è meglio. Tutti gli altri evaluator della famiglia non danno una severità, solo pass o fail a seconda che il rischio sia rilevato. Sull’insieme del dataset il servizio calcola un defect rate, la percentuale di contenuto indesiderato: è quello il numero da portare in un report.

Due avvertenze. La transparency note dichiara che questi punteggi non vanno letti come garanzia di conformità: sono un segnale, non un certificato. E gli stessi evaluator alimentano l’AI Red Teaming Agent, che esegue scansioni avversariali automatiche con strategie di attacco predefinite ed è dichiaratamente non deterministico — due scansioni identiche possono dare esiti diversi, quindi è una sonda e non un test di regressione, e non sostituisce il red teaming manuale.

Evaluator personalizzati accanto a quelli integrati

Quando serve una metrica di dominio — tono di brand, formato di output, presenza di un disclaimer — si registra un evaluator personalizzato nel catalogo del progetto e da lì lo si usa come uno integrato. Le forme sono tre.

Il code-based è una funzione Python grade(sample, item) che restituisce un float fra 0.0 e 1.0. Gira in una sandbox senza accesso di rete, con limiti su dimensione del codice, memoria e tempo per chiamata; se solleva un’eccezione il servizio registra 0.0 e marca l’item come errore, quindi va scritta difensiva con try/except e un punteggio di ripiego. Dettaglio che pesa in sede d’esame: pretende comunque deployment_name fra i parametri di inizializzazione, insieme a pass_threshold, anche se non chiama nessun modello.

Il prompt-based è un prompt giudice che deve restituire un oggetto JSON con result e reason; il punteggio può essere ordinale, continuo o binario e servono deployment_name e threshold. L’endpoint-based delega a un servizio HTTP tuo, raggiunto tramite una connessione del progetto autenticata con chiave API oppure con Microsoft Entra ID e managed identity: è la via quando servono rete, modelli proprietari o logica che eccede i limiti della sandbox. Tutti e tre si versionano, e le run passate restano ancorate alla versione che hanno usato.

Portare la valutazione dentro la pipeline

Valutare a mano prima del rilascio non è MLOps. Il canale nominato dal profilo dell’esame è GitHub Actions, con l’action microsoft/ai-agent-evals: le passi l’endpoint del progetto, un deployment per i giudici, uno o più agent-ids nel formato nome:versione e un file dati JSON con name, evaluators e data. Il report finisce nel summary della run e include intervalli di confidenza e, quando confronti più agenti contro un baseline-agent-id, un test statistico che dice se la differenza è reale o rumore.

name: AI Agent Evaluation
on:
  workflow_dispatch:
  push:
    branches: [main]
permissions:
  id-token: write
  contents: read
jobs:
  evaluate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Azure login con credenziali federate
        uses: azure/login@v2
        with:
          client-id: ${{ vars.AZURE_CLIENT_ID }}
          tenant-id: ${{ vars.AZURE_TENANT_ID }}
          subscription-id: ${{ vars.AZURE_SUBSCRIPTION_ID }}
      - name: Run evaluation
        uses: microsoft/ai-agent-evals@v3-beta
        with:
          azure-ai-project-endpoint: ${{ vars.FOUNDRY_PROJECT_ENDPOINT }}
          deployment-name: ${{ vars.JUDGE_DEPLOYMENT }}
          data-path: ${{ github.workspace }}/eval/dataset.json
          agent-ids: support-agent:4

Il permesso id-token: write serve per l’autenticazione OIDC con credenziali federate, che è il modo raccomandato: niente segreti di lunga durata. E c’è una raccomandazione esplicita a non far girare la valutazione a ogni commit, perché ogni riga costa chiamate al modello.

Il cancello vero arriva dall’estensione azd ai eval (preview), che descrive la valutazione in un file evals/azure.eval.yaml versionato con il codice e restituisce un exit code diverso da zero sotto soglia:

azd ai eval run start --fail-on pass-rate=0.8
azd ai eval run start --fail-on any-failure

Senza --fail-on una run con campioni falliti esce comunque con 0: i campioni falliti sono l’output normale di una valutazione che funziona, quindi il gating è opt-in. Su Azure DevOps esiste una task equivalente. Nota di contesto: se incontri materiale che costruisce questi flussi con prompt flow, sappi che prompt flow è in ritiro il 20 aprile 2027 e Microsoft non lo raccomanda più per nuovi sviluppi, indicando come alternativa Microsoft Agent Framework.

Da ricordare per l esame

  • Gli evaluator di rischio e sicurezza girano su modelli ospitati dal servizio Foundry: niente deployment_name, ma progetto e regione supportata sì.
  • Contenuto dannoso: severità 0-7, soglia predefinita 3, pass con punteggio pari o inferiore alla soglia; gli altri evaluator della famiglia danno solo pass/fail. Sull’insieme si legge il defect rate.
  • builtin.indirect_attack (XPIA) vale per i soli modelli; prohibited_actions e sensitive_data_leakage per i soli agenti, con i tool_calls.
  • Custom evaluator: code-based (grade che ritorna 0.0-1.0, sandbox senza rete, richiede comunque deployment_name e pass_threshold), prompt-based (result + reason), endpoint-based (connessione con chiave o Microsoft Entra ID).
  • In CI: microsoft/ai-agent-evals con id-token: write e login OIDC; il gate di qualità è --fail-on di azd ai eval, senza il quale la run esce 0 anche con campioni falliti.