<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
  <title>Paweł Dubiel Tech Blog</title>
  <link>https://paweldubiel.com/it</link>
  <atom:link href="https://paweldubiel.com/it/rss.xml" rel="self" type="application/rss+xml" />
  <description>Note su AI, modelli linguistici e ingegneria del software.</description>
  <language>it</language>
  <lastBuildDate>Mon, 12 Oct 2026 00:00:00 GMT</lastBuildDate>
<item>
  <title>Ho dato a un agente AI i dischetti dell&apos;Amiga. Dopo una sera Pirates! girava in Unity</title>
  <link>https://paweldubiel.com/it/articles/porting-pirates-amiga-unity</link>
  <guid isPermaLink="true">https://paweldubiel.com/it/articles/porting-pirates-amiga-unity</guid>
  <pubDate>Sun, 11 Oct 2026 22:37:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>agents</category>
  <category>coding</category>
  <category>llm</category>
  <description>Ho dato a un agente di programmazione quattro immagini di dischetti con la versione Amiga di Sid Meier&apos;s Pirates!</description>
  <content:encoded><![CDATA[<p>Ho dato a un agente di programmazione quattro immagini di dischetti con la versione Amiga di Sid Meier's Pirates! del 1990 e gli ho chiesto di portare il gioco in Unity. A lavorare è stato Claude Opus 5.5 in Claude Code. Dopo una sera il gioco si poteva percorrere dalla schermata del titolo, attraverso un duello, una città e la navigazione sulla mappa, fino a una battaglia navale, con la grafica e il sonoro originali. Più importante del ritmo è il modo in cui il risultato è stato verificato: lo stesso copione di decisioni è stato eseguito sul porting in C# e sul codice macchina originale fatto girare in un emulatore di processore. In 802 esecuzioni, cioè circa 6 milioni di righe confrontate, le due versioni hanno mostrato al giocatore la stessa cosa.</p>
<p>Descrivo qui le tappe di questo lavoro perché insieme formano un metodo che si può ripetere con un altro gioco e un altro modello. Alla fine mostro un secondo progetto realizzato con lo stesso schema, il porting di Centurion: Defender of Rome da DOS a JavaScript. Entrambi sono progetti privati di studio: i giochi originali, la loro grafica e il loro sonoro restano protetti dal diritto d'autore e non li distribuisco.</p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-title-screen.webp" alt="La schermata del titolo di Pirates! nel porting per Unity: un galeone con la bandiera pirata al tramonto, disegnato con la grafica originale del 1990." loading="eager" decoding="async" width="1600" height="900"></p>
<p><em>La schermata del titolo in Unity. L'immagine viene decodificata a runtime dai file originali del gioco.</em></p>
<h2 id="dallimmagine-del-dischetto-al-codice-decompilato">Dall'immagine del dischetto al codice decompilato</h2>
<p>L'agente ha cominciato identificando i file. L'immagine di un dischetto Amiga (ADF) è una copia grezza dei settori, quindi sono bastate poche decine di righe di Python per estrarne il contenuto. Il programma del gioco si è rivelato un eseguibile a overlay: un nucleo resta sempre in memoria, mentre altri tre segmenti di codice vengono caricati dal disco quando servono. Ghidra, un decompilatore gratuito, non supporta nativamente questo formato. L'agente ha scritto uno script che dispone tutti i segmenti a indirizzi fissi in un'unica immagine e trasforma 45 salti indiretti verso gli overlay in normali chiamate. In questo modo il decompilatore ha visto circa 630 funzioni come un solo programma.</p>
<p>I dati del gioco hanno riservato una sorpresa. I file con estensione <code>.rez</code> hanno la struttura delle risorse dei computer Macintosh, perché la versione Amiga era un porting da Mac. Una volta riconosciuto il formato, l'agente ha estratto 210 testi, 82 liste di stringhe, i dati delle città per sei epoche, immagini, animazioni, sprite e suoni. I testi si sono rivelati la migliore mappa del codice: il numero della stringa passata alla routine «mostra testo» dice quale schermata del gioco gestisce una data funzione.</p>
<h2 id="tredici-agenti-leggono-il-codice-nove-lo-riscrivono">Tredici agenti leggono il codice, nove lo riscrivono</h2>
<p>Il codice decompilato contava quasi 29 mila righe, senza nomi di funzioni né di variabili. L'agente principale lo ha tagliato in pezzi da circa 2 mila righe e ha affidato ciascuno a un agente separato, con lo stesso brief scritto. Ognuno doveva salvare in un file la descrizione di tutte le funzioni del proprio frammento: formule esatte, costanti, intervalli dei valori casuali, numeri dei testi visualizzati e variabili globali lette e scritte. Il brief conteneva una frase che si è rivelata importante: una formula sbagliata è peggio di una lacuna segnalata. Gli agenti dovevano quindi indicare ciò che non erano riusciti a stabilire e verificare i punti poco chiari nell'assembly. Qui il decompilatore perdeva molti argomenti delle funzioni, perché il compilatore di 35 anni fa usava un tipo <code>int</code> a 16 bit.</p>
<p>La seconda fase ha avuto la stessa suddivisione. Nove agenti hanno riscritto le regole del gioco in C#, ciascuno per il proprio intervallo di indirizzi. Ne sono uscite circa 16 mila righe di codice, e lo stato del gioco è finito in un array di byte indirizzato esattamente come la memoria dell'originale. Non è una soluzione elegante, ma elimina un'intera classe di errori. Il vecchio codice sovrappone liberamente le strutture l'una all'altra e legge le tabelle a partire dal byte che ne precede l'inizio. Un porting costruito su un'immagine della memoria si può tradurre riga per riga e confrontare con l'assembly, e le tabelle di costanti restano dove il codice le cerca. Disegno, sonoro e controlli sono stati sostituiti dagli agenti con chiamate a un'interfaccia che il motore implementa a parte.</p>
<h2 id="loracolo-il-codice-originale-in-un-emulatore-di-processore">L'oracolo: il codice originale in un emulatore di processore</h2>
<p>Leggere il codice decompilato non dimostra che il porting si comporti come l'originale. L'agente ha quindi costruito uno strumento di confronto. Il codice macchina originale per il processore Motorola 68000 gira nell'emulatore Unicorn. Le routine di sistema, cioè menu, finestre di testo, lettura dell'input e disegno, sono state sostituite con funzioni in Python. Queste funzioni rispondono a ogni domanda del gioco seguendo un semplice generatore di decisioni e registrano tutto ciò che il gioco ha mostrato. Il porting in C# riceve l'identica sequenza di decisioni tramite un «giocatore scriptato» che gira fuori da Unity. Alla fine le due registrazioni vengono confrontate riga per riga. I testi contengono l'oro, la consistenza dell'equipaggio, le date e i nomi delle città, quindi la corrispondenza delle registrazioni è un test solido delle regole.</p>
<p>La prima misurazione completa ha dato 800 esecuzioni concordi su 802. Le due discrepanze avevano un'unica causa: l'aritmetica in virgola mobile. Il gioco usa una libreria software che non arrotonda come i processori di oggi. La sua radice quadrata di 81 vale 8,999999999999998 e il gioco tronca i risultati a numeri interi, quindi nel porting il morale dell'equipaggio risultava più alto di un punto per certe proporzioni tra oro ed equipaggio. La correzione è consistita nel riscrivere le routine della libreria istruzione per istruzione: 1.572 istruzioni, 43 routine e 21.701 vettori di test calcolati dal codice originale, senza alcuna differenza. Dopo questa modifica tutte le 802 esecuzioni concordano, e in altre 120 lo stato del gioco è stato confrontato fotogramma per fotogramma nel duello, nella navigazione e nelle battaglie navale e terrestre.</p>
<p>Il confronto ha fatto emergere anche due bug del gioco stesso del 1990: una lettura della mappa attraverso un puntatore nullo quando si attacca una città in diagonale e una divisione per zero quando l'equipaggio scende a zero. In questi punti il porting deve scegliere un comportamento, e lo strumento di confronto ha un interruttore che obbliga l'originale a seguire la stessa strada. Il risultato ha anche dei limiti. Lo strumento non confronta né il disegno né il sonoro, e i percorsi rari, come il matrimonio, la mappa del tesoro completa o i gradi più alti, sono stati esercitati poco.</p>
<h2 id="la-presentazione-e-le-aggiunte-che-nel-1990-non-cerano">La presentazione e le aggiunte che nel 1990 non c'erano</h2>
<p>Lo strato visibile al giocatore è stato costruito dagli agenti in Unity via codice, senza scene già pronte. Immagini e animazioni vengono decodificate dalle risorse originali, gli sprite prendono i colori dalla palette della schermata corrente e la musica è stata renderizzata in file audio emulando il sequencer a quattro canali del gioco. L'agente pilotava il gioco in esecuzione dalla riga di comando, catturava schermate e le guardava. Così sono venuti a galla alcuni difetti che nessun test delle regole intercetta, per esempio l'assenza del sonoro nella versione per browser, perché la conversione dell'audio richiedeva il programma ffmpeg, che non era installato nel sistema.</p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-world-map.webp" alt="La mappa dei Caraibi nel porting per Unity: isole con città, la nave del giocatore con l&#x27;indicatore di rotta e nubi di tempesta." loading="lazy" decoding="async" width="1600" height="900"></p>
<p><em>La navigazione sulla mappa. Lo sfondo nasce da una griglia del terreno di 160 per 200 caselle e dalle tile originali.</em></p>
<p>Dopo le prime partite di prova ho chiesto tre modifiche. La domanda sulla data di arrivo della flotta del tesoro era, nell'originale, la protezione contro la copia e richiedeva il manuale cartaceo; ora il quiz resta, ma negli «appunti del capitano» compare la risposta corretta. L'elenco delle città mostrava soltanto i dati della città, perché il gioco dava per scontato che il giocatore avesse una mappa stampata; ora la città scelta è segnata su una mappa dei Caraibi. La schermata del duello ha ricevuto una tabella con la forza, il morale e l'arma di entrambe le parti, disposta come nell'originale. Le aggiunte si possono disattivare e i test di confronto girano senza di esse, in modo che le registrazioni continuino a coincidere con il codice del 1990.</p>
<p><img src="https://paweldubiel.com/assets/pirates-amiga-original-duel-openretro.webp" alt="Una schermata del gioco originale su Amiga: due schermidori davanti a un muro, sotto il titolo del duello e la tabella Force, Morale, Weapon." loading="lazy" decoding="async" width="640" height="400"></p>
<p><em>Il duello nell'originale. Fonte della schermata: OpenRetro Game Database.</em></p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-duel-panel.webp" alt="Il duello nel porting per Unity: schermidori sul ponte di una nave, sotto il titolo e una tabella con forza, morale e arma di entrambe le parti." loading="lazy" decoding="async" width="1600" height="900"></p>
<p><em>La stessa schermata nel porting. I numeri della tabella vengono letti in tempo reale dallo stato del duello.</em></p>
<p><img src="https://paweldubiel.com/assets/pirates-unity-port-city-chart.webp" alt="Una mappa dei Caraibi con la città di Port-de-Paix evidenziata, la posizione del giocatore e un riquadro con i dati della città e la bandiera francese." loading="lazy" decoding="async" width="1600" height="900"></p>
<p><em>Un'aggiunta rispetto all'originale: la città scelta su una mappa dei Caraibi.</em></p>
<h2 id="centurion-lo-stesso-schema-in-javascript-e-con-un-gameplay-esteso">Centurion: lo stesso schema in JavaScript e con un gameplay esteso</h2>
<p>Il secondo progetto è Centurion: Defender of Rome, un gioco per DOS del 1990, portato in JavaScript e sull'elemento Canvas, senza emulatore. I passi sono stati gli stessi, con nomi diversi. L'eseguibile andava prima decompresso, perché era stato compresso con lo strumento EXEPACK. Cinque moduli del gioco (battaglia terrestre, arena dei gladiatori, corsa delle bighe, battaglia navale e introduzione) stavano in un file di overlay e usavano un unico segmento dati condiviso. Lo stato della campagna lavora su una copia viva dei 64 kilobyte di quel segmento, perché il motore del gioco fa affidamento sull'overflow a 16 bit, sulla divisione intera e sui byte con segno, che i numeri in virgola mobile di JavaScript da soli non riproducono. Il salvataggio coincide con il formato originale byte per byte, cosa che i test verificano.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-title-screen.webp" alt="La schermata del titolo di Centurion nel porting per browser: la scritta CENTURION sopra una mappa del Mediterraneo, un pannello con i crediti e i pulsanti Start Game, Difficulty e Game Options." loading="lazy" decoding="async" width="1070" height="800"></p>
<p><em>La schermata del titolo di Centurion nel browser, con la grafica originale.</em></p>
<p>Qui sono andato oltre il porting fedele. Ho aggiunto un interruttore per le regole estese, disattivato per impostazione predefinita: la fusione delle legioni e più legioni in una stessa provincia, i veliti armati alla leggera, gli elefanti da guerra e lo sbarco dal mare. Il codice di questo porting è stato scritto da modelli diversi rispetto a Pirates: per la maggior parte da Gemini 3.8 Flash e in parte da <code>gpt-6.1-sol</code> di OpenAI eseguito tramite Codex. La scelta è dipesa dagli strumenti che avevo sottomano, non da un confronto tra modelli.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-game-options.webp" alt="Il menu delle opzioni di gioco nel porting di Centurion: la voce Extra Features: OFF, il livello di difficoltà, salvataggio e caricamento, e accanto il mandato del Senato con il grado e lo stato del tesoro." loading="lazy" decoding="async" width="1070" height="800"></p>
<p><em>Il menu delle opzioni. La prima voce attiva le regole estese che nell'originale non c'erano.</em></p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-province-screen.webp" alt="La schermata della provincia Italia nel porting di Centurion: la veduta della città, il menu dei giochi con la costruzione dell&#x27;anfiteatro e lo stato della provincia: umore, tributo, truppe." loading="lazy" decoding="async" width="1086" height="818"></p>
<p><em>La schermata della provincia con il menu dei giochi.</em></p>
<h2 id="i-problemi-in-cui-gemini-si-è-imbattuto-con-centurion">I problemi in cui Gemini si è imbattuto con Centurion</h2>
<p>La maggior parte del tempo è andata nei punti in cui il codice decompilato o i nomi dei file suggerivano qualcosa di diverso da ciò che il gioco fa davvero. Cinque esempi dagli appunti del progetto:</p>
<ul>
<li><strong>Overlay senza dati.</strong> I cinque moduli del gioco stanno in un solo file, <code>OVL0.OVL</code>, e vengono caricati allo stesso indirizzo, ma tutti usano un segmento dati condiviso. Il solo codice di un overlay aperto in Ghidra non mostrava quindi né stringhe né tabelle. Uno script ha unito ciascun overlay al segmento dati in cinque eseguibili sintetici, e solo allora il decompilatore ha collegato il codice dei minigiochi alle strutture della campagna.</li>
<li><strong>I confini delle province conquistate.</strong> Tracciare il contorno di una provincia a partire dalla mappa delle aree cliccabili con il mouse dava linee spigolose, che non combaciavano con la mappa disegnata a mano. Il codice ha rivelato un altro meccanismo: nell'immagine della mappa ogni provincia ha un percorso nascosto, largo un pixel e di colore scuro, e una tabella nei dati indica un punto di partenza per ciascuna delle 27 province. Il gioco ridipinge quel percorso con il colore dell'impero, cominciando dal punto di partenza, e il porting fa lo stesso.</li>
<li><strong>Fotogrammi che tornano indietro.</strong> Il ciclo di gioco originale girava a 9–12 Hz, mentre un browser disegna 60 volte al secondo. In tre punti uno sprite arretrava per un attimo di un fotogramma. Il globo dell'introduzione ruota facendo scorrere 14 colori della palette in 10 passi, ma il primo passo nella tabella vale zero; far scorrere la palette a ogni passo provocava uno scatto dei continenti a ogni rotazione. Nella marcia delle coorti e negli affondi dei gladiatori è stato necessario riprodurre esattamente l'ordine: prima il fotogramma intermedio, poi il cambio di posizione.</li>
<li><strong>Nomi di file fuorvianti.</strong> Le bitmap <code>BB1.CBM</code> e <code>BB2.CBM</code> sembravano stendardi di battaglia e, disegnate nella parte alta dello schermo, coprivano l'intero campo di battaglia. Il codice le carica soltanto quando il computer non ha una scheda VGA: sono sfondi a tutto schermo per le più vecchie schede EGA e CGA. Dalla stessa routine è emerso che lo schieramento prima della battaglia ha due fasi. La scelta della formazione sostituisce l'elenco delle tattiche disponibili, e la manovra di Canne compare solo dopo aver scelto il cuneo.</li>
<li><strong>Musica appena udibile.</strong> Dopo aver decodificato 17 brani e 24 strumenti del driver della scheda audio AdLib, le melodie erano corrette ma suonavano a circa −55 dB. Il disassemblaggio del driver ha mostrato che a ogni nota esso sottrae un quarto della velocity della nota dall'attenuazione memorizzata nello strumento. Una sola riga di codice ha restituito circa 32 dB. Un secondo difetto stava dal lato del browser: con note molto brevi, annullare le variazioni di volume programmate nella Web Audio API cancellava l'attacco del suono ancora in corso e silenziava la nota.</li>
</ul>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-battle-tactics.webp" alt="Una battaglia terrestre nel porting di Centurion: l&#x27;elenco di cinque tattiche per la formazione a cuneo, tra cui la Cannae Tactic, e i reparti schierati sul campo di battaglia." loading="lazy" decoding="async" width="1086" height="818"></p>
<p><em>La seconda fase dello schieramento prima della battaglia: le tattiche disponibili per la formazione a cuneo.</em></p>
<p>Un lavoro a parte sono state le corse delle bighe nel Circo Massimo. Lì una biga non è un'unica immagine. Bitmap separate per ogni combinazione di tre classi di bighe, quattro colori degli aurighi, quattro azioni, sedici inclinazioni in curva e tre fotogrammi di galoppo avrebbero significato oltre 2.300 fotogrammi, perciò gli autori del gioco hanno costruito in memoria un albero di nodi da 16 byte. Ogni nodo punta all'elemento successivo sullo stesso livello e al proprio primo figlio, e contiene un indice di fotogramma, una tabella di offset per i fotogrammi successivi dell'animazione e un flag di visibilità. La radice sono i quattro cavalli. La cassa della biga ha un offset orizzontale aggiuntivo in cui la fisica della curva scrive un'inclinazione da 0 a 15 pixel, e l'auriga è suo figlio e ne eredita la posizione. Per questo in curva l'auriga si inclina insieme alla cassa, mentre i cavalli continuano a correre lungo l'asse della pista. I rami con l'asse che si spezza e con il relitto che si ribalta esistono sempre; hanno soltanto il flag di visibilità disattivato.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-chariot-sprite-tree.webp" alt="Lo schema dell&#x27;albero degli sprite della biga in Centurion: il nodo con i quattro cavalli, il nodo della cassa in tre classi, i nodi degli stati di incidente, quattro animazioni dell&#x27;auriga e la biga assemblata senza inclinazione e con un&#x27;inclinazione di 12 pixel." loading="lazy" decoding="async" width="920" height="540"></p>
<p><em>L'albero degli sprite della biga ricostruito dai dati del gioco. Lo schema è stato realizzato nel progetto a partire dalle risorse originali decodificate.</em></p>
<p>Nemmeno la pista è costruita con tile. Il gioco espande 72 coppie di coordinate memorizzate in 368 punti di controllo e divide la posizione trasversale sulla pista in 16 corsie. Dalla corsia dipende la velocità di sicurezza in curva, calcolata come (numero della corsia + 15) × 4: lungo il muro interno vale 60, lungo la barriera esterna 116–120. La corsia interna offre il percorso più breve, ma entrare nel tornante sopra quella soglia inclina la cassa, spinge la biga verso l'esterno e fa scattare un'estrazione casuale per il ribaltamento, tanto più probabile quanto maggiore è l'eccesso. Il segno rosso sulla barra della velocità mostra al giocatore quella soglia.</p>
<p><img src="https://paweldubiel.com/assets/centurion-js-port-circus-track-physics.webp" alt="La geometria della pista del Circo Massimo: rettilinei, zone di frenata e tornanti evidenziati a colori sull&#x27;immagine dello stadio, e un grafico della velocità di sicurezza che cresce da 60 nella corsia interna a 120 in quella esterna." loading="lazy" decoding="async" width="880" height="500"></p>
<p><em>I 368 punti della pista e la velocità di sicurezza in curva in funzione della corsia.</em></p>
<h2 id="che-cosa-resta-di-questo-lavoro-oltre-ai-giochi">Che cosa resta di questo lavoro oltre ai giochi</h2>
<p>Ho messo per iscritto il metodo sotto forma di skill, cioè un insieme di istruzioni che un agente carica quando riceve un compito simile. Contiene tre principi ricavati da entrambi i progetti. Le regole del gioco si portano fedelmente, mentre la presentazione si sostituisce con un'interfaccia. Il porting conserva la disposizione della memoria dell'originale. Del risultato non ci si fida finché non supera il confronto con il codice originale. Nella skill sono finiti anche i brief per gli agenti di analisi e di porting e gli script del progetto Pirates.</p>
<p>La conclusione più interessante riguarda i fan, non gli agenti. Chi ha un gioco che ama e a cui da anni manca qualcosa oggi può rifarlo a modo suo, in fretta e con poca spesa, senza il codice sorgente. In Pirates il quiz che richiedeva il manuale stampato ora dà la risposta, ed è comparsa una mappa che il gioco non aveva mai avuto. In Centurion ho aggiunto regole che l'originale non aveva: fusione delle legioni, elefanti da guerra e sbarchi dal mare. Una volta che le regole del gioco sono normale codice in C# o JavaScript, la modifica successiva è una normale modifica al codice, non una patch del binario. Allo stesso modo si può portare un gioco su un motore più veloce o su un'altra piattaforma: Centurion gira nel browser, e Pirates si compila per Linux e per il browser. Il metodo non è nemmeno legato ai vecchi giochi. Un decompilatore, un emulatore di processore e il confronto dei registri funzionano allo stesso modo per un programma più recente; più codice significa più lavoro, non un approccio diverso.</p>
<h2 id="fonti">Fonti</h2>
<ul>
<li>Materiali miei, da entrambi i progetti: appunti dell'analisi del codice, brief per gli agenti, il report dello strumento di confronto (802 esecuzioni, elenco delle differenze trovate), la descrizione del porting di Centurion e le sue specifiche. Non sono pubblicati.</li>
<li>National Security Agency, <a href="https://github.com/NationalSecurityAgency/ghidra" rel="noopener noreferrer">Ghidra</a>, la suite di reverse engineering usata per decompilare entrambi i giochi.</li>
<li><a href="https://www.unicorn-engine.org/" rel="noopener noreferrer">Unicorn Engine</a>, l'emulatore di processori usato per eseguire il codice 68000 originale.</li>
<li>OpenRetro Game Database, <a href="https://openretro.org/amiga/pirates" rel="noopener noreferrer">la pagina di Pirates! per Amiga</a>, fonte della schermata del gioco originale.</li>
</ul>]]></content:encoded>
</item>
<item>
  <title>Un orizzonte METR più lungo non significa compiti proporzionalmente più difficili</title>
  <link>https://paweldubiel.com/it/articles/un-orizzonte-metr-piu-lungo-non-significa-compiti-proporzionalmente-piu</link>
  <guid isPermaLink="true">https://paweldubiel.com/it/articles/un-orizzonte-metr-piu-lungo-non-significa-compiti-proporzionalmente-piu</guid>
  <pubDate>Sun, 11 Oct 2026 15:03:00 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <category>papers</category>
  <category>llm</category>
  <category>agents</category>
  <category>benchmarks</category>
  <description>Un team vuole stabilire se alla prossima versione di un agente si possano affidare compiti di programmazione più lunghi.</description>
  <content:encoded><![CDATA[<p>Un team vuole stabilire se alla prossima versione di un agente si possano affidare compiti di programmazione più lunghi. Confronta quindi i risultati di un benchmark espressi nel tempo di cui una persona ha avuto bisogno per svolgere il lavoro. È facile leggere un risultato del genere come un'indicazione di quanto lavoro si possa già cedere all'agente.</p>
<p>Questa interpretazione richiede però di verificare se un lavoro umano più lungo significhi davvero un compito corrispondentemente più difficile per l'AI. Se in un certo intervallo i compiti hanno una difficoltà simile per l'agente, un piccolo miglioramento del suo tasso di successo può spostare il risultato attraverso un ampio intervallo di minuti.</p>
<p>Per scegliere un agente serve allora un'informazione in più: come è cambiata la probabilità di portare a termine gli stessi compiti. Il solo moltiplicatore del tempo può sopravvalutare la differenza tra le versioni, se stiamo confrontando proprio un tratto del benchmark in cui il tempo distingue poco la difficoltà.</p>
<p><a href="https://metr.org/time-horizons/" rel="noopener noreferrer">METR chiama questa misura</a> <a href="https://paweldubiel.com/it/glossary/time-horizon">time horizon</a>. Nella variante con soglia al 50% è il tempo di lavoro umano per il quale la curva adattata prevede che metà dei tentativi dell'agente riesca. È una media per i compiti di quella durata, non una garanzia per ciascuno di essi. Qui non misuriamo il tempo di esecuzione dell'AI stessa.</p>
<p>Nel preprint <a href="https://arxiv.org/abs/2610.12466" rel="noopener noreferrer"><em>On the estimation and validity of AI time horizons—a statistical look at the METR plot</em></a> Drew T. Nguyen e William Fithian analizzano proprio la conversione del tempo in difficoltà. Il lavoro, che rientra nella valutazione dell'AI e nella statistica ed è stato pubblicato per la prima volta l'8 ottobre 2026, individua nei dati di METR un tratto quasi piatto tra 2 e 30 minuti di lavoro umano. I compiti di questo intervallo avevano in media una difficoltà simile per gli agenti esaminati.</p>
<h2 id="una-piccola-variazione-delle-probabilità-può-spostare-di-molto-la-soglia">Una piccola variazione delle probabilità può spostare di molto la soglia</h2>
<p>L'esempio che segue è una mia semplificazione didattica, non il risultato dello studio. Abbiamo tre compiti, A, B e C, che a una persona richiedono rispettivamente 3, 10 e 30 minuti. Ciascuno dei due agenti esegue ogni compito 100 volte nello stesso ambiente. Registriamo un successo oppure un fallimento.</p>





























<table><thead><tr><th>Compito</th><th>Tempo umano</th><th>Successi dell'agente più vecchio</th><th>Successi dell'agente più recente</th></tr></thead><tbody><tr><td>A</td><td>3 minuti</td><td>50 su 100</td><td>52 su 100</td></tr><tr><td>B</td><td>10 minuti</td><td>49 su 100</td><td>51 su 100</td></tr><tr><td>C</td><td>30 minuti</td><td>48 su 100</td><td>50 su 100</td></tr></tbody></table>
<p>Per chiarezza trattiamo queste frequenze come probabilità note con esattezza e uniamo i punti con curve decrescenti. L'agente più vecchio interseca il 50% a 3 minuti, quello più recente a 30. L'orizzonte cresce di dieci volte, anche se su ogni compito il tasso di successo è aumentato di soli 2 punti percentuali. Su 300 tentativi per agente il numero di successi è passato da 147 a 153.</p>
<p>Tutti e tre i compiti e tutti i fallimenti restano nella misura. Scegliamo soltanto il punto in cui la curva interseca la soglia; non filtriamo né premiamo nulla. Il costo di questo test ipotetico è di 600 tentativi completi dell'agente. In un esperimento reale numerosità simili non permettono di considerare certa una differenza di 2 punti percentuali. Bisogna adattare una curva e stimare l'incertezza.</p>
<p>L'esempio mostra l'operazione di lettura dell'orizzonte su una curva quasi piatta. In uno studio la sua forma va prima determinata a partire da molti compiti e sistemi. Se in un altro intervallo la curva scende molto più in fretta, lo stesso moltiplicatore dell'orizzonte richiede un aumento maggiore delle probabilità di successo. Per questo i passaggi da 3 a 30 minuti e da 30 minuti a 5 ore non sono per definizione porzioni uguali di progresso.</p>
<h2 id="il-tempo-umano-va-adattato-alla-difficoltà-per-lai">Il tempo umano va adattato alla difficoltà per l'AI</h2>
<p>Il punto di partenza è una tabella dei risultati: quale compito ha eseguito un dato agente, quante volte e con quale esito. Conosciamo anche il tempo umano e la famiglia del compito. Non conosciamo un unico numero oggettivo che ne descriva la difficoltà per l'AI.</p>
<p>La baseline degli autori assume che ogni successivo raddoppio del tempo umano aumenti la difficoltà dello stesso passo. Usa una pendenza delle curve comune a tutti gli agenti; questi differiscono per livello di capacità. È un termine di confronto più solido della regressione separata per ogni sistema, applicata in origine.</p>
<p>La prima proposta sostituisce il passo costante con una curva monotona appresa di tipo spline: tratti raccordati in modo liscio, che possono crescere più o meno in fretta. Un tempo più lungo continua a non abbassare la difficoltà prevista, ma la crescita non deve essere uniforme.</p>
<p>La seconda proposta, chiamata nel lavoro Model 2, si basa sulla <a href="https://paweldubiel.com/it/glossary/item-response-theory">item response theory, IRT</a>. Dallo schema di successi e fallimenti stima congiuntamente le capacità degli agenti e la difficoltà dei compiti. Tiene conto anche della somiglianza tra compiti appartenenti a una stessa famiglia e di un'ulteriore variabilità dei risultati dei tentativi. Così molte ripetizioni della stessa coppia agente–compito non vengono trattate come altrettante informazioni nuove e indipendenti sull'intero benchmark.</p>
<p>Il primo passo in cui la baseline e i nuovi metodi divergono è la conversione del tempo umano in difficoltà. I risultati degli agenti in ingresso restano gli stessi. Un nuovo adattamento può quindi cambiare l'orizzonte senza che cambi nemmeno una risposta dell'AI.</p>
<h2 id="gli-stessi-risultati-di-gpt-4o-hanno-dato-un-orizzonte-diverso">Gli stessi risultati di GPT-4o hanno dato un orizzonte diverso</h2>
<p>Gli autori rianalizzano i risultati registrati di METR Time Horizon 1.1: 228 compiti e 26 sistemi di AI. Nella figura 1 l'orizzonte di GPT-4o è di 7,2 minuti secondo la baseline con pendenza comune e di 4,4 minuti secondo il Model 2. Sono due stime ricavate dagli stessi tentativi, non un peggioramento del funzionamento di GPT-4o né un confronto del costo della sua inferenza.</p>
<p>Una curva più flessibile potrebbe semplicemente adattarsi meglio al rumore. Gli autori verificano quindi la previsione dei risultati su intere famiglie di compiti non utilizzate durante l'adattamento. In una validazione in cinque parti suddividono 79 famiglie, e non i singoli tentativi di uno stesso compito. Entrambi i nuovi metodi hanno stime puntuali migliori in tutte le 12 combinazioni di metrica e di modalità di ponderazione dei risultati. Questo significa un errore minore nella previsione del successo, non un aumento del tasso di successo degli agenti stessi. <a href="https://arxiv.org/html/2610.12466v1#S2.SS5" rel="noopener noreferrer">§2.4–2.5 e figura 2</a></p>
<p>Il vantaggio non è distribuito in modo uniforme. L'adattamento migliora soprattutto per i sistemi dell'epoca di GPT-4, i cui orizzonti attraversano l'intervallo piatto indicato. Per i sistemi più forti le curve confrontate quasi coincidono. Le stime per i singoli sistemi sono inoltre molto meno conclusive del risultato complessivo. <a href="https://arxiv.org/html/2610.12466v1#A1" rel="noopener noreferrer">Appendice A</a></p>
<details>
<summary>Dettagli dell'esperimento</summary>
<p><strong>Dati e impostazione.</strong> È una nuova analisi dei risultati pubblici di METR, non una nuova serie di esecuzioni degli agenti. I compiti riguardano il lavoro sul software e hanno una valutazione automatica del successo. Il tempo umano è di norma la media geometrica dei tempi delle esecuzioni riuscite; una parte dei valori proviene da stime di esperti. Il tempo di inferenza dell'AI non è una variabile dell'orizzonte misurato.</p>
<p><strong>Scelta del modello e del checkpoint.</strong> Gli autori non addestrano nuovi LLM né ne scelgono il checkpoint migliore. Utilizzano i risultati registrati di precedenti valutazioni di METR. GPT-4o è un modello accessibile via API con un numero di parametri non reso noto. Questa analisi non stabilisce il suo protocollo interno di selezione dei pesi. Gli adattamenti statistici usano il metodo della massima verosimiglianza; il Model 2 applica l'algoritmo EM e l'approssimazione numerica degli integrali. I grafici della forma delle curve usano i dati completi, mentre il confronto della qualità predittiva descritto sopra usa la suddivisione per famiglie.</p>
<p><strong>Metriche.</strong> L'insieme comprende il marginal log score, cioè la <a href="https://paweldubiel.com/glossary/cross-entropy" hreflang="pl">cross-entropy [Polski]</a> binaria, il Brier score e misure smussate dell'errore in prossimità delle soglie del 50% e dell'80%. La cross-entropy penalizza fortemente le previsioni sicure ma sbagliate; il Brier score misura il quadrato della differenza tra la probabilità e l'esito successo/fallimento. Un valore più basso è migliore. Ciascuna delle quattro metriche è stata calcolata con tre modalità di ponderazione: compiti di pari peso, famiglie di pari peso e la variante intermedia usata da METR. Non le sommiamo in un unico miglioramento percentuale.</p>
<p><strong>Costo e incertezza.</strong> La nuova analisi richiede adattamenti statistici, anche separati per le suddivisioni di validazione, ma non ulteriori chiamate agli LLM valutati. Il lavoro non riporta risparmi di tempo o di denaro derivanti dall'adozione dello stimatore. Gli intervalli di incertezza del confronto principale sono calcolati sulle famiglie di compiti. Un risultato puntuale migliore per ogni metrica non significa che ogni singolo contrasto sia statisticamente conclusivo.</p>
</details>
<h2 id="i-compiti-più-lunghi-richiedono-di-verificare-di-nuovo-la-scala">I compiti più lunghi richiedono di verificare di nuovo la scala</h2>
<p>Il lavoro non stabilisce la causa del tratto piatto e non mostra che esso comparirà in ogni benchmark. Non dimostra nemmeno che i compiti di METR rappresentino l'intero lavoro di un programmatore. Gli autori non mettono in discussione la tendenza esponenziale osservata del progresso; studiano che cosa significhino gli intervalli sull'asse del tempo di lavoro umano.</p>
<p>L'applicazione pratica consiste nell'affiancare all'orizzonte un grafico delle probabilità di successo per intervalli fissi di compiti. Questo permette di vedere se un suo salto corrisponde a un chiaro cambiamento di affidabilità. Quando si aggiungono compiti più lunghi al proprio benchmark conviene verificare, su famiglie tenute da parte, se il loro tempo continui a prevedere la difficoltà per l'agente, prima di prolungare la curva usata finora.</p>
<h2 id="fonti">Fonti</h2>
<ul>
<li>Drew T. Nguyen, William Fithian, <a href="https://arxiv.org/abs/2610.12466" rel="noopener noreferrer"><em>On the estimation and validity of AI time horizons—a statistical look at the METR plot</em></a>, preprint, 2026, v1. arXiv:2610.12466; DOI: 10.48550/arXiv.2610.12466. <a href="https://arxiv.org/html/2610.12466v1" rel="noopener noreferrer">Testo completo</a>.</li>
<li>METR, <a href="https://metr.org/time-horizons/" rel="noopener noreferrer"><em>Task-Completion Time Horizons of Frontier AI Models</em></a>, definizione della misura, procedura di valutazione e limiti. La pagina segnala che il grafico non viene più aggiornato attivamente.</li>
</ul>]]></content:encoded>
</item>
<item>
  <title>SemiAnalysis confronta i limiti degli abbonamenti AI</title>
  <link>https://paweldubiel.com/it/articles/semianalysis-confronta-i-limiti-degli-abbonamenti-ai</link>
  <guid isPermaLink="true">https://paweldubiel.com/it/articles/semianalysis-confronta-i-limiti-degli-abbonamenti-ai</guid>
  <pubDate>Sat, 10 Oct 2026 11:06:52 GMT</pubDate>
  <dc:creator>Paweł Dubiel</dc:creator>
  <category>ai</category>
  <description>Nella sua analisi del 5 ottobre 2026 SemiAnalysis confronta i limiti effettivi degli abbonamenti AI.</description>
  <content:encoded><![CDATA[<p>Nella sua <a href="https://newsletter.semianalysis.com/p/anthropic-subscriptions-offer-5x" rel="noopener noreferrer">analisi del 5 ottobre 2026</a> SemiAnalysis confronta i limiti effettivi degli abbonamenti AI. Gli autori verificano come i diversi tipi di <a href="https://paweldubiel.com/glossary/token" hreflang="pl">token [Polski]</a> fanno avanzare gli indicatori di consumo e convertono la quota disponibile nel costo di un utilizzo identico tramite API.</p>
<p>Secondo le loro misurazioni, con le proporzioni di token ipotizzate per il lavoro degli agenti, Claude con Opus 5.5 offre un valore circa cinque volte superiore, ai prezzi di listino delle API, rispetto agli abbonamenti OpenAI con GPT-6.1 Sol messi a confronto. È una misura dell'utilizzo disponibile; l'efficacia dei modelli nello svolgere i compiti qui non è stata confrontata.</p>
<p>L'articolo mostra anche gli effetti del dimezzamento della quota di token nel nuovo Pro 200 di OpenAI e descrive un test A/B individuato dagli autori, in cui uno degli account aveva limiti inferiori di circa il 20%. Il valore di un abbonamento dipende quindi anche dalle regole di conteggio del consumo, che cambiano nel tempo.</p>
<p>Il confronto finale dei servizi degli intermediari è disponibile per gli abbonati paganti.</p>]]></content:encoded>
</item>
</channel>
</rss>