C’è un modo molto comodo per raccontare la modernizzazione del software: si prende un programma scritto quarant’anni fa, lo si passa a un modello AI, si ottiene codice in un linguaggio più recente e si annuncia che il problema è risolto. La presentazione funziona. Il sistema informativo, di solito, pretende qualche dettaglio in più.
Il 19 ottobre 2026 OpenAI ha pubblicato due valutazioni dedicate ai linguaggi meno rappresentati nei dati di addestramento: una chiede ai modelli di ricostruire un motore compatibile con SQLite in venti linguaggi; l’altra misura la migrazione di programmi COBOL verso C++, Java, Kotlin, Python e Rust. I risultati dichiarati sono notevoli. Ma la parte interessante non è la classifica: è il criterio scelto per dire che una migrazione è corretta.
Il codice può cambiare completamente. Il comportamento osservabile, invece, deve restare quello atteso. È qui che finisce la traduzione e comincia l’ingegneria.
Una percentuale alta non è un collaudo in produzione
Secondo i dati diffusi da OpenAI, nel benchmark MultiLangBench GPT-6 Astra raggiunge una media dell’87,4% di test superati sui venti linguaggi, contro il 26,8% attribuito a GPT-5.6 Sol. Nel caso specifico di COBOL, il risultato dichiarato sale dal 10,9% al 72,1%. Nel benchmark separato sulla migrazione COBOL, GPT-6.1 Sol arriva al 97,9% al livello di ragionamento più alto. Sono risultati riportati dall’organizzazione che sviluppa i modelli, non una certificazione indipendente di affidabilità sui sistemi di un’azienda.
È una distinzione meno spettacolare di un grafico, ma molto più utile. Un benchmark definisce un insieme di prove e misura quanto bene un sistema le supera. Non dimostra, da solo, che siano stati rappresentati tutti i vincoli di un’applicazione reale: archivi storici, dipendenze esterne, finestre batch, procedure operative, formati scambiati con altri software e comportamenti che nessuno ha mai documentato perché “hanno sempre funzionato così”.
La valutazione COBOL è particolarmente interessante perché richiede parità byte per byte degli output osservabili su test nascosti. Non basta che il programma nuovo produca un risultato plausibile o che un revisore trovi il codice elegante. Deve restituire esattamente ciò che il contratto di prova si aspetta. Resta un limite fondamentale: l’equivalenza vale rispetto agli input e agli output effettivamente coperti dai test, non rispetto a ogni stato possibile del sistema.
Il dettaglio che costa denaro: un decimale
Immaginiamo un calcolo che produca 1,239 e debba essere conservato con due cifre decimali. Se il comportamento storico tronca la parte eccedente, il valore diventa 1,23; se una riscrittura arrotonda, diventa 1,24. Entrambi i programmi compilano. Entrambi possono superare decine di test scritti su numeri interi. Solo uno replica la regola originale. Su un movimento isolato sembra una sciocchezza; su un processo che elabora molti movimenti, la differenza diventa una riconciliazione che non torna.
Non è una peculiarità inventata per rendere interessante il COBOL. La documentazione IBM della clausola ROUNDED specifica che, nelle operazioni aritmetiche pertinenti, l’eccesso di cifre frazionarie viene troncato se l’arrotondamento non è richiesto. Esistono differenze tra operazioni, rappresentazioni e opzioni del compilatore: proprio per questo non si può sostituire una regola effettiva con una generica intuizione sul significato di “numero decimale”.
Un assistente che traduce correttamente la sintassi ma cambia il trattamento degli importi non ha semplicemente prodotto un piccolo bug. Ha modificato una regola di business, magari senza sapere che fosse una regola. E la documentazione, in certi sistemi, è il programma stesso: compresi i suoi comportamenti scomodi.
La qualità di una migrazione non si misura da quanto il nuovo codice somiglia a quello vecchio, ma da quanto è difficile dimostrare una differenza di comportamento.
MultiLangBench misura una capacità reale, ma non quella che molti immaginano
Il repository pubblico di MultiLangBench descrive un compito concreto: implementare funzionalità compatibili con SQLite 3.40.1 in un linguaggio assegnato. Ogni test parte da un database iniziale, applica una query e usa SQLite reale per verificare il risultato ottenuto. È un modo intelligente per avere un riferimento comune anche quando i linguaggi sono molto diversi.
Il README specifica che circa 24.000 prove sono state convertite dalla suite TCL di SQLite, ma raccomanda per le esecuzioni ordinarie un sottoinsieme di 272 test, per contenere i costi. Questo dettaglio non invalida il benchmark; rende però essenziale sapere quale sottoinsieme è stato effettivamente usato quando si confrontano percentuali. Il repository consente di ispezionare le condizioni della valutazione, mentre la seconda valutazione, quella di migrazione COBOL, è descritta nell’annuncio con i suoi criteri principali.
Costruire una parte funzionante di un database in COBOL, Fortran o OCaml è un segnale serio di capacità di programmazione. Ma non coincide con il prendere un’applicazione aziendale esistente, capirne tutte le dipendenze e sostituirla senza regressioni. Sono due problemi diversi. Confonderli serve a vendere una promessa, non a pianificare un progetto.
Prima di cambiare linguaggio, bisogna rendere visibile il contratto
La difficoltà maggiore di una migrazione legacy spesso non è trovare un programmatore che sappia scrivere il linguaggio di destinazione. È ricostruire ciò che il sistema promette ai suoi interlocutori. Un programma può parlare con altri servizi tramite file a lunghezza fissa, codici di errore, ordinamenti impliciti, campi riempiti di spazi, conversioni di date e convenzioni sui record mancanti. Nessuno di questi elementi diventa irrilevante perché il nuovo codice è più moderno.
Ecco perché partirei da un inventario di comportamenti, non da una lista di file da convertire. Non perché sia romantico conservare il passato, ma perché senza una base di confronto non esiste una definizione verificabile di successo.
Un protocollo di migrazione che si può controllare
- Congelare il comportamento osservabile. Identificare input, output, formati, codici di ritorno, ordinamento dei record, regole decimali e dipendenze esterne. Versionare anche le configurazioni del compilatore e dell’ambiente che influenzano i risultati.
- Costruire un corpus di confronto. Affiancare ai casi ordinari gli estremi: importi negativi, zeri, arrotondamenti, record assenti, date anomale, duplicati e confini di campo. Quando possibile usare dati anonimizzati o sintetici, non copiare indiscriminatamente dati reali.
- Eseguire vecchio e nuovo sistema sugli stessi casi. Confrontare byte, record e risultati economici; per gli effetti esterni servono controlli aggiuntivi su transazioni, ordine degli eventi e idempotenza.
- Classificare ogni differenza. Un output diverso può essere un difetto della migrazione oppure un comportamento storico che si vuole correggere. Nel secondo caso la modifica deve essere deliberata, documentata e approvata: non nascosta nella conversione.
- Ripetere le prove a ogni modifica. La suite di regressione diventa parte del prodotto. Senza questo passaggio, il primo rilascio può sembrare corretto e quello successivo riaprire problemi già risolti.
La parità byte per byte è un ottimo strumento quando il contratto riguarda un output deterministico. Non basta invece, da sola, per misurare concorrenza, latenze, isolamento transazionale, recovery dopo un guasto o effetti collaterali su sistemi terzi. La strategia di test deve seguire l’architettura effettiva, non il formato più facile da confrontare.
Il costo non è generare il nuovo codice
Quando si parla di AI nello sviluppo, la discussione si concentra spesso sul prezzo per richiesta o sulla velocità con cui viene generato un file. Sono metriche legittime, ma parziali. Il costo reale di una migrazione comprende l’inventario dei contratti, l’ambiente riproducibile, i test di regressione, la gestione delle differenze, il rilascio controllato e il periodo in cui vecchio e nuovo sistema devono convivere.
È lo stesso problema che emerge quando la produzione di codice aumenta senza aumentare la capacità di verificarlo. Più output non significa automaticamente più software consegnato. E il caso delle regressioni al confine fra compilatore e ABI ricorda che la correttezza non è una proprietà della sola sorgente: dipende anche dagli strumenti e dalle interfacce attraversate.
Il progresso dei modelli sui linguaggi meno comuni è una buona notizia per chi mantiene sistemi che il mercato tende a considerare invisibili. Può rendere accessibili porzioni di codice difficili da comprendere, accelerare la preparazione dei test e ridurre il costo delle prime conversioni. Ma se un’azienda compra soltanto la velocità di riscrittura, rischia di scoprire il prezzo dell’equivalenza quando i conti non tornano.
La domanda giusta per il prossimo progetto
Non chiederei a un fornitore soltanto quanti programmi COBOL riesce a convertire in una settimana. Chiederei quali comportamenti è in grado di dimostrare invariati, con quali dati, quali limiti di copertura e quale procedura di ritorno al sistema precedente. Se la risposta è un benchmark generico e una demo, siamo ancora alla presentazione commerciale.
L’AI sta migliorando anche dove il codice pubblico è scarso. Il risultato del 19 ottobre merita attenzione proprio perché porta la verifica al centro del discorso. Sarebbe un peccato usarlo per tornare alla vecchia illusione: che basti scrivere più in fretta per fare ingegneria migliore.
Domande frequenti
Che cosa misura MultiLangBench?
Valuta la capacità di costruire un motore compatibile con SQLite 3.40.1 in venti linguaggi, usando test derivati dalla suite SQLite. Non misura direttamente l’affidabilità di una migrazione aziendale in produzione.
Il 97,9% nel benchmark COBOL significa che una migrazione è sicura?
No. È un risultato dichiarato da OpenAI su un insieme definito di test nascosti che confrontano gli output byte per byte. Una migrazione reale richiede anche verifica di dipendenze, dati, transazioni, casi limite e procedure operative.
Perché arrotondamenti e troncamenti contano nella migrazione COBOL?
Perché un cambiamento nella gestione dei decimali può modificare importi e riconciliazioni anche se il programma compila. Il comportamento effettivo dipende da istruzioni, tipi, rappresentazioni e opzioni del compilatore: va testato, non presunto.
Come si verifica l'equivalenza tra un programma COBOL e uno riscritto?
Si definiscono input e output osservabili, si costruisce un corpus di casi ordinari e limite, si eseguono le due versioni sugli stessi dati e si confrontano risultati, formati, errori ed effetti esterni. Le differenze devono essere classificate e approvate prima del rilascio.
