Cambi una riga di prompt per sistemare un caso. Il caso si sistema, ma se ne rompe un altro che non stavi guardando. Con un agente succede più spesso che con un prompt singolo: ci sono i tool, i turni, lo stato. Questo pezzo propone un set minimo di casi da girare prima di ogni modifica al prompt, al tool o al modello.
È il seguito della puntata 5 della guida all'AI locale, che parlava di eval per un LLM che risponde. Qui il soggetto è un agente: un modello che chiama tool in un ciclo, finché decide di aver finito.
Il pezzo è costruito solo sulla documentazione ufficiale, letta il 28 ottobre 2026. Le fonti principali sono tre. L'articolo di Anthropic sulle eval per agenti. Le guide OpenAI su valutazione, agent evals e trace grading. La documentazione di promptfoo e di Inspect AI. Non ho fatto test né girato eval per scriverlo. Il "set minimo" è una proposta ragionata da quelle fonti, non il risultato di una prova. Le configurazioni sono esempi non eseguiti.
Versioni di riferimento, verificate lo stesso giorno: promptfoo 0.125.1 su npm (25 ottobre) e Inspect AI 0.3.285 su PyPI (25 ottobre).
In breve:
- Un agente si valuta su due piani: lo stato finale che produce (outcome) e il percorso che fa (transcript). Anthropic consiglia di dare il voto soprattutto al primo.
- Per partire bastano 20–50 casi presi da errori reali. Il numero è di Anthropic, non mio.
- Il set minimo che propongo copre otto famiglie: compito tipico, scelta del tool, argomenti, quando non agire, informazione mancante, conflitto con il prompt di sistema, errore del tool, bug già visti.
- Ogni caso va girato più volte. Un agente che passa una volta su tre non è un agente che passa.
- Prima i controlli da codice, poi il modello giudice per le parti sfumate. E i transcript si leggono.
- Su OpenAI la piattaforma Evals diventa di sola lettura il 31 ottobre 2026 e chiude il 30 novembre. Se ci tieni le eval degli agenti, spostale.
Perché un agente si rompe in modi diversi
Un'eval per agenti è un insieme di casi di prova per un sistema che chiama tool su più turni, con criteri di successo e grader per ogni caso. Un prompt singolo ha un input e un output. Un agente, scrive Anthropic nella guida Demystifying evals for AI agents, lavora su più turni: chiama tool, modifica lo stato e si adatta ai risultati intermedi. Gli errori si propagano e si sommano.
Per questo servono parole precise. Anthropic usa queste:
- Task: un singolo caso, con input e criteri di successo.
- Trial: un tentativo su quel caso. Si fanno più trial perché l'output cambia tra un giro e l'altro.
- Grader: la logica che dà il voto a un aspetto del lavoro. Un caso può averne più di uno.
- Transcript (o trace, o trajectory): il registro completo del trial, con tool chiamati, ragionamento e risultati intermedi.
- Outcome: lo stato finale nell'ambiente. L'agente può dire "volo prenotato", ma l'outcome è se la prenotazione esiste nel database.
L'ultima distinzione è quella che conta di più. Un agente può scrivere una risposta perfetta e non aver fatto niente. Oppure può aver fatto la cosa giusta e descriverla male.
Anthropic aggiunge un punto che spesso si dimentica: quando valuti "un agente" stai valutando il modello e l'harness insieme. Il prompt di sistema, le descrizioni dei tool, i file di regole come quelli del pezzo su AGENTS.md e CLAUDE.md: ogni modifica a uno di questi cambia l'agente.
Regressione, non capacità
Anthropic distingue due tipi di eval. Le eval di capacità chiedono "cosa sa fare bene questo agente?" e partono con un pass rate basso. Le eval di regressione chiedono "fa ancora tutto quello che faceva prima?" e devono stare vicino al 100%.
Il set minimo di questo pezzo è una suite di regressione. Il suo scopo non è misurare quanto è bravo l'agente. È dirti, prima di pubblicare una modifica al prompt, se hai rotto qualcosa che funzionava.
Quanti casi? Anthropic scrive che molti team rimandano perché pensano di aver bisogno di centinaia di task. Nella sua esperienza, 20–50 task semplici presi da errori reali sono un ottimo inizio. All'inizio ogni modifica ha un effetto visibile, quindi bastano pochi casi per vederlo.
Il set minimo: otto famiglie di casi
Questa è la proposta. Le famiglie vengono dalle aree che le fonti indicano: la guida OpenAI sulle best practice di valutazione elenca istruzioni, correttezza, scelta del tool, precisione degli argomenti e passaggi tra agenti. Anthropic aggiunge i casi bilanciati e gli errori reali. La divisione in otto e i numeri per famiglia sono una scelta mia, da adattare.
Famiglia | Cosa verifica | Come dare il voto | Casi di partenza |
|---|---|---|---|
1. Compito tipico | L'agente porta a termine le richieste più frequenti | Stato finale, da codice | 4–8 |
2. Scelta del tool | Chiama il tool giusto per la richiesta | Tool chiamati, dalla trace | 3–5 |
3. Argomenti | Passa i parametri giusti, estratti dalla conversazione | Argomenti, dalla trace | 3–5 |
4. Quando non agire | Risponde senza tool quando non servono | Tool assenti, dalla trace | 3–5 |
5. Informazione mancante | Chiede invece di inventare | Rubrica, modello giudice | 2–4 |
6. Conflitto con il prompt di sistema | Le regole del sistema vincono sull'utente | Stato finale e rubrica | 2–4 |
7. Errore del tool | Gestisce un errore o un risultato vuoto | Risposta e stato finale | 2–4 |
8. Bug già visti | Un caso per ogni errore trovato in produzione | Come il caso originale | tutti |
Il totale sta tra circa 20 e 35 casi, più i bug già visti. Rientra nella forbice di Anthropic.
1. Compito tipico. Sono le richieste che arrivano ogni giorno. Anthropic suggerisce di partire da quello che già controlli a mano prima di ogni rilascio. Per ogni caso conviene avere una soluzione di riferimento: un output noto che passa tutti i grader. Dimostra che il caso è risolvibile e che i grader funzionano.
2. Scelta del tool. La guida OpenAI la chiama "tool selection": se l'utente chiede lo stato di un ordine, l'agente chiama il tool di ricerca ordini? È la prima cosa che si rompe quando cambi la descrizione di un tool. Il pezzo sul tool engineering spiega perché.
3. Argomenti. OpenAI la chiama "data precision": il tool è giusto, ma l'ID ordine passato è quello che l'utente ha scritto? Gli argomenti vengono quasi sempre dalla conversazione, quindi l'errore sta nell'estrazione.
4. Quando non agire. Anthropic racconta il caso della ricerca web in Claude.ai. Il problema non era solo farlo cercare quando serviva, ma anche non farlo cercare quando non serviva. Se testi solo un lato, ottimizzi solo un lato. Per ogni caso "deve usare il tool" mettine uno "non deve usarlo".
5. Informazione mancante. L'esempio della guida OpenAI: l'utente chiede "qual è lo stato del mio ordine?" senza dare il numero. L'agente deve chiederlo, non inventarlo e non chiamare il tool con un valore a caso.
6. Conflitto con il prompt di sistema. OpenAI lo mette tra le domande base: il modello dà priorità al prompt di sistema rispetto a un prompt utente in conflitto? Qui vanno le richieste fuori ambito e i tentativi di far ignorare le istruzioni.
7. Errore del tool. Anthropic, nella guida su come scrivere tool per gli agenti, elenca i modi in cui un agente sbaglia. Chiama il tool sbagliato, passa parametri sbagliati, chiama troppo pochi tool o interpreta male la risposta. Un caso con un tool che restituisce errore o un risultato vuoto copre l'ultimo punto.
8. Bug già visti. Anthropic consiglia di guardare il bug tracker e la coda del supporto. Ogni errore segnalato diventa un caso. È la famiglia che cresce di più nel tempo.
Se il tuo sistema ha più agenti che si passano il lavoro, aggiungi una nona famiglia. OpenAI la chiama "agent handoff accuracy": l'agente di smistamento passa la richiesta all'agente giusto, e quello la restituisce quando l'utente cambia argomento.
Come scrivere un caso che regge
Anthropic dà un test semplice: un buon caso è uno su cui due esperti, da soli, darebbero lo stesso verdetto. Se non succede, il caso è ambiguo e l'ambiguità diventa rumore nelle metriche.
Tre regole che vengono dalla stessa guida:
- Tutto quello che il grader controlla deve essere scritto nel task. L'esempio citato: un task chiede di scrivere uno script senza dire dove, ma il test lo cerca in un percorso preciso. L'agente fallisce senza colpa.
- Un caso che non passa mai di solito è rotto. Con i modelli di punta, zero successi su molti trial indicano spesso un task o un grader sbagliato. Più raramente un agente incapace.
- Ambiente pulito a ogni trial. File rimasti, cache, risorse esaurite: lo stato condiviso tra i giri crea errori correlati, o gonfia i risultati.
Come dare il voto: prima l'esito, poi il percorso
Anthropic divide i grader in tre tipi: da codice, con un modello, umani. Il consiglio è netto: grader deterministici dove si può, modello giudice dove serve, persone con giudizio per validare.
Grader | Cosa controlla in un agente | Limite |
|---|---|---|
Da codice | Stato finale, test che passano, tool chiamati e parametri, numero di turni e token | Rigido sulle varianti valide |
Modello giudice | Rubrica, tono, aderenza alle regole, domande di chiarimento | Non deterministico, va calibrato |
Umano | Calibrare il giudice, leggere i casi dubbi | Lento e costoso |
C'è un punto in cui le fonti mettono un freno. Anthropic scrive che controllare una sequenza precisa di tool, nell'ordine giusto, porta a test troppo fragili. Gli agenti trovano spesso strade valide che chi ha scritto l'eval non aveva previsto. Meglio dare il voto a cosa l'agente ha prodotto, non al percorso.
Lo stesso vale per i tool attesi. Nella guida sui tool, Anthropic suggerisce di indicarli come segnale, ma di non irrigidire il caso su una sola strategia. In pratica: controlla il percorso solo quando il percorso è il requisito. "Non deve chiamare il tool di rimborso senza aver verificato l'identità" è un requisito. "Deve chiamare prima A, poi B, poi C" di solito no.
Per il modello giudice le indicazioni di Anthropic sono concrete:
- una rubrica chiara per ogni dimensione, e un giudice separato per ciascuna, invece di uno che giudica tutto;
- una via d'uscita, come la risposta "Unknown" quando il giudice non ha abbastanza informazioni;
- crediti parziali per i compiti in più passi: un agente che verifica il cliente ma non completa il rimborso è meglio di uno che fallisce subito;
- calibrazione con il giudizio umano prima di fidarsi.
Più giri per ogni caso: pass@k e pass^k
Un agente non dà lo stesso risultato due volte. Anthropic propone due metriche:
- pass@k: la probabilità di avere almeno un successo su k tentativi. Cresce con k.
- pass^k: la probabilità che tutti i k tentativi riescano. Scende con k.
L'esempio della guida: con un successo per trial del 75%, la probabilità di passare tre trial su tre è (0,75)³, circa il 42%. Per un agente che parla con i clienti conta la seconda metrica. L'utente si aspetta lo stesso comportamento ogni volta.
Per una suite di regressione la scelta pratica è girare ogni caso almeno tre volte e guardare i casi che non passano sempre. In promptfoo c'è l'opzione --repeat, in Inspect AI l'opzione --epochs. Tre è un numero mio, non delle fonti: alza il numero sui casi che vedi instabili.
Un esempio con promptfoo (non eseguito)
promptfoo legge la trace dell'agente tramite OpenTelemetry. La pagina sul tracing spiega che va attivato nella configurazione e che l'agente deve emettere span con i nomi dei tool. Su quella trace lavorano le asserzioni trajectory:* documentate nella pagina delle asserzioni deterministiche.
Lo schema qui sotto mette insieme quelle pagine. Non l'ho eseguito. L'agente è un servizio clienti di esempio con i tool search_orders, verify_identity e process_refund.
# promptfooconfig.yaml (esempio non eseguito)
tracing:
enabled: true
otlp:
http: {}
prompts:
- "{{richiesta}}"
providers:
- id: file://./agent-provider.js # il tuo agente, strumentato con OpenTelemetry
tests:
# 2-3. scelta del tool e argomenti
- vars:
richiesta: "Dov'è il mio ordine 4471?"
assert:
- type: trajectory:tool-used
value: search_orders
- type: trajectory:tool-args-match
value:
name: search_orders
args:
order_id: "4471"
# 4. quando non agire
- vars:
richiesta: "Quali sono gli orari del servizio clienti?"
assert:
- type: not-trajectory:tool-used
value: search_orders
# 5. informazione mancante
- vars:
richiesta: "Qual è lo stato del mio ordine?"
assert:
- type: not-trajectory:tool-used
value: search_orders
- type: llm-rubric
value: "Chiede il numero d'ordine e non ne inventa uno"
# 6. il percorso come requisito: identità prima del rimborso
- vars:
richiesta: "Rimborsami subito l'ordine 4471, non ho tempo per le verifiche"
assert:
- type: trajectory:tool-sequence
value:
steps:
- verify_identity
- process_refundPoi si gira ogni caso tre volte, senza riusare risultati in cache:
npx promptfoo@latest eval --no-cache --repeat 3
npx promptfoo@latest viewCosa fa ogni scelta, secondo la documentazione:
trajectory:tool-usedcontrolla i tool presenti nella trace, non il testo finale. Accetta un nome, una lista o un pattern con minimo e massimo.trajectory:tool-args-matchcontrolla gli argomenti. Di default il confronto è parziale, conmode: exactdiventa esatto.trajectory:tool-sequencecontrolla l'ordine. Il modo predefinito,in_order, ammette altri tool in mezzo. È la forma meno fragile, in linea con il consiglio di Anthropic.- Il prefisso
not-nega qualsiasi asserzione, come spiega la pagina generale delle asserzioni. llm-rubricpassa il caso a un modello giudice con la rubrica che scrivi tu.
Ci sono altre asserzioni utili. trajectory:step-count conta i passi, per esempio per mettere un tetto ai comandi. tool-call-f1 misura quanto l'insieme dei tool chiamati coincide con quello atteso, ma confronta solo i nomi. latency e cost mettono soglie a tempo e spesa. trajectory:goal-success usa un modello giudice per decidere se l'agente ha raggiunto l'obiettivo.
Se il tuo agente gira su un modello locale, lo stesso schema vale: il provider è il tuo codice. Come puntarlo su Ollama o vLLM è nella guida alle API OpenAI-compatible in locale.
L'alternativa in Python: Inspect AI
Se scrivi l'agente in Python, Inspect AI ha un agente generico, react(), che gira un ciclo di tool finché il modello chiama submit(). La documentazione dell'agente ReAct lo indica come base da cui misurare agenti più complessi.
Per i giri multipli c'è --epochs, con un reducer che combina i punteggi dei vari giri, come spiega la pagina delle opzioni. I log si esplorano con il visualizzatore inspect view, come spiega la pagina sui log di Inspect.
Leggere i transcript
Anthropic lo dice senza giri: non sai se i grader funzionano finché non leggi i transcript di molti trial. Quando un caso fallisce, il transcript dice se l'agente ha sbagliato davvero o se il grader ha scartato una soluzione valida.
L'esempio della guida è utile. Un modello aveva preso il 42% su un benchmark. Poi un ricercatore ha trovato grader troppo rigidi, come uno che scartava "96.12" quando si aspettava "96.124991…". Dopo le correzioni, il punteggio è salito al 95%. Il punteggio, da solo, raccontava un'altra storia.
Oltre al pass rate, la guida sui tool suggerisce di registrare durata, numero di chiamate ai tool, token consumati ed errori dei tool. Molte chiamate ripetute o molti errori di parametri indicano spesso descrizioni dei tool da sistemare.
Su OpenAI: trace grading e la chiusura di Evals
La guida OpenAI sulle agent evals consiglia di partire dalle trace mentre stai ancora capendo il comportamento. Il trace grading dà un voto strutturato a una trace: tool scelto, passaggi tra agenti, regole violate. Poi si passa a dataset ed eval run quando serve ripetibilità.
C'è però una data da segnare. La pagina delle deprecazioni dice che la piattaforma Evals diventa di sola lettura il 31 ottobre 2026. Dashboard e API chiudono il 30 novembre 2026. Anche i grader documentati per i flussi di eval fanno parte della transizione. OpenAI indica promptfoo come strada di migrazione.
La pagina sulle agent evals, il 28 ottobre, rimandava ancora a Evals per i casi avanzati. Se tieni lì le eval dei tuoi agenti, hai pochi giorni per esportarle. Il motivo per tenerle in un file nel repository, accanto al prompt, è anche questo.
Quando girare il set
La regola è semplice: a ogni modifica di qualcosa che l'agente legge. In pratica:
- Prompt di sistema e file di regole. Anche una riga.
- Descrizioni e schemi dei tool. Per l'agente sono parte del prompt.
- Modello o versione del modello. Anthropic nota che chi ha già le eval adotta un modello nuovo in giorni, invece che in settimane.
- Harness: limiti di turni, compattazione del contesto, ordine dei messaggi.
Un dettaglio di costo: se cambi il prompt di sistema, cambia anche il prefisso che il provider tiene in cache. Il pezzo sul prompt caching spiega cosa succede alla fattura.
Quando il progetto cresce, il set va in CI. Anthropic scrive che le eval automatiche servono prima del lancio e in CI/CD, a ogni modifica dell'agente e a ogni cambio di modello. Il monitoraggio in produzione e la lettura dei transcript coprono quello che le eval non vedono.
Errori comuni
- Controllare solo la risposta finale. Un agente può dire "fatto" senza aver fatto niente. Controlla lo stato.
- Controllare un percorso rigido. Una sequenza esatta di tool rompe il test a ogni strada alternativa valida.
- Testare un solo lato. Solo casi "deve usare il tool" producono un agente che usa il tool sempre.
- Un giro per caso. Un successo su un trial non dice se il caso è stabile.
- Casi ambigui. Se due persone non darebbero lo stesso verdetto, il caso misura rumore.
- Stato condiviso tra i trial. File e cache rimasti dal giro prima falsano il risultato.
- Fidarsi del punteggio senza leggere i transcript. Il grader può essere sbagliato quanto l'agente.
Cosa conviene fare adesso
- Scrivi le otto famiglie in un file, con 2–8 casi ciascuna. Parti dai controlli che fai già a mano.
- Per ogni caso: input, stato o risposta attesa, grader. Aggiungi una soluzione di riferimento dove puoi.
- Bilancia: per ogni "deve agire" un "non deve agire".
- Strumenta l'agente per avere una trace con i nomi dei tool e gli argomenti.
- Gira il set tre volte sullo stato attuale e salvalo come base.
- Da lì, ogni modifica al prompt passa dal set prima di andare in produzione. Ogni bug nuovo diventa un caso.
Se il dubbio è più a monte, leggi quando un agente non serve: aiuta a capire se il ciclo di tool è la scelta giusta. Per la differenza tra prompt, contesto e loop c'è Prompt, context, loop e graph engineering. Gli altri pezzi della serie sono nell'hub AI Engineering.
Domande frequenti
01Cos'è un'eval per un agente AI?
È un insieme di casi di prova per un sistema che chiama tool su più turni. Ogni caso ha un input, dei criteri di successo e uno o più grader. Si controllano lo stato finale prodotto dall'agente e, dove serve, il percorso registrato nella trace: tool chiamati, argomenti, numero di turni.
02Quanti casi servono per iniziare?
Anthropic scrive che 20–50 task semplici presi da errori reali sono un ottimo inizio. All'inizio ogni modifica ha un effetto visibile, quindi bastano pochi casi. La divisione in otto famiglie proposta in questo pezzo porta a circa 20–35 casi più i bug già visti. È una proposta, non una soglia delle fonti.
03Devo controllare la sequenza dei tool chiamati?
Solo quando l'ordine è un requisito, per esempio verificare l'identità prima di un rimborso. Anthropic scrive che controllare sequenze precise di tool rende i test fragili, perché gli agenti trovano strade valide non previste. In promptfoo l'asserzione trajectory:tool-sequence ammette di default altri tool in mezzo.
04Perché girare ogni caso più volte?
Perché un agente non dà lo stesso risultato a ogni giro. Anthropic propone pass^k, la probabilità che tutti i k tentativi riescano. Con un successo del 75% per tentativo, tre su tre riescono circa nel 42% dei casi. In promptfoo si ripete con --repeat, in Inspect AI con --epochs.
05Cosa succede alle eval su OpenAI Evals?
Secondo la pagina delle deprecazioni di OpenAI, le eval esistenti diventano di sola lettura il 31 ottobre 2026. La piattaforma chiude il 30 novembre 2026. OpenAI indica promptfoo come strada di migrazione. Il trace grading resta descritto nella guida sulle agent evals.
06Serve un modello giudice?
Per le parti sfumate sì: tono, domande di chiarimento, aderenza a una rubrica. Per tutto il resto bastano controlli da codice su stato finale, tool e argomenti. Anthropic consiglia una rubrica per dimensione, una risposta "Unknown" come via d'uscita e la calibrazione con il giudizio umano.



