Questo è un seguito delle Parti 1 e 2 di "Why Software Factories Fail"
abbiamo benchmark migliori
Ricordi quando ho detto questo nella Parte 1?
NON ESISTONO BUONI BENCHMARK per la capacità di un modello di mantenere la qualità del codebase
Non era del tutto vero, ma volevo seppellire il lede qui un po'. In questo articolo, guarderemo al futuro.
Approfondiremo SlopCodeBench, un benchmark di codifica a lungo orizzonte piuttosto recente (marzo 2026) dal laboratorio di @GOrlanski alla UW Madison. Affronta esattamente il problema che abbiamo evidenziato nella Parte 1 - che anche benchmark "più grandi" e più complessi rivelano ancora l'intero problema in anticipo:

Tuttavia, ogni sfida in SlopCodeBench ha molteplici "checkpoint": il modello non conosce l'intero problema in anticipo, deve evolvere il codebase nel tempo man mano che nuovi requisiti vengono rivelati. È un buon paper. Non è così lungo. Dovresti leggerlo.

La cosa bella di questo benchmark è che è insaturo: al momento dell'esecuzione, i migliori modelli disponibili, GPT-5.4 e Opus 4.6, hanno ottenuto rispettivamente l'11% e il 17% di tassi di superamento rigorosi.

testare opus 5 su slopcodebench
Venerdì ho eseguito tre modelli Claude (Opus 4.8, Sonnet 5 e Opus 5) su un sottoinsieme di SlopCodeBench e l'ho guardato in diretta per sei ore. Opus 5 vince tecnicamente, ma secondo me nessuno ha fatto un lavoro molto buono. Pubblicherò presto altri risultati con Fable e 5.6 Sol inclusi.

La grande notizia è che Opus 5 ha ottenuto un 24% sul piccolo sottoinsieme del benchmark che ho eseguito - non molto più alto del 17% di Opus 4.6 nel paper originale. Tutti i modelli testati hanno mostrato un aumento piuttosto significativo in verbosità, complessità e una serie di altre metriche di code smell nel corso di ogni sfida, con Opus 5 che ha scritto cinque volte il numero di funzioni/callable rispetto a Opus 4.8 durante lo stesso insieme di sfide.

La mia lettura personale di questo tasso di superamento del 23% è che SlopCodeBench fornisce un segnale che giustifica le mie sensazioni dalla parte 1 - che per lavori di ingegneria del software reali, costruendo un problema alla volta, i modelli odierni non possono essere usati con le luci spente senza supervisione.
il sottoinsieme del benchmark
ho fatto scegliere a Claude 3 problemi dal repository, 17 checkpoint in totale, un mix di problemi etichettati facili/medi/difficili:
- circuit_eval — facile (8 checkpoint)
- database_migration — medio (5 checkpoint)
- dynamic_config_service_api — difficile (4 checkpoint)
C'è un'appendice alla fine con tutti i 17 checkpoint spiegati in dettaglio, ma non li metterò tutti qui.
Poi li ho eseguiti su tutti e tre i modelli, in parallelo, con una finestra di contesto fresca per checkpoint. Tutti i modelli hanno ricevuto gli stessi prompt e sono stati eseguiti nell'harness del codice Claude.
La metrica a cui ho deciso di tenere è il superamento rigoroso: tutto ciò che è nuovo è verde, inclusi tutti i test di regressione ereditati dai checkpoint precedenti.
Un modello fallisce un checkpoint se la soluzione ha un difetto: i difetti vengono rilevati prendendo l'output del modello, un CLI da eseguire o in alcuni casi, ad esempio, un server API da sollecitare, ed eseguendo una serie di test black-box nascosti contro l'entrypoint prodotto.
- Il modello scrive codice per ck1
- L'harness di valutazione esegue test black-box contro ck1
- Il modello scrive codice per ck2
- La valutazione esegue test black-box per ck1 e ck2
- ecc.
Ancora, il criterio di superamento rigoroso significa che se un modello combina qualcosa nel checkpoint 4, non può superare i checkpoint successivi perché quella parte fallita del codice viene portata avanti (a meno che il modello non sistemi involontariamente un caso di valutazione nel checkpoint 6 che era rotto nel checkpoint 4, ma non abbiamo visto accadere in pratica).
Per tutti i 9 test run, nessun modello è arrivato alla fine di alcuna sfida con tutto funzionante, nemmeno sul problema etichettato come "facile".
mentre era in esecuzione
Il primo checkpoint di Sonnet è stato più costoso, ma alla fine del problema 1, Sonnet è diventato il più economico dei tre. (sembra che una volta costruite le basi e il lavoro si sia trasformato in manutenzione, allora i risparmi sui costi hanno iniziato a subentrare)
Per la prima sfida, i modelli dell'ultima generazione hanno accumulato difetti costantemente, Opus 5 un difetto ciascuno ai checkpoint 4 e 5.

