Che cosa hanno cambiato i modelli più capaci
Dall'agosto 2026, ho esplorato quanto reverse engineering può eseguire un agente con l'accesso a un programma e un modo per verificarne il lavoro. La maggior parte della mia esperienza deriva dalla ricostruzione di giochi, in particolare Touhou. Man mano che ho cambiato modello, i repository hanno tenuto traccia di ciò che è riuscita a recuperare ciascuna sessione.
Gran parte di questo lavoro mira alla ricostruzione esatta: compiliamo il sorgente mantenuto in una toolchain storica con versioni fisse e controlliamo se riproduce la funzione di destinazione. Quando un modello successivo riesce dove il lavoro precedente si era bloccato, le modifiche alla fonte mostrano cosa ha reso possibile quel progresso.
Le variabili temporanee necessitavano di vite sovrapposte
Gran parte della logica della funzione di attacco TH09 era già stata ricostruita, ma il compilatore memorizzava ancora i risultati temporanei in modo diverso dall'originale. Il problema rimanente era quanto tempo occorreva a quei risultati per rimanere in vita e quando la loro conservazione poteva essere riutilizzata.
Un GPT-6-Sol record di sessione ha segnalato questa mancata corrispondenza dopo aver testato diverse disposizioni ordinarie del codice sorgente. Quando GPT-6.1-Sol ha esaminato nuovamente il problema, ha proposto un'ipotesi utile sulla durata di queste variabili temporanee.
La funzione ha prodotto risultati temporanei e li ha copiati in posizioni di animazione. In C++, un risultato temporaneo rimane attivo finché l'espressione che lo utilizza non termina. Raggruppare le operazioni reali in un'unica espressione ha mantenuto vivi insieme i risultati, quindi il compilatore non poteva più riutilizzare la stessa memoria per tutti loro.
Un risultato ha ancora spazio di archiviazione condiviso con un valore utilizzato successivamente per i controlli di collisione. Dare a quel valore la propria durata ha risolto la rimanente sovrapposizione. Dopo diversi esperimenti mirati, una ricompilazione pulita dal sorgente ha confermato che l'intera funzione corrispondeva a.
Sono interessato a come la scoperta e i test si siano supportati a vicenda. L’ipotesi sulla durata temporanea degli oggetti ha dato all’agente AI una nuova direzione. Il feedback del compilatore ha aiutato a perfezionare quell'ipotesi in una disposizione del codice sorgente che corrispondesse.
Un diverso grafico del flusso di controllo
Una seconda funzione TH09 mostra perché questa nuova direzione può essere importante. In questo caso, l’ostacolo era il modo in cui diversi rami condividevano il loro lavoro finale. Il lavoro precedente di GPT-6.1-Sol faceva corrispondere parti della funzione, ma i rami si univano ancora in modo diverso dall'originale.
GPT-6-Astra ha cambiato il grafico del flusso di controllo circostante. I percorsi principali conducono ora ad un aggiornamento finale condiviso e al ritorno. In quella struttura sorgente, il compilatore ha combinato i rami nello stesso modo dell'originale. La funzione completa corrispondeva e un controllo di ricostruzione separato lo ha confermato.
La modifica della rappresentazione ha aperto uno spazio di ricerca più produttivo. Entrambi i casi mi danno un motivo per prendere sul serio le capacità generali del modello: un agente può continuare a provare variazioni locali per molto tempo prima di trovare un modo migliore per esprimere il lavoro circostante.
Le sessioni successive hanno anche ereditato il codice precedente e i tentativi falliti già documentati. Questo lavoro accumulato faceva parte del loro vantaggio. La cronologia permette di esaminare le scoperte e le verifiche; un confronto controllato aiuterebbe a separare il contributo del modello da quello dell’esperienza ereditata.
Questo è ciò che rende la domanda interessante per me. Alcuni progressi sono arrivati dalla ricerca di una nuova rappresentanza. Gran parte del lavoro rimanente prevedeva il test di diverse disposizioni del codice sorgente rispetto a un compilatore familiare. Quanto di tutto ciò richiede un’ampia capacità di ragionamento? Quanto potrebbe imparare un modello lavorando ripetutamente con quel compilatore e quel codice?
Perché un modello di IA specializzato potrebbe funzionare bene?
Touhou ci dà una ragione concreta per aspettarci che quell'esperienza sia d'aiuto. Gran parte del codice del gioco proviene dallo stesso autore, ZUN, quindi le abitudini ricorrenti sono un presupposto di partenza ragionevole. I repository lo confermano con esempi utili: cicli correlati e disposizioni di supporto hanno fornito ipotesi attraverso i giochi.
Questi modelli di origine diventano più specifici quando includiamo il compilatore. In una particolare versione e insieme di opzioni, piccole modifiche all'origine possono produrre differenze ripetibili nel codice macchina. Alcune di queste differenze sono sorprendentemente oscure.
In TH095, ad esempio, anche il nome di una variabile locale potrebbe influenzare dove VC7.1 l'ha memorizzata. Lo spostamento della sua dichiarazione non ha risolto il layout di archiviazione. Tuttavia, una precedente funzione in background aveva rivelato un modello di denominazione che influenzava la scelta del compilatore. Ciò ha suggerito un'ipotesi più promettente per ricostruire Supervisor::LoadDat.
Il riutilizzo di quel modello per la variabile della dimensione del file ha prodotto il layout richiesto senza aggiungere spazio di archiviazione. La funzione completa quindi corrispondeva.
Questo è un dettaglio molto specifico che un modello di intelligenza artificiale generica potrebbe non conoscere quando incontra per la prima volta il problema. Un modello specializzato per questo compilatore potrebbe vedere molti casi simili e apprendere quali variazioni del codice sorgente vale la pena testare per prime.
L'opportunità è particolarmente chiara nei problemi di abbinamento finale in cui ne comprendiamo già il comportamento. Ci stiamo quindi chiedendo quale disposizione ordinaria del codice sorgente questo compilatore trasforma nelle istruzioni osservate. La specializzazione potrebbe aiutare il modello a proporre tali forme in modo più efficiente, mentre l’obiettivo determina ancora quali ipotesi sopravvivono.
Gli schemi utili devono conservare il loro contesto. TH08 usa una versione di Visual C++ precedente a quella di TH095 e TH09. TH04 usa un altro compilatore dell’epoca DOS. La ricostruzione del codice del giocatore richiedeva ipotesi diverse sugli schemi del sorgente e sul collegamento del codice in un eseguibile. Lo stesso autore ci dà un’aspettativa iniziale, ma ogni obiettivo indica se è applicabile. Un modello specializzato dovrebbe imparare a distinguere questi contesti.
Dove dovrebbe essere archiviata questa esperienza?
Prima di decidere di insegnare questi modelli attraverso l'addestramento dei modelli, esaminerei la conoscenza che già conserviamo nel repository. Nel saggio precedente ho scritto che diventa la memoria di lavoro del progetto. Quella memoria include lezioni del compilatore, insieme alla fonte e agli esperimenti falliti che li hanno resi utili.
Recuperando quel record, un agente può iniziare con un risultato noto e verificare come lo abbiamo raggiunto. Può anche evitare alternative che hanno già fallito nello stesso contesto. Il punto di partenza migliora senza modificare i parametri addestrati del modello.
Durante la ricostruzione della funzione di TH09 per la creazione di nemici, una sessione GPT-6-Luna-max ha preso un'ipotesi dal relativo codice sorgente TH08. Il codice precedente suggeriva come organizzare il ciclo e gestire gli errori al suo interno. Le prove di TH09 hanno fornito i dettagli specifici del gioco. Le ricostruzioni dall'origine hanno confermato che la funzione completa corrispondeva.
"Il modello non conosceva quella stranezza del compilatore" e "il modello non poteva usarlo" sono problemi diversi. Il recupero può risolvere il primo, ma trasformare questo fatto in un candidato utile richiede ancora lavoro. E se il codice sorgente candidato fallisce, il modello deve decidere cosa significherà il risultato per il suo prossimo tentativo. Conoscere il modello rilevante è solo l’inizio di quel processo.
Per questo motivo, includerei in ogni confronto un modello di intelligenza artificiale generico più piccolo con un buon recupero. Fornire la stessa libreria di esperienze ci aiuterebbe a identificare ciò che la formazione aggiunge: una migliore generazione di candidati, decisioni migliori dopo il feedback o entrambi.
Imparare il prossimo esperimento utile
Quelle decisioni dopo il feedback sono ciò che mi piacerebbe di più studiare. Nella ricostruzione agentica, il modello propone una spiegazione e la mette alla prova rispetto al programma. Anche quando il codice sorgente candidato fallisce, il risultato può restringere le possibilità rimanenti e suggerire un prossimo esperimento più utile.
Consideriamo nuovamente l'esempio dei risultati temporanei. La sua fonte finale mostra la soluzione che ha funzionato, ma il percorso verso quella fonte contiene più informazioni. Ciascuno dei seguenti esperimenti ha contribuito a identificare ciò che ancora doveva cambiare.
| Esperimento | Cosa ci ha insegnato il suo risultato |
|---|---|
| Prova un modo diverso per copiare i risultati | Il codice di copia cambia, ma la funzione cambia ancora. |
| Utilizzare direttamente i valori restituiti | La copia segue lo schema originale, ma l'archiviazione temporanea differisce ancora. |
| Mantieni valide tutte le variabili temporanee contemporaneamente | Ottengono un'archiviazione separata, ma uno si sovrappone comunque a un valore utilizzato successivamente per i controlli di collisione. |
| Mantenere separato il valore del controllo collisioni | Una ricompilazione pulita dalla fonte conferma la corrispondenza completa. |
Esperimenti selezionati dalla ricostruzione della funzione di attacco sopra, raggruppati in base a ciò che ci hanno insegnato.
Un registro dell'addestramento che mantenga questa sequenza può insegnare più della sola fonte finale. Collega ogni modifica proposta a un risultato osservato e alla decisione successiva. Anche mantenere le variazioni inefficaci è importante: dicono a un agente successivo quali ipotesi sono già state testate in quel contesto.
Vorrei che il modello imparasse come utilizzare il feedback. Un risultato neutro è un motivo per riconsiderare la variazione; una mancata corrispondenza modificata può indicare un'altra causa. Quando le modifiche locali smettono di essere informative, l'agente dovrebbe essere in grado di rivisitare la rappresentazione originale o ispezionare nuovamente le prove.
Imparare a fare queste scelte richiede autonomia. A volte il passaggio successivo utile è ispezionare un altro chiamante anziché compilare un'altra modifica. Una rigida sequenza di riscritture richieste eliminerebbe quella scelta, insieme a parte del comportamento che vogliamo che il modello impari.
Perché il reverse engineering è interessante per l'apprendimento per rinforzo
La ricostruzione limitata ci offre un ambiente pratico per studiare queste scelte. Una volta fissate le versioni di destinazione e del compilatore, molti esperimenti di origine producono un feedback rapido e ripetibile. L'agente può compilare un candidato, ispezionare la mancata corrispondenza e utilizzare tale osservazione per scegliere il passaggio successivo.
L’apprendimento per rinforzo potrebbe addestrare il processo decisionale attraverso il feedback che riceve. Un candidato accettato con una verifica definita ci dà un risultato concreto, mentre la sequenza dei tentativi ci permette di osservare quanto lavoro è stato necessario per raggiungerlo.
Esistono già ricerche a sostegno di questa direzione. LLM4Decompile studia modelli specializzati per la decompilazione. AutoDecompiler addestra il perfezionamento multi-turn utilizzando il feedback del compilatore e dell'esecuzione. I loro studi si concentrano sul recupero funzionale. Per questo lavoro, li userei come punto di partenza per il compito correlato di trovare fonti che corrispondano all'output di un compilatore storico.
Per raggiungere un compito così ben definito, tuttavia, potremmo prima dover stabilire quali risorse possiede una funzione o ideare un nuovo modo di osservare il comportamento del programma durante l’esecuzione. In TH08, ad esempio, una differenza di collisione riportava al modo in cui il programma originale gestiva i calcoli in virgola mobile. Prima che l'agente potesse testare una correzione utile, doveva capire cosa misurare.
Ciò suggerisce un altro ruolo per un modello ampiamente capace: in primo luogo, contribuire a rendere il problema controllabile. Una volta effettuato questo controllo, possiamo indagare fino a che punto può arrivare una politica di ricerca appresa.
Quando il controllo di verifica è sbagliato
Quando una verifica viene usata per l’addestramento, anche la sua copertura entra nell’ambiente di apprendimento. Chiamo oracle quel riferimento o verificatore. Persino una risposta ripetibile va interpretata in base a ciò che verifica davvero.
TH08 ha mostrato quanto si può nascondere al di fuori di quella copertura. Alcune funzioni ricostruite hanno superato i confronti esatti con costanti in virgola mobile errate. Il comparatore aggiustava gli indirizzi trasferiti prima di controllare le istruzioni, ma controllava i valori dietro quegli indirizzi solo quando erano stati esplicitamente registrati per la verifica. Altri riferimenti letterali potrebbero passare senza che i loro valori vengano esaminati.
Per colmare questa lacuna, un controllo più ampio ha rilevato costanti errate nelle funzioni che avevano già superato la verifica. In un calcolo, il codice sorgente ricostruito aggiungeva 1.0f, mentre l'originale aggiungeva 32.0f.
Un modello premiato dal vecchio controllo di verifica potrebbe imparare a produrre una ricostruzione errata. Non abbiamo addestrato un modello RL utilizzando quel controllo. L'errore che abbiamo osservato riguardava il controllo stesso. Ma se lo usassimo come ricompensa, lo stesso punto cieco diventerebbe parte dell’ambiente di apprendimento.
Un test funzionale può avere un punto cieco simile. La ricerca che utilizza il fuzzing differenziale sui decompilatori LLM ha rilevato differenze comportamentali al di fuori dei test forniti. Dobbiamo quindi comprendere una prova di superamento in termini dei casi che esercita. Allo stesso modo, la corrispondenza di un'istruzione deve essere intesa in termini di byte e dati che verifica.
Prima di utilizzare uno dei due tipi di controllo di verifica come ricompensa, lo testerei con risultati deliberatamente errati. Vorrei anche mantenere l'accettazione finale separata dal codice sorgente che l'agente AI può modificare. Il modello deve superare la verifica ricostruendo correttamente il programma. Altrimenti, la semplice copia di un array di byte dalla destinazione potrebbe ingannare un ingenuo sistema di punteggio senza recuperare codice sorgente utile.
Migliorare lo studente e migliorare il suo strumento di verifica appartengono allo stesso problema di ricerca. Man mano che lo studente migliora nell'ottimizzare il feedback che gli forniamo, anche comprendere quel feedback diventa più importante.
Un confronto che vale la pena fare
Con questi controlli in atto, inizierei il confronto su una famiglia di attività VC7.1 fissa. Innanzitutto, stabilirei le linee di base per un forte modello di intelligenza artificiale generale e uno più piccolo. L'aggiunta della conoscenza del repository al modello più piccolo mostrerebbe quali cambiamenti nel recupero. Da lì, la specializzazione supervisionata e una versione addestrata con RL ci permetterebbero di esaminare cosa aggiunge la formazione.
Per rendere informativi questi confronti, ciascun modello riceverebbe le stesse prove e strumenti target. Per i confronti specifici della formazione, manterrei fisso anche il modello base e le conoscenze disponibili. Prove ripetute aiuterebbero a distinguere una strategia di ricerca affidabile da una soluzione candidata che ha successo per caso.
Separerei quindi due condizioni iniziali: ricostruire una funzione dalle sue istruzioni e chiudere le ultime differenze nel sorgente mantenuto. Un modello di IA specializzato potrebbe essere eccellente per il secondo compito, mentre un modello di IA generico svolge gran parte del lavoro necessario per raggiungerlo. Misurarli separatamente rivelerebbe quella divisione del lavoro.
Entrambi i compiti necessitano di esempi di test esclusi dall'addestramento e dal recupero. I giochi Touhou correlati condividono il codice motore. Escludere un gioco dall'allenamento potrebbe comunque lasciare funzioni quasi identiche nel set di allenamento. Invece, escluderei interi gruppi di codice sorgente correlato e manterrei le loro risposte verificate fuori sia dai dati di addestramento che dalla libreria di recupero.
Per questi esempi, il risultato sarebbe corrispondenze complete e verificate in modo indipendente. Budget uguali per le proposte dei candidati o i tentativi di compilazione aiuterebbero a confrontare la qualità della ricerca. La misurazione del tempo e dei costi totali, inclusa la compilazione, mostrerebbe se tale qualità produce un flusso di lavoro efficiente. I costi di formazione dovrebbero essere misurati separatamente.
Entrambe le misurazioni contano. Una proposta economica può portare a un flusso di lavoro costoso se comporta più compilazioni che non forniscono informazioni utili. Al contrario, un modello più lento può essere più economico se trova prima un esperimento utile. Il confronto dovrebbe includere questi costi.
Il conteggio dei risultati accettati mantiene inoltre in prospettiva i progressi intermedi. Un TH09 candidato al replay-save sembrava promettente perché la funzione compilata aveva le dimensioni previste, ma un confronto completo ha comunque rilevato differenze sostanziali. I cambiamenti nel modo in cui il compilatore organizza le istruzioni possono anche far sembrare un candidato più vicino al risultato atteso senza risolvere il problema di fondo. Tale diagnostica può guidare il prossimo esperimento, ma convaliderei qualsiasi ricompensa per "avvicinarsi" rispetto al controllo completo di accettazione.
Sarei interessato allo schema tra questi risultati. Se un modello di intelligenza artificiale specializzato funziona bene all’interno di una famiglia di compilatori familiare, tale vantaggio sopravvive a un cambiamento nella toolchain? E una volta che entrambi i modelli di intelligenza artificiale hanno un buon recupero, quanto aggiunge ancora l’addestramento? Le risposte ci aiuterebbero a decidere dove ciascun tipo di modello è più utile.
Che tipo di agente AI suggerisce questo?
Se i modelli si rivelano utili in diverse fasi, una soluzione utile potrebbe essere un ampio agente con accesso a un modello di intelligenza artificiale specializzato. Una volta che un'attività diventa una ricerca familiare del compilatore, potrebbe richiedere il modello di intelligenza artificiale specializzato per i candidati. Se i risultati smettono di avere senso, l’agente più ampio potrebbe tornare all’evidenza target o indagare sulla misurazione stessa.
In questo modo, la specializzazione diventa uno strumento che l’agente può scegliere man mano che l’indagine si sviluppa. L'agente mantiene la libertà di cambiare direzione che ha reso possibili i progressi precedenti.
Ciò deriva naturalmente dal cambiamento industriale che ho descritto nel saggio precedente. Essere in grado di eseguire molti più esperimenti cambia il modo in cui organizziamo il lavoro. Ci dà anche una ragione per chiederci quali decisioni necessitano di un ampio giudizio e quali migliorano attraverso l’esperienza ripetuta con una particolare imbarcazione.
Per ora il modello generale più forte si è guadagnato il suo posto nel mio lavoro risolvendo problemi che avevo lasciato aperti. Sono proprio questi successi a farmi studiare il processo: quanto dipendeva dall’ampiezza delle sue capacità, e quanto potrebbe fare un modello addestrato specificamente per questo tipo di ricostruzione?
I repository ci offrono un modo per testare la domanda. Vorrei utilizzare quel record per creare il confronto e vedere cosa impariamo.
Evidenze e attribuzione del modello
Le note dettagliate sulle prove includono i confronti registrati e il contesto degli esperimenti.
Gli esempi descrivono i confronti storici a livello di funzione registrati nei commit collegati. I controlli di runtime dell'intero gioco sono traguardi separati. I record di origine e corrispondenza sono stati esaminati il 13 ottobre 2026.
L'etichetta TH09 gpt-dots significa GPT-6-Astra. Il modello associato a gpt-web è cambiato nel tempo, quindi l'etichetta da sola non può identificare il modello utilizzato in una specifica esecuzione. I nomi espliciti dei modelli negli altri commit citati forniscono l'attribuzione registrata. Queste cronologie non includono misurazioni coerenti dei costi o dell'impegno per ogni esecuzione.
- TH09 durata degli oggetti temporanei: la revisione del contesto precedente e la ricostruzione completa verificata da una ricompilazione pulita dall'origine.
- TH09 Front callback: aree diagnostiche che non corrispondevano, il nuovo grafico del flusso di controllo di Astra e il relativo controllo di ricompilazione accettato.
- Conoscenze del compilatore: TH095 riutilizzo del comportamento del bucket di identificatori, TH04 codice sorgente del giocatore e ordine dei linker e Luna ricostruzione completa della funzione di creazione del nemico di TH09.
- Controlli e diagnostica: TH08 audit costante in virgola mobile, TH08 indagine numerica e TH09 ricostruzione con salvataggio replay.
I confronti proposti tra modelli specializzati e la formazione RL sono esperimenti futuri. Le storie dei progetti li motivano. Per questo saggio non è stato valutato alcun modello specializzato addestrato.