Fable 5, Opus 4.8 e Sonnet 4.6: come confrontare onestamente gli LLM sul proprio codice
Esperimento controllato: Fable 5, Opus 4.8 e Sonnet 4.6 eseguono l'audit di una base di codice reale con lo stesso prompt. Metodologia per un confronto onesto degli LLM sul proprio progetto.
Impossibile caricare questa immagine.Quando esce un nuovo modello, l'annuncio risponde alla domanda «quanto è migliore sui benchmark» — e non risponde all'unica domanda che mi interessa: cosa cambierà nel mio lavoro. Ho condotto un esperimento controllato: tre modelli Claude — Fable 5, Opus 4.8 e Sonnet 4.6 — hanno ricevuto un compito identico parola per parola di audit della base di codice di questo blog, ciascuno in una copia isolata del repository, con una rubrica di valutazione concordata in anticipo. Nell'articolo — la metodologia stessa, che si può ripetere su qualsiasi progetto, i risultati, e separatamente — come l'esperimento si è rotto due volte e cosa questo ha insegnato.
Perché i benchmark non rispondono alla mia domanda
I benchmark pubblici hanno due problemi, ed entrambi fondamentali. Il primo è la contaminazione dei dati: gli esempi di test filtrano nei set di addestramento, e il modello in parte «ricorda» le risposte invece di risolvere il compito. Non è un sospetto marginale, ma l'oggetto di un intero filone di ricerca: la rassegna di Xu e coautori (2024) sistematizza gli studi sulla contaminazione dei benchmark, e la rassegna EMNLP 2025 registra la risposta dell'industria — il passaggio da test statici a test generati dinamicamente.
Il secondo problema è più semplice: il benchmark non misura il mio compito. Non mi serve un modello che risolve meglio di tutti i problemi delle olimpiadi. Mi serve un modello che trovi bug reali nel mio blog Laravel, non ne inventi di inesistenti e dimostri che il suo fix funziona.
Da ciò segue un pensiero semplice: il miglior banco di prova per confrontare i modelli è il proprio progetto. Il suo codice, in questa combinazione, non è nei set di addestramento, i compiti su di esso sono esattamente quelli per cui pago, e i risultati posso verificarli a mano, perché conosco questo codice.
Disegno dell'esperimento: un prompt, tre mondi isolati
Il compito per tutti e tre i modelli era identico parola per parola — differivano solo il nome del branch e la cartella dei risultati. Quattro fasi: audit del sistema bilingue degli articoli del blog con la prova di ogni riscontro sotto forma di файл:строка con citazione del codice; scelta delle soluzioni per i tre riscontri principali con descrizione dei compromessi; implementazione di un fix con autoverifica; nota sui risultati in russo e inglese. Un ciclo completo di lavoro ingegneristico, non un isolato «domanda-risposta» — un approccio che raccomanda anche Anthropic: valutare gli agenti su compiti di un prodotto reale, secondo una rubrica concordata prima dell'avvio.
Tre regole hanno reso il confronto onesto:
Isolamento. Ogni modello lavorava in un git worktree separato — una propria copia della directory di lavoro con il proprio branch. I modelli non potevano fisicamente vedere i risultati degli altri né interferire tra loro.
Protezione dalle allucinazioni — nel prompt stesso. La riga chiave del compito: «un riscontro inventato (codice inesistente, riga errata) è peggio dell'assenza di un riscontro». Senza questo incentivo, il modello a cui si chiede di trovare problemi tende a «trovarli» in ogni caso. Con esso — ogni riscontro deve superare una verifica manuale.
Esclusione degli indizi dal punteggio. Nel repository c'è un CLAUDE.md che descrive le insidie note del progetto — ad esempio, i percorsi relativi agli asset che si rompono sugli URL con prefisso di lingua. Tutti e tre i modelli leggono questo file, quindi tali riscontri sono «gratuiti»: contano per la cura, ma non per la profondità.
Rubrica: valutare solo ciò che si può verificare a mano
Prima dell'avvio ho fissato sei assi da cinque punti: accuratezza dell'audit (verifica manuale di un campione di riscontri tramite файл:строка), profondità (riscontri confermati che non sono negli indizi), qualità del ragionamento sui compromessi, codice e realtà dell'autoverifica, qualità del testo russo e inglese, disciplina (zero domande all'umano, nessuna violazione dei vincoli). Il principio è lo stesso di una buona code review: meno un asse si basa sul gusto e più su un fatto verificabile, più ci si può fidare di esso.
Come tutto si è rotto la prima volta
Il primo avvio l'ho fatto in modo sbagliato — e questa si è rivelata la parte più trasferibile dell'esperimento. Ho aperto tre sessioni interattive in parallelo nella stessa cartella del repository. Dopo qualche minuto nell'albero di lavoro giacevano modifiche non committate impossibili da attribuire: un checkout condiviso significa che quando una sessione fa git checkout -bil branch cambia per tutte e tre, e le loro modifiche e commit si mescolano. Una delle sessioni in più ha fatto git stash e ci ha spazzato dentro tutto — inclusi i miei file personali, non pertinenti all'esperimento.
“Agenti AI paralleli in una sola cartella non sono un esperimento parallelo. È un unico grande conflitto con tre autori.”
– la conclusione che mi è costata un riavvio
I risultati di due sessioni hanno dovuto essere considerati inutilizzabili: anche se fossero stati portati a termine, non avrei potuto dire onestamente di chi stavo valutando le modifiche. La seconda esecuzione — già in worktree isolati — si è scontrata con i limiti del piano tariffario: due agenti sono morti all'avvio, e il terzo si è bloccato, continuando a sembrare «funzionante» nell'interfaccia. La diagnosi l'ha fatta il filesystem, non l'indicatore di stato: in venti minuti nella sua copia di lavoro non è comparso nemmeno un file. Questa è la seconda lezione trasferibile: la vitalità di un agente si verifica dalle modifiche sul disco. Dopo il riavvio, tutti e tre i modelli hanno completato il ciclo completo in condizioni paritarie.
Risultati: dove i modelli sono uguali e dove differiscono
Il risultato più importante è quello che non è successo: nessun modello ha avuto allucinazioni. Ho verificato manualmente tre o più riscontri di ciascuno — tutte le citazioni e i numeri di riga sono esatti fino al carattere. Per i compiti di audit questa è la soglia di fiducia principale, e tutti e tre l'hanno superata.
Poi iniziano le differenze:
| Fable 5 | Opus 4.8 | Sonnet 4.6 | |
|---|---|---|---|
| Riscontri confermati | 11 | 5 | 9 |
| Unici non banali | 3 | 1 | 2 |
| Autoverifica della correzione | render di integrazione su DB temporaneo, xmllint, attribuzione di un test fallito altrui | linter + render; ha individuato un proprio bug | solo linter e lista delle route |
| Token / tempo | 164k / 21 min | 101k / 12 min | 131k / 12 min |
| Totale per rubrica (su 30) | 30 | 24 | 25,5 |
Le differenze qualitative sono più informative dei punteggi. Opus 4.8 è l'unico che non ha notato l'intestazione rotta Content-Type nella sitemap (l'hanno trovata gli altri due) e l'ha lasciata nella propria correzione; e nel suo testo russo è filtrata una parola inglese — «и even путь к картинке». Sonnet 4.6 ha fatto una correzione corretta, ma la sua autoverifica era dichiarativa: il linter invece dell'esecuzione. Fable 5 si è distinta proprio nell'autoverifica: ha scoperto che php sulla mia macchina è un wrapper su un container docker montato sulla directory principale, ha ricostruito tutte le verifiche tramite container usa-e-getta e ha eseguito la propria correzione in modo integrato su un database temporaneo. La differenza tra «l'ho fatto» e «ho dimostrato di averlo fatto» è proprio l'asse più discriminante per i compiti agentici.
Un altro segnale utile è la convergenza: tutti e tre i modelli hanno indicato indipendentemente come riscontro principale lo stesso problema con la sitemap. Quando revisori indipendenti convergono sul riscontro principale, è un analogo a basso costo della concordanza tra esperti: il problema è quasi certamente reale.
Un giudice tra i partecipanti
La valutazione per rubrica è stata effettuata da Fable 5 — lo stesso modello che partecipava al confronto. È un buco metodologico, e va detto chiaramente: i giudici LLM sovrastimano sistematicamente i propri testi, e la tendenza è tanto più forte quanto meglio il modello riconosce i propri testi — questo è mostrato nel lavoro di Panickssery e coautori a NeurIPS 2024. Il bias si può attenuare in due modi, e ho usato entrambi: in primo luogo, spostare il più possibile la rubrica dagli assi di gusto ai fatti verificabili — l'esattezza delle righe, la completezza della correzione, la parola straniera filtrata non dipendono dalle simpatie del giudice; in secondo luogo, dichiarare esplicitamente il conflitto e affidare gli assi controversi alla verifica incrociata di un altro modello o di una persona. Gli assi soggettivi del mio totale — qualità del testo, qualità del ragionamento — vanno letti con questa correzione.
Limiti di onestà
Un'unica esecuzione per modello è n=1: differenze di uno o due punti non significano nulla, ci si può fidare solo degli scarti qualitativi — un bug mancato, la profondità dell'autoverifica. L'esperimento misura tre modelli su un compito in un dominio; «Fable 5 è migliore in generale» non ne consegue. E va ricordato il costo: il modello top ha speso 1,6 volte più token e quasi il doppio del tempo rispetto al partecipante più economico, e il suo token a listino è anche più caro di per sé — per compiti regolari è un argomento pesante a favore di modelli più semplici.
Cosa mi porto via
La metodologia si è ridotta a una breve checklist che funziona per qualsiasi progetto e qualsiasi modello:
- Il compito di prova — un ciclo completo di lavoro reale sul proprio codice, non un compito sintetico.
- Un unico prompt per tutti, isolamento tramite worktree separati, risultati in branch separati.
- Nel prompt — un prezzo esplicito dell'allucinazione: un riscontro inventato è peggio dell'assenza di un riscontro.
- I suggerimenti disponibili a tutti (documentazione, note nel repository) sono esclusi dal conteggio della profondità.
- La rubrica si fissa prima dell'avvio e si basa su fatti verificabili, non sull'impressione.
- Verificare a mano un campione dei riscontri; la coincidenza dei riscontri principali tra modelli indipendenti è un segnale della loro realtà.
- Il giudice-partecipante è un conflitto dichiarato: gli assi controversi vanno affidati alla valutazione incrociata.
- La vitalità dell'agente va verificata dal disco, non dall'indicatore nell'interfaccia.
Un bonus non previsto dal piano: l'esperimento si è ripagato da solo. Tre audit indipendenti hanno trovato nel blog problemi reali — dalla sitemap senza pagine inglesi alle query morte nel controller — e due correzioni pronte giacciono già nei branch, in attesa del passaggio in produzione. Confrontare i modelli sul proprio codice, a differenza di leggere i benchmark, lascia dietro di sé non solo un'opinione.
Fonti e riferimenti
- Benchmark Data Contamination of Large Language Models: A Survey (Xu et al., 2024) — una sistematizzazione del problema della contaminazione dei benchmark; l'argomento principale a favore dei test sul proprio codice.
- Benchmarking LLMs Under Data Contamination: From Static to Dynamic Evaluation (EMNLP 2025) — come l'industria si sta allontanando dai test statici verso quelli dinamici; il mio esperimento è un caso particolare di test dinamico.
- Demystifying evals for AI agents (Anthropic Engineering, 2026) — la pratica della valutazione degli agenti: compiti dal prodotto reale, rubriche verificabili, distinzione tra traiettoria e risultato.
- LLM Evaluators Recognize and Favor Their Own Generations (NeurIPS 2024) — perché il modello-giudice sovrastima se stesso e cosa fare al riguardo.
- Run parallel sessions with worktrees (Claude Code Docs) — il meccanismo standard di isolamento delle sessioni agentiche parallele, senza il quale il primo avvio dell'esperimento è fallito.
