Note dal ciclo di rilascio — Parte 7
Venerdì alle 16:47 hai spedito una modifica al prompt di un carattere. Il punteggio aggregato dell’eval si è spostato da 0,873 a 0,871 — ben dentro il rumore di fondo. Lunedì mattina la tua coda di supporto è in fiamme per una classe di query che hai smesso di osservare sei mesi fa perché era stabile.
Niente è regredito nel modello. Il modello è lo stesso modello. L’eval è andato in deriva sotto i tuoi piedi. Sei mesi di lenta crescita in un segmento di clienti non sono mai entrati nel dataset aureo, il prompt del giudice è stato calibrato per l’ultima volta contro esseri umani a ottobre, e l’indice di retrieval si è ricostruito silenziosamente mercoledì scorso su un modello di embedding aggiornato.
Questo è ciò che il post 6 ha messo in evidenza — il modello è la risposta giusta circa un allarme su sette. Il che significa che la tua suite di regressione deve rilevare il drift in se stessa, non solo nel modello. Questo post è la suite.
Cos’è davvero il test di regressione per un LLM personalizzato?
I test di regressione software asseriscono output == expected per input fissi. Funzionano perché la funzione è deterministica.
Un modello linguistico non è una funzione nello stesso senso. Lo stesso prompt a temperatura > 0 produce una distribuzione di completamenti validi, e “valido” è multi-dimensionale: ha risposto alla domanda, la risposta è grounded nel contesto recuperato, è rimasta dentro l’envelope di sicurezza, è tornata dentro il budget di latenza. Quindi il test di regressione di un LLM personalizzato significa misurare la distribuzione del comportamento contro una distribuzione di baseline congelata — attraverso slice che contano per te, con giudici calibrati contro esseri umani, su input che assomigliano al tuo traffico di produzione.
Tre cose devono essere in posizione prima che tutto questo sia significativo:
- Un dataset aureo che assomigli alla produzione a livello di slice, non in aggregato.
- Un giudice calibrato — non “usiamo GPT-5 come giudice”, ma “abbiamo misurato Spearman ρ ≥ 0,7 contro tre rater umani, aggiornato l’ultima settimana”.
- Un manifest di baseline — i pesi esatti del modello, il template del prompt, l’indice di retrieval e la versione del giudice che hanno prodotto quei punteggi. Senza questo non puoi sapere se il punteggio si è mosso perché è cambiato il modello o perché è cambiato il righello.
Divinci esegue tutti e tre come oggetti di prima classe, collegati da hash, valutati su ogni commit. Il resto di questo post è come assemblarli.
Perché la maggior parte delle suite di regressione per LLM non rileva le vere regressioni
La modalità di fallimento dominante del 2026 per gli LLM personalizzati è ciò che il team Sigma Inference di Tianpan ha battezzato la Bugia del Semver nel loro postmortem di aprile 2026[1]: una metrica aggregata rimane piatta o migliora, mentre uno o due slice di produzione regrediscono silenziosamente. Lo slice era sotto il 5% del traffico quando il test è stato progettato, quindi non è mai entrato nel dataset aureo; sei mesi dopo è il 12% del traffico, il modello è peggiorato su di esso, e il numero aggregato non se ne sarebbe mai accorto.
Abbiamo esaminato ogni postmortem pubblico di rilascio di LLM degli ultimi diciotto mesi e il pattern si ripete: la suite è risultata verde perché stava valutando la cosa sbagliata. Specificamente:
- Il dataset aureo è stato scritto a mano dal team al lancio e mai ristratificato contro distribuzioni di traffico spostate.
- Il prompt LLM-as-judge è stato impostato una volta e mai ricalibrato contro etichette umane. L’accordo del giudice è decaduto silenziosamente[2].
- I punteggi di baseline sono stati conservati come numeri grezzi, non come tuple
(model_sha, prompt_sha, judge_sha, dataset_sha, score)— quindi quando qualcosa regrediva, nessuno poteva capire quale dei quattro si fosse mosso.
Una suite di regressione che non risolve tutte e tre queste cose è solo uno step di CI che diventa verde al momento del deploy e ti dà una falsa fiducia. La soluzione non è “più casi”. La soluzione è una misurazione slice-aware, ancorata alla versione, calibrata sul giudice, ad ogni rilascio.
Costruisci un dataset aureo che sopravviva all’analisi slice-aware
La composizione a quattro bucket che spediamo di default — campioni di produzione 60%, avversariali 15%, casi limite curati da esperti 15%, replay di fallimenti 10% — è un punto di partenza ragionevole. Ciò che la rende effettivamente capace di intercettare le regressioni sono i metadati di slice allegati a ogni caso.
Ogni voce nel dataset porta: input, comportamento atteso (rubrica, non stringa esatta), contesto di retrieval (se presente) e un tag slice — dominio, segmento utente, intent della query, lingua, bucket di lunghezza, qualunque decomposizione conti per il tuo prodotto. La suite valuta per slice, e qualsiasi slice che scenda oltre la sua soglia blocca il rilascio, anche se il punteggio aggregato è salito.
Due regole operative che abbiamo imparato a far rispettare:
Ricampionare trimestralmente. Le distribuzioni del traffico di produzione si spostano più velocemente di quanto la maggior parte dei team misuri. Ristratifichiamo il bucket campione di produzione contro gli ultimi 90 giorni di traffico ogni trimestre; se qualsiasi slice è cresciuto oltre il 5% del traffico ed era sotto il 2% del dataset aureo, viene reintegrato prima che il prossimo rilascio venga spedito.
Ogni postmortem aggiunge un caso. Una regressione che ha raggiunto la produzione e non è stata intercettata è un caso mancante dal dataset. Lo aggiungiamo al bucket dei replay entro 48 ore dal postmortem e lo taggiamo con lo slice che lo ha portato a galla.
Come rilevare il drift prima degli utenti?
Ci sono quattro tipi distinti di drift, e una suite di regressione che osserva solo l’ultimo è una suite che si perde la maggior parte delle regressioni.
| Tipo di drift | Cosa si muove | Segnale di rilevamento | Azione |
|---|---|---|---|
| Drift di qualità | Il punteggio del giudice per uno slice fisso | Cala lo Spearman ρ per-slice vs baseline | Bloccare il rilascio; diagnosticare per l’albero del post 6 |
| Drift di copertura | Distribuzione del traffico di produzione vs distribuzione del dataset aureo | Divergenza KL tra proporzioni di slice | Ricampionare il dataset aureo |
| Drift del giudice | Accordo del modello giudice con gli umani | Spearman ρ vs un audit set umano-etichettato congelato | Ricalibrare il prompt del giudice o sostituire il giudice |
| Drift di produzione | Punteggi di produzione live vs punteggi offline sullo stesso modello | Gap del punteggio nel replay delle tracce di produzione | Indagare retrieval / preprocessing / runtime |
Il drift di qualità è quello che la maggior parte delle suite misura; gli altri tre sono dove le regressioni del venerdì pomeriggio di solito si nascondono. Divinci traccia tutti e quattro contro il manifest di baseline, con la suddivisione del punteggio per-slice esposta su ogni PR e un job settimanale di calibrazione del giudice che segnala il drift prima che si accumuli.
Valutazione multi-dimensionale — valuta quattro cose insieme, per slice
Un singolo punteggio composito è un segnale peggiore di quattro punteggi scalari. Facciamo il gating su quattro dimensioni:
- Completamento del task — la risposta ha effettivamente risposto alla domanda, valutata da un giudice calibrato contro una rubrica. Slice-aware.
- Fedeltà — per qualsiasi risposta che ha fatto riferimento al contesto recuperato, ogni affermazione è grounded in quel contesto. Le allucinazioni appaiono qui per prime.
- Sicurezza — correttezza del rifiuto, resistenza al jailbreak, esposizione PII / policy. Quasi sempre fa gating a un pass-rate ≥ 0,99; la sicurezza è un muro rigido, non un trade-off morbido.
- Budget di latenza — p95 entro l’SLA dello slice. Un cambio di prompt che ha raddoppiato i token per risposta è una regressione anche se la qualità è migliorata.
Ogni dimensione ha la sua baseline per-slice e la sua soglia per-slice. Non le combiniamo mai in un singolo scalare pesato al momento del gate; le esponiamo come quattro punteggi per slice e blocchiamo su quello che si è mosso oltre la propria soglia per primo. Un modello che ha guadagnato 4 punti di completamento task al costo di 1 punto di fedeltà sullo slice medico è comunque una regressione.
Quali gate dovrebbero bloccare il deployment di un LLM personalizzato?
Eseguiamo un’architettura a tre layer, ognuno dei quali fa gating su uno stadio diverso della pipeline (vedi post 1 per la tassonomia degli stadi).
Layer 1 — Smoke (ogni commit, ~90 secondi). Venti-trenta casi critici tratti dagli slice ad alto impatto. Intercetta regressioni catastrofiche prima che la suite completa consumi compute. Se lo smoke fallisce, il resto non viene eseguito.
Layer 2 — Suite completa (ogni PR, ~12 minuti). Il dataset aureo completo, valutato per slice su tutte e quattro le dimensioni. Spearman ρ slice-aware rispetto al manifest di baseline. La violazione di soglia blocca il merge. Il commento sulla PR elenca esattamente quale slice su quale dimensione si è mosso di quanto, con cinque esempi di casi falliti.
Layer 3 — Confronto di baseline (release candidate, ~25 minuti). Il modello candidato viene riprodotto contro le ultime 14 giorni di tracce di produzione — il replay closed-loop delle tracce di produzione che abbiamo spedito nel post 1. Lo stesso giudice calibrato che valuta il dataset aureo valuta anche gli output del replay. Qualsiasi slice i cui punteggi di replay divergano dai punteggi offline di più della propria soglia blocca il rilascio. Questo layer è ciò che intercetta il drift che il dataset aureo non conosce ancora.
Calibra il tuo giudice prima di fidarti di un singolo punteggio che produce
LLM-as-judge è ciò che permette a tutto questo di scalare oltre poche centinaia di casi. È anche dove una suite di regressione smette silenziosamente di funzionare, perché il giudice non ha alcun obbligo di rimanere calibrato man mano che viene aggiornato o man mano che la distribuzione dei tuoi dati si sposta.
Calibriamo ogni prompt del giudice contro un audit set umano-etichettato congelato di almeno 100 casi stratificati attraverso gli stessi slice del dataset aureo, e rieseguiamo la calibrazione settimanalmente. La barra a cui spediamo è Spearman ρ ≥ 0,7 contro la mediana dei rater umani, con κ di Cohen ≥ 0,6 sui giudizi binari di sicurezza. Entrambi sono sopra la soglia oltre la quale è stato dimostrato che i giudici in stile MT-Bench seguono i rater umani al livello dell’accordo inter-umano[2].
Quando la calibrazione settimanale scende sotto soglia, il giudice viene automaticamente ritirato e l’eval engineer di turno viene paginato. La pipeline di rilascio tiene aperti i candidati invece di farne il gating su un giudice che non sta più misurando ciò che misurava.
# Esegui il job settimanale di calibrazione del giudice
curl -X POST https://api.divinci.ai/v1/regression/judges/calibrate \
-H "Authorization: Bearer $DIVINCI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"judge_id": "rubric-v7",
"audit_set": "human-labels-2026-04",
"min_spearman": 0.70,
"min_kappa": 0.60,
"on_fail": "retire_judge_and_page"
}'Il differenziatore Divinci — replay closed-loop delle tracce di produzione
Il gate del Layer 3 è la parte che la maggior parte delle suite di regressione non ha. Il flusso è lo stesso flusso che abbiamo spedito nel post 1, con una specializzazione per il test di regressione: ogni release candidate ha il proprio punteggio sul dataset aureo offline confrontato, slice per slice, con il proprio punteggio su una finestra di 14 giorni di tracce di produzione riprodotte. Il dataset aureo misura ciò che ci aspettavamo che il modello facesse. Il replay misura ciò che il modello avrebbe effettivamente fatto la scorsa settimana.
Quando quei due punteggi divergono di più del gap-budget per-slice, il rilascio viene bloccato. La discrepanza è il segnale: o il dataset aureo non è più rappresentativo (drift di copertura), oppure il candidato si comporta diversamente su tracce modellate dal preprocessing e dal retrieval di produzione (drift di produzione). In entrambi i casi, lo scopri prima degli utenti.
Il giudice che valuta la run offline è lo stesso giudice che valuta la run di replay. L’audit log registra entrambi i set di punteggi, entrambe le versioni del giudice, gli ID delle tracce riprodotte e il gap che ha fatto scattare il blocco. Il gap stesso è il segnale diagnostico più utile che abbiamo, ed è ciò che viene consegnato a chiunque prenda in carico l’albero diagnostico del post 6 successivamente.
Ancora il dataset aureo con una ricevuta vindex
Ogni punteggio nella suite è privo di significato se non puoi riprodurlo più tardi. Hashiamo il dataset aureo ad ogni rilascio e concateniamo quell’hash in una ricevuta vindex insieme allo SHA del modello, allo SHA del prompt, allo SHA del giudice e al record di calibrazione. La ricevuta è ancorabile esternamente — gli auditor possono riprodurre la nostra esatta run di regressione sei mesi dopo e verificare i punteggi che abbiamo dichiarato.
{
"release_id": "rel_3f1a-2026-05-26",
"model": { "sha": "0c1f9…", "weights_uri": "r2://models/custom-v7.2", "open_weights": true },
"prompt": { "sha": "c4a8e…", "template_id": "support-v3.4" },
"retrieval": { "index_sha": "b21f0…", "embedder": "e5-mistral-7b-instruct" },
"judge": { "sha": "d8e21…", "rubric_id": "rubric-v7", "spearman_vs_humans": 0.74 },
"dataset": { "sha": "a90b1…", "n": 512, "slices": 17, "stratified_at": "2026-04-30" },
"scores": { "aggregate": 0.872, "by_slice": { "/* … */": "/* scalari per-slice */" } },
"replay": { "trace_window_days": 14, "n_traces": 8430, "max_gap": 0.018 },
"vindex_anchor": "sha256:f0bfd2…",
"verifiable_at": "https://vindex.divinci.ai/rel_3f1a-2026-05-26"
}Avvertenza open-weights. La ricevuta sopra porta la provenienza dei pesi solo quando il modello è open-weights — vindex ancora i byte effettivi dei pesi. Per i modelli supportati da API closed (modelli gestiti OpenAI / Anthropic / Google), la ricevuta porta comunque la catena decisionale — ogni punteggio dei gate, ogni risultato del giudice, il record di calibrazione — ma il campo dei pesi è vuoto, e non puoi verificare indipendentemente l’artefatto del modello. Lo diciamo nella ricevuta e nella documentazione di compliance in modo che gli auditor non abbiano una falsa impressione. I rilasci che beneficiano di più di una catena vindex completa sono quelli in cui controlli i pesi.
Una tempistica di implementazione in quattro fasi che abbiamo effettivamente spedito
I team che provano a spedire l’architettura completa nella prima settimana si bloccano sul tooling. L’ordine sotto è l’ordine che funziona.
Fase 1 — Baseline (settimana 1). Estrai un campione stratificato degli ultimi 30 giorni di tracce di produzione. Fai etichettare a mano da due ingegneri il completamento del task su 100 casi ciascuno. Calcola l’accordo inter-rater (obiettivo κ di Cohen ≥ 0,6). Il numero che ottieni è la tua baseline umana di partenza; tutto il resto viene calibrato contro questo.
Fase 2 — Harness (settimane 2–3). Allestisci l’harness di valutazione sul dataset da 100 casi. Aggiungi un giudice calibrato contro le tue etichette umane. Verifica che l’harness riproduca i punteggi umani entro ρ ≥ 0,7. La maggior parte dei team scopre che il proprio primo prompt del giudice fallisce in questo e lo riscrive due volte — è normale.
Fase 3 — Gate (settimane 3–4). Cabla l’harness nel CI come avvertimento, non come blocco. Osservalo per due settimane. Le soglie che scopri osservando i tassi di falsi positivi sono le uniche soglie che sopravvivono. Promuovi al blocking solo quando il tasso di falsi positivi è sotto il 5%.
Fase 4 — Loop di replay (continuo). Una volta che i gate stanno bloccando in modo affidabile, abilita il layer di replay delle tracce di produzione. È qui che il gap di copertura degli slice viene a galla, ed è qui che ogni postmortem inizia ad aggiungere casi indietro nel dataset aureo.
Cosa questo non risolve
Tre limitazioni oneste, nello stesso modo in cui le abbiamo inquadrate in ogni post di questa serie.
- Il drift della suite è lavoro senza fine. Il test di regressione è infrastruttura, non un progetto. Il dataset aureo deve essere ristratificato ogni trimestre, il giudice ricalibrato ogni settimana, i budget di soglia ri-tarati ad ogni postmortem. Non esiste una versione di questo in cui spedisci una suite e te ne vai.
- Un giudice perfettamente calibrato è comunque un modello. Spearman ρ = 0,74 contro i rater umani significa che circa un quarto delle chiamate del giudice non concorda con la mediana umana. Quel disaccordo residuo è il rumore di fondo su ogni punteggio. Lo esponiamo esplicitamente in ogni report di rilascio; i team che dimenticano che è lì verranno sorpresi da esso prima o poi.
- I backing API closed limitano quanto puoi verificare. Con un modello API closed, la suite di regressione misura il comportamento ma non può verificare la provenienza dei pesi. Se hai bisogno di piena riproducibilità — industrie regolamentate, deployment soggetti ad audit — il trade-off è sulla scelta del modello, non sulla suite.
Prossimamente
Il post 8, l’ultimo di questa serie, chiude il loop dentro il CI. Dove questo post e il post 5 trattavano di cosa gira ai gate, il prossimo riguarda il layer CI che produce i candidati che i gate valutano in primo luogo — valutazione pre-merge, contract test per i template dei prompt e come dimensionare la flotta CI per una suite di eval da 12 minuti senza far saltare il budget. È il layer ingegneristico sotto tutto ciò di cui abbiamo scritto finora.
FAQ
Qual è la differenza tra valutazione di un LLM e test di regressione di un LLM?
La valutazione misura se un modello soddisfa una barra di qualità in un momento nel tempo, rispetto a una rubrica assoluta. Il test di regressione misura se un candidato si comporta allo stesso modo di una baseline congelata, per slice, attraverso più dimensioni. La baseline è ciò che lo rende test di regressione — Divinci spedisce entrambi, e la modalità di regressione fissa (model_sha, prompt_sha, judge_sha, dataset_sha) in modo che un punteggio mosso identifichi quale input si è mosso.
Quanti casi dovrebbe avere un dataset aureo?
Meno di quanti pensi, stratificati meglio di quanto pensi. Abbiamo spedito una copertura di regressione utile con 200 casi su cinque slice ben definiti e visto dataset da 5.000 casi che si perdevano tutto ciò che contava perché non erano stratificati. Inizia a 200, stratificati, poi fai crescere il bucket di replay caso per caso a partire dai postmortem.
Dovrei usare revisori umani o LLM-as-judge?
Entrambi, con gli umani che calibrano il giudice. Gli umani non possono tenere il passo con il volume di cui un gate CI del ciclo di rilascio ha bisogno per fare scoring. Il giudice riempie il volume, gli umani calibrano il giudice — misurato settimanalmente con Spearman ρ ≥ 0,7. L’uno da solo o l’altro da solo è una modalità di fallimento.
Come testare per output non deterministici?
Valuta la distribuzione, non la stringa. Valuta con una rubrica che il giudice possa applicare attraverso le formulazioni, ed esegui ogni input da tre a cinque volte a temperatura > 0 in modo che il punteggio slice-aware sia su una distribuzione di completamenti piuttosto che su un singolo campione. Stringi la temperatura solo per i casi che hanno genuinamente bisogno di output deterministici (chiamate a strumenti con output strutturato, classificazione).
Quali metriche dovrei prioritizzare per il primo quality gate del CI?
Completamento del task e un gate di sicurezza. Entrambi per-slice. Aggiungere più dimensioni prima che le prime due siano calibrate produce rumore; i team che spediscono di più di solito finiscono per fare gating sul rumore. Aggiungi la fedeltà dopo quando attivi il retrieval; aggiungi la latenza una volta che le prime due sono stabili.
Riferimenti
- Pan, Tianpan. "The Semver Lie: how a minor LLM update broke production." 29 aprile 2026. La modalità di fallimento 2026 nominata per l'analisi di regressione slice-aware; i punteggi aggregati rimangono piatti mentre uno slice a basso volume regredisce silenziosamente.
- Zheng et al. "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena." arXiv:2306.05685. Evidenza empirica che i giudici LLM forti concordano con i rater umani approssimativamente ai livelli dell'accordo inter-umano (≈ 80%) su task aperti, con modalità di fallimento riportate che gli audit calibrate-against-humans sono progettati per rilevare.
- Kirkpatrick et al. "Overcoming catastrophic forgetting in neural networks." PNAS / arXiv:1612.00796. Il risultato fondante sul catastrophic forgetting nelle reti neurali fine-tuned — perché un LLM personalizzato fine-tuned debba essere testato in regressione per la perdita di capacità generale, non solo per il guadagno sul task target.
- Amazon Web Services. "SageMaker Deployment Guardrails — blue/green deployments and canary monitoring." Il contrasto closed-API: gate su metriche infrastrutturali (latenza, errori, CPU) piuttosto che sulla qualità semantica per-slice.
- Spearman, C. "The proof and measurement of association between two things." American Journal of Psychology, 15(1):72–101, 1904. Il coefficiente di correlazione di rango che ancora il gate slice-aware — robusto al drift della scala di scoring nel giudice, che è la proprietà di cui avevamo bisogno.
- DORA / Google Cloud. "Accelerate State of DevOps — change-failure-rate and time-to-restore-service metrics." La baseline trasversale al settore per "con quale frequenza i deploy causano incidenti" e "quanto velocemente ti riprendi". Le suite di regressione che bloccano al gate spingono in basso la prima metrica; il rollback istantaneo ([post 5](/it/blog/automated-llm-ci-cd-pipelines-with-instant-rollback/)) spinge in basso la seconda.
Ready to Build Your Custom AI Solution?
Discover how Divinci AI can help you implement RAG systems, automate quality assurance, and streamline your AI development process.
Get Started Today