Una soluzione generativa non si collauda come un servizio deterministico: la stessa domanda può produrre due risposte diverse e ugualmente accettabili, quindi non esiste un assert da scrivere. Al suo posto si costruisce un ciclo di misura ripetibile, e il primo pezzo di quel ciclo non è la metrica: è il dataset. Senza un insieme di casi fisso e versionato ogni punteggio resta un numero senza storia, impossibile da confrontare fra due versioni del prompt, dell’agente o del modello. Questa unità tiene insieme le due cose che gli obiettivi chiedono: come si costruisce il dataset di test e come le sue colonne finiscono davvero dentro l’evaluator.
Il dataset di test è un artefatto, non un file di appoggio
In Microsoft Foundry il dataset di valutazione è un file JSONL — un oggetto JSON per riga — oppure un CSV con le intestazioni di colonna. I nomi di campo ricorrenti sono query, response, context e ground_truth; il context è una stringa singola, quindi quando il contesto arriva a pezzi i chunk vanno concatenati con un separatore prima di scriverlo. Il file si carica nel progetto con nome e versione, perché è la versione a rendere confrontabili due run:
data_id = project_client.datasets.upload_file(
name="support-golden",
version="3",
file_path="./eval/support-golden.jsonl",
).id
Le righe arrivano da tre sorgenti. La prima è il golden set scritto dagli esperti di dominio: costoso, ma è l’unico che porta un vero ground_truth. La seconda è la generazione sintetica (preview), che parte dalle istruzioni di un agente, da un prompt inline o da un documento di riferimento caricato, e produce un dataset versionato con schema query e ground_truth; le sorgenti si combinano — il documento ancora le domande al dominio, il prompt ne governa tono e difficoltà. Il servizio accetta fra 15 e 1000 campioni, con 15 come minimo e default, e la prassi indicata è generarne pochi, rileggerli a mano e solo dopo scalare. La terza sorgente è il traffico di produzione convertito in dataset. Sintetico e tracce non sono alternative: il primo copre casi limite e fase pre-lancio, il secondo riflette il comportamento reale. Un dataset generato dalle istruzioni di un agente invecchia quando quelle istruzioni cambiano: la rigenerazione va trattata come una modifica di codice, con una nuova versione.
Data mapping: come una colonna diventa un input
Il data mapping è il punto in cui la maggior parte delle valutazioni si rompe in silenzio. Ogni evaluator dichiara gli input che pretende, e tu devi dirgli da quale campo prenderli. I segnaposto sono tre: {{item.nome_campo}} legge una colonna del dataset, {{sample.output_text}} legge il testo generato quando la run ha come bersaglio un modello o un agente, {{sample.output_items}} legge la risposta strutturata di un agente. Da qui discendono le tre forme di valutazione: sul dataset, con risposte già calcolate; sul target modello, che genera le risposte al volo dalle sole query; sul target agente.
testing_criteria = [
{
"type": "azure_ai_evaluator",
"name": "groundedness",
"evaluator_name": "builtin.groundedness",
"initialization_parameters": {"deployment_name": model_deployment},
"data_mapping": {
"context": "{{item.context}}",
"response": "{{item.response}}",
},
},
]
Un mapping sbagliato non produce un errore chiaro: produce punteggi assenti o a zero, ed è esattamente la voce che la guida di troubleshooting elenca accanto agli errori di formato. Quando una run torna con una colonna vuota, il primo sospettato è il mapping, non il modello.
Groundedness, relevance, coherence e fluency
Le quattro metriche nominate dagli obiettivi misurano cose diverse e chiedono input diversi. Groundedness verifica che la risposta non aggiunga nulla che non stia nel contesto: è l’aspetto di precisione. Vuole response e context, accetta query come opzionale ma consigliata perché migliora il punteggio, e usa un modello giudice, quindi richiede deployment_name. Non va confusa con Groundedness Pro, che si appoggia al servizio Azure AI Content Safety e restituisce un booleano, né con il rilevamento a runtime: l’evaluator è una misura offline su un dataset, non un guardrail che blocca una risposta.
Relevance chiede query e response e giudica quanto la risposta centri la domanda, senza ground truth. Coherence chiede query e response e misura l’ordine logico delle idee; Fluency chiede la sola response e misura grammatica e leggibilità. Queste due valutano la qualità della scrittura indipendentemente dalla verità dei fatti: una risposta inventata ma ben scritta prende fluency alta e groundedness bassa, ed è proprio per questo che si combinano.
Gli evaluator con giudice LLM restituiscono un punteggio da 1 a 5 con soglia di superamento predefinita 3, più reason, label e passed. Costano chiamate al modello per ogni riga, perdono affidabilità sulle risposte molto brevi e oggi supportano l’inglese. Per misurare la coerenza su un’intera conversazione invece che su un singolo turno si imposta evaluation_level="conversation" sulla run e si mappa il campo messages. Se serve l’aspetto di richiamo — cioè se la risposta ha omesso qualcosa — l’evaluator adatto è Response Completeness, che pretende ground_truth; se il sospetto è che il problema stia a monte nel recupero, si misura lo step con gli evaluator di retrieval.
Da ricordare per l esame
- Il dataset di valutazione è JSONL o CSV, si carica con nome e versione: senza versione fissa il confronto fra run non ha senso.
- La generazione sintetica parte da definizione di agente, prompt o file di riferimento, produce
queryeground_truth, accetta da 15 a 1000 campioni e va riletta a mano. {{item.campo}}legge il dataset,{{sample.output_text}}e{{sample.output_items}}leggono ciò che genera il target; un mapping sbagliato dà punteggi mancanti o a zero, non un errore.- Groundedness = precisione rispetto al contesto (
response+context); Relevance =query+response; Coherence =query+response; Fluency = soloresponse. - Gli evaluator con giudice LLM vogliono
deployment_name, danno 1-5 con soglia predefinita 3 e costano chiamate al modello per riga.