per le prime due ore Opus 5 è stato l'unico modello ad avere superamenti rigorosi — tre di fila all'inizio.

Le cose si sono evolute man mano che procedevamo. Claude ha diligentemente aggiornato l'HTML.

Rispetto agli altri modelli, Opus 5 è stato tecnicamente migliore sul problema 1 (circuit_eval). Ma dopo aver superato brillantemente i primi tre checkpoint, ogni soluzione successiva ha avuto almeno un difetto (caso di test fallito).
risultato finale
Se la nostra definizione di successo è "raggiunto il checkpoint finale senza difetti", allora Opus 5 ha fallito tutti e tre i problemi, ma è fallito leggermente meno male degli altri modelli.

Per il rapporto costi vs difetti, odio veramente i claude-ismi ma questo ho deciso di lasciarlo:
ogni dollaro ha comprato correttezza. nessuno ne ha comprato abbastanza.
(ovviamente questo piccolo sottoinsieme del benchmark non può dirci in modo definitivo che spendere più $$ porterà a tassi di superamento più alti)

Per quanto riguarda i superamenti rigorosi, Opus 5 ne ha ottenuti quattro (tasso di superamento del 24%) (i primi tre ck di circuit_eval, più database_migration ck1).
opus 4.8 e sonnet 5 hanno entrambi ottenuto un superamento rigoroso (tasso di superamento del 6%), lo stesso database_migration ck1 che ha ottenuto Opus 5.
quindi il vincitore ha superato 4/17, e 3 di questi erano i checkpoint di apertura di un problema. Sembrerebbe che abbiamo un benchmark insaturo per la prossima frontiera dei modelli. bel lavoro @GOrlanski e team.
il misuratore di schifezza
Non sono ancora completamente convinto di "eliminare la schifezza con il linting", perché non penso che sia ancora possibile analizzare deterministicamente la "manutenibilità" di un particolare checkpoint del codebase. Ma sono interessanti da tenere d'occhio.
Le metriche di qualità del codice sono interessanti da tenere d'occhio, e probabilmente sono direzionalmente corrette, e
Con SlopCodeBench, ottieni i risultati dopo ogni checkpoint attraverso varie metriche di qualità. Ce ne sono 41 nel file dei risultati. Raggruppate approssimativamente:
- dimensione — linee di sorgente, file, funzioni, metodi, classi, istruzioni, e linee aggiunte e rimosse a quel checkpoint
- complessità — complessità ciclomatica media, massima e spread, quante funzioni cadono nelle bande "alta" ed "estrema", quanto è concentrata la complessità, profondità massima di annidamento, e lunghezza media delle funzioni
- duplicazione — linee clonate, e linee clonate come percentuale del sorgente
- decomposizione — funzioni a uso singolo, wrapper banali, variabili inutilizzate, linee per simbolo
- violazioni di regole — errori di lint e quanti sono auto-risolvibili, colpi di ast-grep contro regole di schifezza di test, e la percentuale di linee contrassegnate come verbose
- grafo delle dipendenze — costo di propagazione (quanto lontano si propaga un cambiamento), massa di dipendenze cicliche, entropia delle dipendenze (probabilmente la più interessante per me)
Ognuna di queste è calcolata deterministicamente utilizzando lo stato corrente del codice dopo ogni checkpoint.
Il grafico sotto mostra lo spread tra i modelli per il punteggio ck1 vs. ck8 per la sfida circuit_eval. (Cioè, quanto è aumentato l'indicatore di schifezza durante la vita dei checkpoint della sfida.) La cosa più interessante è che la maggior parte delle metriche non distinguono i modelli.

Mi piace che queste misure siano ripetibili e non utilizzino un modello per il giudizio. Ma il collegamento tra una qualsiasi di esse e "questo codebase è facile da modificare ed evolvere" non è ancora stabilito.
più correttezza è arrivata al costo di molto più codice

Ma molto di quello erano "più test": il volume di produzione effettivo è più vicino a 1,8x per Opus 5 rispetto a Opus 4.8.

La mia ipotesi sarebbe... verbosità costosa che non si è tradotta direttamente in risultati molto migliori.
Dovrò approfondire per sapere se questo è un segnale di tic del modello o semplicemente "questo è un problema davvero difficile e merita tutto questo codice".
quasi tutto il codice scritto ha attivato il misuratore di schifezza
Per tutti i modelli, una grande maggioranza delle linee di codice ha inciampato in almeno una delle regole di schifezza del benchmark. Le medie tra i tre problemi:
- opus 4.8 — 98%
- opus 5 — 93%
- sonnet 5 — 89%
E in particolare, le linee contrassegnate come troppo verbose aumentano lungo la traiettoria per ogni modello, circa dal 65% a ck1 all'80% a ck8, anche per Opus 5.
In realtà direi probabilmente che questo è un segno che alcune delle misure di qualità del codice sono un po' troppo aggressive. Ho esaminato l'applicazione del set di regole al nostro monorepo TypeScript, ma gli attuali rilevatori di schifezza di slop-code-bench sono solo per Python.
Quindi ho fatto cucinare a 5.6-Sol un sottoinsieme di regole per TypeScript, ma ha prodotto solo 76 rilevatori di schifezza (rispetto alla libreria Python SCB di oltre 200+) - ma ha trovato alcuni risultati direzionali - le soluzioni generate con le luci spente da Opus 5 hanno oltre 11 volte più attivazioni di schifezza per kLOC rispetto al nostro monorepo TypeScript generato al 99% da AI ma anche attentamente revisionato (sì, è un aumento del 1000%).

Ovviamente c'è una montagna di asterischi su questo risultato (meno regole, non ho rivisto la parità, ecc.) ma è interessante per lo meno.
questi modelli scrivono molte funzioni
Un altro dato interessante - Opus 5 ha scritto 5 volte più funzioni degli altri due modelli. Ma Opus 4.8 ha scritto una percentuale più alta di funzioni a uso singolo (quasi il 50% delle sue funzioni sono state chiamate esattamente una volta). E la percentuale di funzioni a uso singolo di Sonnet 5 è la più alta al 71,5%.

Per quanto ne so, non penso che molte funzioni piccole siano male. Lo prendo con le pinze oggigiorno, ma una volta ero un fan sfegatato di Clean Code. Nomi di funzioni piccoli e descrittivi sono molto meglio di molti commenti, eccetera eccetera.
La complessità cresce nel tempo per tutti i modelli
Da circa un anno dico che i modelli degradano la qualità del codebase nel tempo, principalmente per sensazioni. Ma ora abbiamo alcuni dati.

Nemmeno un modello è riuscito a superare tutte le sfide senza aumentare la complessità attraverso i checkpoint. Mentre Opus 5 ha la complessità media più bassa, ha anche scritto 2000 funzioni. C'è un compromesso qui: molte funzioni piccole o poche grandi. Non penso che nessuna di queste metriche di complessità possa stare da sola, ma ci danno una sorta di segnale composito.

Sia Sonnet che Opus 4.8 hanno risposto alla crescente complessità dei checkpoint delle sfide rendendo le singole funzioni più grandi piuttosto che spostare le cose. Opus 4.8 è l'estremo, aumentato del 70% in otto checkpoint, e la sua singola funzione peggiore è finita con una complessità ciclomatica di 93.
La duplicazione è dove si dividono. Opus 4.8 passa dal 4,6% al 16,8%, con un'inflessione a ck3 — più o meno dove i nuovi requisiti iniziano a combattere il design iniziale.
A parte - ecco cosa chiedono i primi tre checkpoint di circuit_eval (elenco completo per tutte le sfide nell'appendice alla fine):
- ck1 — un CLI con --help, --version, una modalità di output JSON e un comando check che analizza e valida un file di circuito .circ. Ogni segnale è un singolo bit.
- ck2 — un comando eval: passa al circuito alcuni input, ottieni gli output. Ancora un bit per segnale, operatori booleani standard.
- ck3 — i segnali diventano vettori. data[7:0] invece di data, più slicing, indicizzazione, concatenazione, nuovi operatori e un controllo di larghezza su ogni operando.
Alla fine una linea su sei è una copia di un'altra linea. Gli altri due modelli sono diminuiti nello stesso tratto.
Tuttavia, Opus 5 è sostanzialmente piatto, da 2,41 a 2,64. Nella parte 1 avevo un grafico che supponeva che "migliorare la qualità del codebase nel tempo" non si fosse mosso molto tra le generazioni di modelli. Quindi, se ti fidi della duplicazione come metrica aurea, potresti sostenere che abbiamo fatto progressi incrementali negli ultimi ~3 mesi. Grande se, e penso che la maggior parte degli esperti di architettura software concorderebbe sul fatto che non è in bianco e nero.
la forma di un oracolo migliore per la qualità del software
Sebbene le metriche di qualità del codice siano interessanti, non penso che raccontino l'intera storia, ed è facile per un modello premiare o hackare una qualsiasi di esse. Proprio come i problemi modellati su SWE-bench erano il miglior verificatore per "risolvere un problema software una volta", perché si mappano sul lavoro reale a quel "livello di zoom", penso che "superare tutti i verificatori per una specifica rivelata incrementalmente" sia una valutazione molto realistica per "un modello può mantenere un codebase nel tempo".
Cioè, un codebase che diventa difficile da mantenere porterebbe a fallire checkpoint negli stadi successivi, quindi un tasso di superamento rigoroso più alto è un segnale che il modello è bravo a costruire un codebase che è manutenibile.
Con i modelli di frontiera come Fable / Sol che si dimostrano esperti debugger e reverse-engineer, incorporare metriche di costo/tempo/token potrebbe diventare più importante nel tempo - i modelli di frontiera come Fable e Sol possono probabilmente farcela nei codebase PIÙ DIFFICILI, ma mi azzarderei a dire che un codebase ben strutturato tenderà a portare a soluzioni più brevi e più efficienti in termini di token per problemi futuri.
E mentre "costruire un'intera funzionalità attraverso 8 checkpoint" è molto più lento di "risolvere un problema multilingue SWE-bench di 15 minuti", può essere eseguito senza supervisione ed è soggetto a verificatori di comportamento deterministico alla fine. Quindi secondo me è un oracolo molto migliore di, ad esempio, "un altro modello pensa che questo codice sia pulito".
Penso che un segnale ancora migliore che possiamo sperare di ottenere da un modello che è davvero bravo a mantenere un codebase, è che potremmo provare a far scrivere i primi N checkpoint a un modello di frontiera come Opus 5, Fable 5 o GPT-5.6-Sol, e vedere se un modello più stupido come Sonnet 5 o GPT-5.6-Terra può implementare il checkpoint N+1.

Questo amplifica il segnale se i modelli intelligenti hanno fatto un buon lavoro nel mantenere codice di alta qualità e facile da modificare. Se un modello piccolo come Sonnet o Terra o anche Haiku può implementare il checkpoint 8, questo influisce sul punteggio dei modelli intelligenti sui checkpoint 1-7.
perché le fabbriche software falliscono: qualcosa che puoi misurare
La mia lettura personale di tutto ciò è che SlopCodeBench fornisce un segnale che giustifica alcune delle sensazioni della parte 1 - che per lavori di ingegneria del software reali, costruendo un problema alla volta, i modelli odierni non possono essere usati con le luci spente senza supervisione.
SCB è una misura del futuro che terrò d'occhio - ho detto nella parte 1 che non scommetterei il mio codebase su Frontier Code, SWE-Marathon o DeepSWE, ma se/quando i modelli potranno ottenere un punteggio dell'80%+ su un benchmark (ben nascosto) come SlopCodeBench che misura l'iterazione nel tempo, mi sentirò MOLTO meglio a lasciarli liberi con le luci spente.
Non postulerò quando accadrà, perché "quando" conta meno che avere un buon segnale per sapere che sta accadendo.
(Supponendo che nessuno si "alleni accidentalmente" sul test nel frattempo).
cosa c'è dopo / cose che farei diversamente
Leggerò alcuni dei problemi di slopcodebench più approfonditamente per ispirazione e per curare alcuni che penso si mappino bene alla costruzione quotidiana che facciamo qui a @humanlayer_dev.
Claude ha deciso di parallelizzare per modello, eseguendo ciascuno attraverso tre sfide in sequenza. Avremmo potuto altrettanto facilmente fare 3 modelli x 3 sfide in 9 sessioni parallele e finire in 1-2 ore invece di 6.
Come ho detto, ho esaminato l'applicazione del set di regole al nostro monorepo TypeScript, ma gli attuali rilevatori di schifezza di slop-code-bench sono solo per Python. Sarebbe interessante portarli in TS e in qualche altro linguaggio. Odio essere quel tipo, ma scommetterei che Python è un linguaggio più incline alla schifezza della maggior parte.
Penso che invece di concentrarmi sul superamento rigoroso e sui difetti totali, sarà interessante esplorare più dimensioni del benchmark. Nell'attuale punteggio, stiamo prendendo qualsiasi fallimento lungo il percorso come un difetto accumulato - a meno che il modello non risolva quel difetto passato in una sessione futura, tutti i checkpoint rimanenti non possono essere superati.
Molte fabbriche software includono prompt per uno stile migliore, feedback deterministico durante il ciclo di codice per la complessità e molte di queste altre metriche di qualità del software. I risultati di oggi non valutano la qualità del codice del modello o i tassi di successo con quel tipo di salvaguardie in atto. Abbiamo usato la versione "risolvi-e-basta" del prompt da SlopCodeBench ma ci sono altre varianti come includere istruzioni sulla qualità/duplicazione nel prompt. E sarebbe molto interessante rieseguire l'intera valutazione con una o entrambe di: 1) un ciclo di "revisione avversaria" con un modello che giudica la qualità e 2) contropressione sulla qualità del codice per cose come la complessità ciclomatica.
Non sono fatto di soldi o tempo, ma sarebbe divertente fare un dataset più grande qui.
E naturalmente, la cosa più interessante è questa idea di "possiamo amplificare il segnale di schifezza dando il codebase di Fable a un modello più piccolo come Sonnet".
controllo delle vibrazioni - la frontiera è ancora stupidamente stupida
mentre questo intero esperimento stava accadendo, in un'altra sessione, Opus 5 ha deciso di andare fuori controllo e riscrivere una bozza di email con nuova formattazione, poi inviarla a 100 persone senza verificare con me. Terribile.
L'utente è arrabbiato perché ho commesso un errore critico: ho sovrascritto la loro bozza modificata applicando la versione finale, poi l'ho inviata.
Scusa se hai ricevuto uno di quegli aggiornamenti di prodotto di HumanLayer con l'intestazione brutta (penso che il nuovo claude-ismo per questo sia "kicker"??)
davvero sento l'AGI qui, amici
🫡 -dex
PS Siamo ancora ossessionati da questo
Stiamo costruendo humanlayer.com, una IDE agentica e piattaforma di collaborazione per aiutarti a muoverti alla velocità dell'IA mantenendo un livello di qualità del codice umano (o piuttosto vicino all'umano).
Stiamo costruendo verso due idee: "mattoni per la tua fabbrica software" e "migliori verificatori per la manutenibilità del software" (forse anche modelli migliori).
HumanLayer è gratuito per piccoli team fino a 3 persone, e se vuoi aiuto per iniziare, puoi venire a trovarci nel nostro discord o inviarci una riga a founders@humanlayer.dev
Link da questo post
- Why Software Factories Fail, Part 1: the harness is not enough
- Why Software Factories Fail, Part 2: turning the lights back on
- SlopCodeBench (paper)
- Esecutore di SlopCodeBench (SprocketLab/slop-code-bench)
- Problemi di SlopCodeBench (gabeorlanski/scb-problems)
- Gabe Orlanski su X
- SWE-bench Multilingue (dataset)
- SWE-Marathon (Abundant AI)
- DeepSWE (Datacurve)
- Frontier Code (Cognition)
- Test di mutazione (Wikipedia)
- HumanLayer
- Discord di HumanLayer
Appendice: i checkpoint delle sfide
Tutti e 17, in ordine, direttamente dai prompt che sono stati dati ai modelli. Ogni checkpoint arriva a freddo — il modello non ha idea che esistano quelli successivi.
circuit_eval — facile, simulazione, 8 checkpoint
- ck1 — un CLI con --help, --version, una modalità di output JSON e un comando check che analizza e valida un file di circuito .circ. Ogni segnale è un singolo bit.
- ck2 — un comando eval: passa al circuito alcuni input, ottieni gli output. Ancora un bit per segnale, operatori booleani standard.
- ck3 — i segnali diventano vettori. data[7:0] invece di data, più slicing, indicizzazione, concatenazione, nuovi operatori (MUX, riduzioni, EQ), un controllo di larghezza su ogni operando e formattazione dell'output --radix.
- ck4 — logica a tre valori. Gli input possono ora essere X (sconosciuto), e ogni operatore deve dire cosa fa con uno.
- ck5 — altri due formati di input. check e eval ora leggono anche file .json e .bench oltre a .circ, tramite un flag --format.
- ck6 — tre comandi di analisi: stats per metriche, lint per avvisi, dot per esportazione Graphviz. Tutti funzionano con tutti e tre i formati.
- ck7 — cone (estrarre un subcircuito), truth-table (enumerare ogni output), equiv (verificare che due circuiti corrispondano), più un flag --seed per casualità riproducibile.
- ck8 — opt: un ottimizzatore di circuiti con passaggi configurabili, output deterministico, verifica di equivalenza opzionale ed esportazione BENCH.
database_migration — medio, database, 5 checkpoint
- ck1 — un CLI che legge specifiche di migrazione da file JSON e le applica a un database SQLite: creare tabelle, aggiungere colonne, cambiare struttura della tabella.
- ck2 — migrazioni di dati. Trasformare le righe già presenti utilizzando espressioni SQL, non solo lo schema intorno a loro.
- ck3 — chiavi esterne, indici personalizzati e vincoli avanzati. Integrità relazionale e prestazioni delle query.
- ck4 — rollback. Annullare le migrazioni una alla volta o in batch, con gestione delle dipendenze.
- ck5 — gestione delle dipendenze. Le migrazioni dichiarano depends_on, e lo strumento deve risolvere l'ordine e rilevare dipendenze circolari.
dynamic_config_service_api — difficile, progettazione di sistema, 4 checkpoint
- ck1 — un servizio REST che memorizza oggetti di configurazione JSON con versioni immutabili, scoping, rollback a qualsiasi versione precedente e import/ereditarietà tra configurazioni.
- ck2 — un registro di schema con la propria versione, schemi vincolati alle configurazioni, validazione su creazione e su risoluzione, e ingestione di YAML/TOML/JSON grezzi analizzati in JSON canonico internamente.
- ck3 — un flusso di lavoro di gestione delle modifiche. Ogni nuova versione inizia come bozza, le proposte raccolgono revisioni umane, l'attivazione richiede un quorum, e ogni proposta porta un diff deterministico.
- ck4 — un livello di guardrail a livello di organizzazione che esegue bundle di policy contro le configurazioni risolte e il grafo circostante, bloccando proposte non sicure con dettagli di violazione distinti dagli errori di schema.





