Testare un LLM in CI: prima le asserzioni, poi il giudice IA

|Autore: Redazione QUASA|5 min di lettura| 1
Testare un LLM in CI: prima le asserzioni, poi il giudice IA

Per testare un’applicazione LLM in CI, salva casi rappresentativi, applica prima le asserzioni su formato e regole verificabili e usa un giudice IA solo per i requisiti che dipendono dal significato. Fissa in anticipo quali violazioni bloccano la build e quali punteggi semantici sono accettabili.

Distingui la verifica di output già salvati dalla prova di una nuova versione dell’applicazione. La prima permette di mettere a punto le asserzioni senza richiamare l’applicazione; per rilevare una regressione causata da un prompt o da un modello modificato, i casi interessati devono produrre risposte nuove. Registrare questa distinzione evita di attribuire un fallimento al componente sbagliato.

Salvare casi e requisiti insieme

Costruisci un insieme stabile di richieste che rappresenti il comportamento atteso: una richiesta ordinaria, un input incompleto, un caso limite e, se previsto dal prodotto, una richiesta da rifiutare. Per ogni caso conserva input, contesto fornito al modello, risposta e requisito da verificare. Annota anche la configurazione del prompt e del modello, così puoi capire se è cambiata l’applicazione, il caso di prova o la regola di valutazione.

Scrivi l’attesa nella forma più precisa consentita dal requisito. Se l’output è JSON, definisci campi obbligatori, tipi e valori ammessi; se la risposta deve scegliere una categoria, elenca le categorie valide. Quando sono corrette più formulazioni in linguaggio naturale, conserva invece i fatti e le istruzioni che la risposta deve rispettare: pretendere un testo identico trasformerebbe una variazione innocua in un fallimento.

Un caso utile deve identificare anche l’errore che intende intercettare. «Risposta buona» lascia troppo spazio all’interpretazione; «usa soltanto i dati presenti nel contesto allegato» indica quale evidenza serve per valutarla. Questa specificità aiuta a scegliere il controllo appropriato prima di scrivere il test.

Usare le asserzioni per ciò che possono verificare

Il primo filtro riguarda proprietà osservabili senza un secondo modello: parsing del JSON, conformità allo schema, presenza di un campo, appartenenza a un elenco o assenza di una stringa vietata. La documentazione delle asserzioni di Promptfoo distingue controlli deterministici e metriche assistite da modelli e mostra come applicare un file di asserzioni a output già generati con promptfoo eval --assertions asserts.yaml --model-outputs outputs.json.

Usa l’uguaglianza esatta quando ogni carattere conta, per esempio per un valore enumerato. Una parola obbligatoria può essere cercata nel testo, ma la sua presenza non dimostra che l’affermazione sia corretta: potrebbe comparire in una negazione. Anche un JSON valido può contenere dati errati. Assegna quindi a ciascuna asserzione solo la proprietà che è effettivamente in grado di provare.

Se l’applicazione restituisce argomenti per uno strumento, verifica i campi e i valori consentiti prima di giudicare la prosa della risposta. Un errore strutturale indica già quale contratto è stato violato e può chiudere quel caso senza una chiamata al giudice. Per un requisito che dipende da fatti esterni o dal contesto fornito, invece, superare lo schema è soltanto il passaggio preliminare.

Limitare il giudice IA ai requisiti semantici

Una valutazione basata su modello serve quando il requisito riguarda pertinenza, fedeltà al contesto o rispetto di istruzioni esprimibili in modi diversi. Se una regola esatta può decidere il caso, aggiungere un giudice introduce una chiamata e un verdetto da interpretare senza chiarire il requisito. Se invece due risposte formalmente valide possono differire per correttezza, occorre un criterio semantico circoscritto.

Fornisci al valutatore le informazioni necessarie per applicare quel criterio. In un caso basato su documenti, per esempio, chiedi se le affermazioni della risposta sono sostenute dal contesto allegato e includi quel contesto nella valutazione. Senza il riferimento, il voto non misura la fedeltà ai documenti. Conserva con l’esito la formulazione del criterio e la configurazione del giudice.

Prima di fissare la soglia, confronta il giudice con alcune risposte che consideri accettabili e altre che non lo sono, comprese quelle vicine al confine. Se il verdetto oscilla su un caso essenziale, rendi il criterio più specifico oppure sostituiscilo con una verifica diretta della proprietà contestata. Ripetere la stessa domanda vaga può mostrare la variabilità del giudizio, ma non risolve l’ambiguità del requisito.

Stabilire soglie e fallimenti della build

Separa i requisiti inderogabili dai punteggi aggregati. Uno schema invalido o una categoria fuori elenco può far fallire il caso immediatamente; una metrica semantica richiede una soglia definita prima dell’esecuzione. Se una richiesta è essenziale per il prodotto, imponi anche una condizione su quel singolo caso: una media alta non dovrebbe compensarne il fallimento.

Definisci inoltre l’esito di una valutazione che non arriva a termine. Un errore di chiamata o un verdetto illeggibile non equivalgono a una risposta corretta dell’applicazione. Registrali separatamente e stabilisci se la pipeline debba interrompersi o ritentare la valutazione. Nel risultato conserva l’identificativo del caso, il requisito fallito e l’output, così chi interviene sulla build può distinguere un errore di formato da un punteggio semantico basso.

Eseguire i controlli in CI senza moltiplicare le chiamate

Metti nel percorso di CI le asserzioni economiche e i casi decisivi; riserva le valutazioni semantiche ai casi selezionati. La guida CI/CD di Promptfoo documenta l’esportazione dei risultati in JSON o JUnit XML e l’opzione --fail-on-error per far fallire la build quando i test non passano. Collega l’esito del comando alla regola di blocco scelta per i requisiti essenziali.

Per test scritti in Python, la documentazione CLI di DeepEval indica che deepeval test run esegue i file tramite il plugin pytest. Documenta anche --exit-on-first-failure, --repeat e --use-cache; quest’ultima opzione riusa risultati di valutazione quando --repeat non è impostato. La ripetizione serve a osservare la variabilità dei casi, mentre il riuso evita di rivalutare risultati idonei alla cache.

La cache riduce il lavoro ripetuto solo se non nasconde la modifica che vuoi misurare. Quando cambiano prompt, modello o contesto recuperato, genera di nuovo le risposte dei casi interessati prima del confronto: rieseguire le asserzioni soltanto sugli output precedenti non rileverebbe la regressione. Mantieni piccolo l’insieme che decide la build e usa prove più ampie quando devi indagare un cambiamento specifico.

Leggi anche:

Condividi:

Iscriviti alla nostra newsletter

Ricevi le ultime notizie su Web3, IA e cripto direttamente nella tua casella di posta.

0