Quando leggere il codice dell'IA non è revisionarlo
Ascolta l'articolo (sperimentale) · 09:54

Uno sviluppatore che riesco a immaginare con chiarezza, perché una sua versione è ovunque in questo momento, ha un flusso di lavoro che sembra responsabile. Lascia scrivere il codice al modello e legge il diff prima di accettarlo. Sta revisionando. Solo che i diff si allungano, la lettura si fa sempre più veloce, e un pomeriggio si accorge di aver accettato codice che ormai non saprebbe cambiare, se dovesse. I progetti costruiti quasi tutti dalla macchina sono quelli in cui a stento sa muoversi. Un progetto che ha scritto a mano tre anni fa gli sembra ancora casa sua. Da qualche parte, lungo la strada, leggere ha smesso di essere revisionare, e niente lo ha annunciato.
A volte leggere è tutto il lavoro
Ecco dove sbaglia la versione forte di questo monito. Per una larga fetta di ciò che accetti in un giorno, leggere il diff è tutto il lavoro, ed eseguirlo di persona sarebbe una messinscena. Una rinomina che il compilatore ha già dimostrato. Un aggiornamento di dipendenza. Un valore di configurazione, una modifica di testo, un commento. Boilerplate che hai scritto cento volte e sai controllare dalla forma. Un blocco di test generati, dove leggere è comunque il passaggio più prezioso, perché è la lettura a scovare il test che non asserisce nulla e diventa comunque verde.
La lettura attenta non è uno strumento debole. Molto prima di tutto questo, l'ispezione del codice trovava più difetti all'ora dei test, e continua a farlo. Quindi il punto non è "esegui sempre il codice". Il punto è che lettura ed esecuzione sono cieche verso bug diversi, e gran parte della discussione che si fa è in realtà una discussione su quale cecità si stia vivendo dentro.
Il vero test è se riesci a prevederlo
La domanda non è mai stata lettura contro esecuzione. È se riesci a prevedere cosa fa il codice senza eseguirlo.
Per una categoria di modifiche ci riesci, e leggere basta. Per un'altra la correttezza non è nel testo che hai davanti. Vive tra le righe, nell'intreccio di due thread che il diff può mostrarti solo uno alla volta. Vive sotto carico, nella query che va bene su dieci righe ed è fatale su dieci milioni. Vive al confine, nell'off-by-one e nel percorso d'errore che il caso positivo scavalca dritto. Vive attraverso la rete, nel fatto che il pezzo nuovo sia davvero collegato alla cosa che lo chiama. Vive nello spazio negativo, nel controllo di autorizzazione che non c'è e nell'eccezione ingoiata in silenzio, vale a dire in una riga che non compare mai nel diff perché non è mai stata scritta. Non puoi arrivare leggendo a un bug che esiste solo a runtime.
L'IA fa valere meno il "sembra giusto"
L'IA affila tutto questo in un modo preciso. Chi revisiona approva il codice sulla base di segnali che fanno le veci della correttezza. Si legge come idiomatico. Ha un'aria sicura. Assomiglia a codice che ha funzionato prima. Un modello linguistico è una macchina tarata per produrre esattamente quei segnali. È bravissimo ad avere l'aria giusta.
Così la scorciatoia più antica della revisione, "sembra a posto", non è mai stata prova più debole che la cosa sia davvero a posto. La rifinitura non è una rassicurazione. È il rischio, perché è puntata esattamente sulla parte di te che stava per far passare la modifica. C'è una ricerca che mostra come chi riceve un assistente capace scriva codice meno sicuro e si senta più certo che sia sicuro. La sicurezza si muove nella direzione opposta al pericolo, e il codice generato pulito è l'input più disarmante che si possa mettere in mano a chi revisiona.
Anche la macchina può eseguirlo
Eseguire il codice non è più solo qualcosa che fai a mano. L'agente può eseguirlo al posto tuo e restituirti i log, uno screenshot, un paragrafo che spiega cosa ha cambiato e perché ne è sicuro. È una cosa reale, e per molte modifiche è tutto lì: i test sono diventati verdi mentre guardavi, lo screenshot mostra il pulsante dove deve stare, e hai finito prima di quanto avresti fatto da solo.
Ma guarda cosa è appena successo. Quella prova è stata prodotta dallo stesso tipo di sistema che ha scritto il codice, puntato sullo stesso bersaglio, cioè avere l'aria giusta. Un log positivo che non hai visto girare è un'affermazione, non un fatto. Puoi persino mettere l'agente a sorvegliare i log, il database, le chiamate in uscita, e chiedergli se tutto tornava, e quella è una leva concreta. Ed è anche lì che ho colto un modello a non guardare davvero, a rispondere con quello che si aspettava di trovare. Quindi affidare l'esecuzione all'agente non elimina la revisione. La sposta di un livello più su, dal diff alla prova. Quando ti dice che i log mostrano X, apri i log e trova X. Tratta il "ha funzionato, ecco la prova" come un'affermazione da confermare, allo stesso modo in cui verificheresti un numero prima di lasciare che il paragrafo di un modello se lo tenga. È la stessa verifica che un ricercatore salta quando una citazione inventata finisce in un articolo pubblicato.
E qui arriva la parte che fa quasi sorridere. Per parecchie piccole modifiche, la cosa più veloce e affidabile che puoi fare è eseguirlo tu stesso. Leggere un muro di log e un riassunto sicuro di sé può costarti più che aprire la cosa e guardarla con i tuoi occhi. Eseguirlo non è l'opzione lenta e diligente a cui ripieghi quando leggere non basta. Metà delle volte è quella rapida.
Il cedimento più comune è il volume
Il cedimento in cui quasi tutti incappano davvero non è affatto sottile. È il volume.
Oltre qualche centinaio di righe, qualsiasi revisione umana degrada in una scorsa, e un agente ti dà qualche centinaio di righe ogni volta che glielo chiedi. Il lavoro di sola revisione è la forma più stancante che il mestiere assume, perché stai ricostruendo l'intenzione di qualcun altro, in uno stile che non è il tuo, a un ritmo che non hai deciso tu. Così crolla, in silenzio, nell'accettazione. Nessuno decide di smettere di revisionare. Cominci a vedere il codice invece di capirlo, e da dentro le due cose sembrano identiche. Il vincolo che conta non è quanto il modello può scrivere. È quanto tu riesci davvero a tenere in testa. Lascialo scrivere oltre quel limite e non stai revisionando, qualunque cosa lo schermo dica che stai facendo.
Adegua la profondità al raggio d'impatto
Questo trasforma la disciplina in qualcosa di più utile del "leggere con più attenzione". Adegua la profondità della revisione al raggio d'impatto, e a quanto è reversibile la modifica.
Una modifica piccola e circoscritta, facile da annullare, merita una lettura veloce e un merge. Una migrazione, un'interfaccia pubblica, una cancellazione, qualsiasi cosa tocchi denaro o accessi, si guadagna la revisione lenta: eseguirla, tracciarla, provare a romperla, che lo faccia tu stesso o che faccia mostrare all'agente il suo lavoro per poi controllare cosa ha davvero fatto, chiunque o qualunque cosa l'abbia scritta. Leggere basta esattamente quando i modi in cui la modifica può fallire sono quelli che i tuoi altri gate già intercettano: il compilatore, i tipi, i test che girano in CI, che tu li esegua a mano o no. Smette di bastare nel momento in cui il fallimento che ti farebbe davvero male è uno che solo l'esecuzione rivelerebbe. Dedicare la stessa attenzione a ogni diff non è diligenza. È un rifiuto di decidere dove sta il rischio.
Ciò a cui rinunci
Sotto quello tecnico c'è un costo più silenzioso. Accettare codice che non hai capito ti sposta, un clic alla volta, dall'essere l'autore del tuo prodotto al suo consumatore. Ti tieni il merito e ti tieni la responsabilità, il pager continua a squillare per te, ma hai ceduto la comprensione su cui entrambi si reggono. C'è chi racconta di aver costruito un'app in un pomeriggio e di essersi sentito stranamente piatto, per poi passare due settimane a farla funzionare davvero e ritrovare se stesso. Non è nostalgia. È la differenza tra possedere la cosa che porta il tuo nome e tenere in mano una copia che non riesci ad aprire.
Io costruisco strumenti che puntano fino in fondo sulla generazione. Uno trasforma una frase in un piano e apre da sé le proprie pull request. Un altro governa intere flotte di agenti. Non sono qui per dire a nessuno di scrivere meno codice con l'IA. Ma ognuno di quegli strumenti presuppone, all'altro capo, una persona che revisiona alla profondità che la modifica merita, e un gate che ti limiti a sbirciare non è un gate. La macchina può produrre il diff. Non può produrre la parte in cui l'hai capito.
Quindi revisiona a colpo d'occhio quanto vuoi, per le modifiche in cui il colpo d'occhio è tutto ciò che serve. Tieni solo una linea netta tra il diff che hai capito e il diff che hai soltanto visto. Il primo è tuo. Il secondo diventa tuo nel momento in cui si rompe, e non gli importerà che sembrava a posto.
Le domande a cui questo articolo risponde
Leggere il diff basta per revisionare il codice generato dall'IA?
Per una larga fetta di ciò che accetti in un giorno sì, ed eseguirlo sarebbe una messinscena: una rinomina che il compilatore ha già dimostrato, un aggiornamento di dipendenza, un valore di configurazione, una modifica di testo, boilerplate che riconosci dalla forma. I test generati sono il caso più chiaro, perché è la lettura a scovare il test che non asserisce nulla e diventa comunque verde. Smette di bastare quando la correttezza non è nel testo che hai davanti: l'intreccio di due thread, la query che va bene su dieci righe ed è fatale su dieci milioni, il percorso d'errore che il caso positivo scavalca dritto, o il controllo di autorizzazione che non compare mai nel diff perché non è mai stato scritto.
L'agente ha eseguito i test e mi dà log verdi e uno screenshot, perché dovrei controllare ancora?
Perché quella prova è stata prodotta dallo stesso tipo di sistema che ha scritto il codice, puntato sullo stesso bersaglio, cioè avere l'aria giusta. Un log positivo che non hai visto girare è un'affermazione, non un fatto. Affidare l'esecuzione all'agente non elimina la revisione, la sposta di un livello più su, dal diff alla prova: quando ti dice che i log mostrano una certa cosa, apri i log e trovala. Ho colto un modello a non guardare davvero e a rispondere con quello che si aspettava di trovare, ed è la stessa verifica che un ricercatore salta quando una citazione inventata finisce in un articolo pubblicato.
Quanto codice scritto dall'IA riesco davvero a revisionare prima che smetta di essere revisione?
Meno di quanto un agente te ne darà, perché ti dà qualche centinaio di righe ogni volta che glielo chiedi e oltre quel punto qualsiasi revisione umana degrada in una scorsa. Il lavoro di sola revisione è la forma più stancante che il mestiere assume, perché stai ricostruendo l'intenzione di qualcun altro, in uno stile che non è il tuo, a un ritmo che non hai deciso tu. Nessuno decide di smettere di revisionare. Cominci a vedere il codice invece di capirlo, e da dentro le due cose sembrano identiche.
Non è più sicuro revisionare ogni modifica alla massima profondità?
No. Dedicare la stessa attenzione a ogni diff non è diligenza, è un rifiuto di decidere dove sta il rischio. Adegua la profondità al raggio d'impatto e a quanto è reversibile la modifica: una modifica piccola e circoscritta, facile da annullare, merita una lettura veloce e un merge, mentre una migrazione, un'interfaccia pubblica, una cancellazione o qualsiasi cosa tocchi denaro o accessi si guadagna quella lenta, in cui la esegui, la tracci e provi a romperla. Eseguirla di persona non è nemmeno il ripiego diligente, perché aprire la cosa e guardarla è spesso più rapido che leggere un muro di log e un riassunto sicuro di sé.
Da leggere dopo
AIQuando l'IA deve filmare la propria revisione
Quando viene aperta una pull request, una mia o una che devo revisionare, ora chiedo all'agente di eseguirla sulla mia macchina, di provare a romperla e di filmarsi mentre lo fa. Un paragrafo può affermare che un test è stato fatto. Una registrazione deve mostrarlo, e decidere cosa significa resta compito mio.
AIL'immagine che tengo in mano. La somma di un anno passato a costruire e scrivere
Ventisei saggi, sei prodotti, una pratica di consulenza e una stagione a misurare cose che avrei potuto semplicemente affermare. Riletti come un'unica trace, eseguono tutti lo stesso meccanismo: l'IA rende gratuita la metà economica di ogni cosa, e la metà costosa cambia indirizzo. Questa è la mappa degli indirizzi (giudizio, risposta, attenzione, la persona), e il motivo per cui la mia fede ha riconosciuto il territorio prima di me.