Why NextWhy Next
Torna all'elenco
💻 SviluppoLettura di 10 min

Quando l'AI dice "è fatto", il meccanismo per non crederle

Gli agenti di coding AI dicono di aver finito quando non hanno finito. Dichiarano che i test passano senza averli eseguiti, dicono di aver corretto un bug senza averlo riprodotto. La storia del cancello di verifica con cui uno sviluppatore solitario, che scrive quasi tutto il codice insieme all'AI, ha reso il completamento riconoscibile solo per prove, non per parole.

In sintesi

L'abitudine più pericolosa di un agente AI è riportare come finito un lavoro che non è finito. La soluzione non è che una persona diffidi ogni volta, ma piantare nel sistema un cancello che riconosce il completamento solo per prove. Il hook che blocca la chiusura, i tipi di prova (output dei comandi, diff, riproduzione, verifica incrociata) e perché questo è il muscolo chiave dell'era dell'AI.

In questa pagina

Lavorando con gli agenti di coding AI c'è una frase che mi frega più spesso di ogni altra: "È tutto fatto."

L'agente la dice con troppa facilità. Senza aver davvero eseguito i test dice "i test passeranno", e senza nemmeno aver riprodotto il bug dice "ho corretto la causa". Se leggi il codice, sembra plausibile. Ma quando poi lanci davvero i comandi, circa la metà delle volte non è finito. Dopo averlo vissuto a lungo sono arrivato a una conclusione. Il problema non è che l'AI mente, ma che ero io a dover decidere ogni volta, come persona, se credere o no a quella frase.

Non è un problema di fiducia, è un problema di prova

Lavorando da solo, scrivo quasi tutto il codice insieme all'AI. Così mi capita decine di volte al giorno di decidere "posso accettare questa modifica?". All'inizio, ogni volta leggevo il resoconto dell'agente e, se qualcosa mi insospettiva, lanciavo io stesso i comandi per verificare. Il problema di questo metodo è che la verifica dipende da me. Nei giorni stanchi, nei giorni di fretta, nel giorno in cui faccio per la decima volta un lavoro simile, lascio correre con un "avrà detto che è fatto, quindi sarà fatto". Ed è proprio da quelle volte che lascio correre che nascono i guai.

Così ho cambiato direzione. Invece di diffidare io ogni volta, ho fatto in modo che fosse il sistema a esigere le prove. Ho piantato nell'harness un cancello che impedisce all'agente di chiudere il turno solo perché dice "è finito". Il completamento non è più una dichiarazione, ma un controllo da superare.

La radice di questa idea è semplice. Più l'AI sforna codice a basso costo, più il collo di bottiglia si sposta dalla produzione alla verifica. Quando il costo di produrre codice tende a zero, "fidarsi che sia giusto" diventa in proporzione il lavoro più costoso. E allora quel lavoro costoso non va affidato all'umore del momento di una persona, ma trasformato in una procedura imposta automaticamente.

Il hook che blocca la chiusura

In concreto, uso un hook che si inserisce nel momento della chiusura. Quando l'agente dichiara di aver finito il lavoro e sta per chiudere il turno, un attimo prima parte un controllo. Il controllo esige una cosa sola: "Mostrami la prova che hai finito."

Se la prova non c'è, la chiusura viene rifiutata. L'agente viene rimandato indietro, con un messaggio del tipo "non hai dimostrato il completamento, quindi continua". A quel punto l'agente finalmente esegue i test, lancia i comandi, incolla l'output. La cosa buffa è che in questo processo circa la metà delle volte è lui stesso a dire "ah, in effetti non era finito" e a completare davvero il lavoro rimasto. Non era affatto vero che fosse finito quando aveva detto che lo era.

Il punto chiave è che questo cancello è una macchina, non una persona. Che io sia stanco o di fretta, il cancello è ugualmente rigoroso. La mia disciplina vacilla, ma quella del hook no. Ho trasformato la verifica da abitudine a infrastruttura.

Cosa accetto come prova

E allora cosa accetto come "prova"? Ne uso quattro tipi.

  1. Output dei comandi. Se i test passano, ci deve essere l'output reale del test runner. Non un "passeranno", ma il log di quando sono passati davvero. Se la build è andata a buon fine, il log della build; se il lint è pulito, l'output del lint.
  2. diff. Cosa è stato cambiato deve vedersi come diff. Non "ho corretto questa funzione" a parole, ma le righe modificate così come sono. È qui che si filtra se l'ambito della modifica corrisponde al resoconto.
  3. Riproduzione. Se hai corretto un bug, devi avere in coppia la prova che quel bug si riproduceva davvero prima della correzione e la prova che è sparito dopo. Senza before/after, "l'ho corretto" è solo una supposizione.
  4. Verifica incrociata. Le modifiche importanti le faccio revisionare da un altro modello. Quel che scrive Claude lo guarda Codex, e ognuno individua i punti ciechi dell'altro. Si scova molto meglio che quando un solo modello giudica il proprio lavoro da sé.

Ciò che questi quattro hanno in comune è che sono tutti fatti riproducibili. Non opinioni, ma output incollabili. È qui che sta il motivo per cui l'AI non può fare da giudice ultimo. Definire il criterio di "buono" e stabilire quale output soddisfa quel criterio resta in fin dei conti compito di una persona. Solo che, invece di emettere quel giudizio a mano ogni volta, la procedura di giudizio la si fissa nel codice.

Perché questo fa bene anche alla persona

Dopo aver eretto il cancello c'è stato un effetto che non mi aspettavo. Non solo l'agente si è disciplinato: anche io mi sono trovato meglio.

Prima, il mio lavoro era leggere il resoconto e dubitare "sarà davvero fatto?". Adesso quel lavoro lo fa il hook. Ciò che mi arriva è già corredato di prove nel momento in cui arriva. Io esamino le prove, non parto dal verificare se le prove ci siano. È come se la linea di partenza del giudizio si fosse spostata avanti di un passo.

E questo è anche un registro che lascio a me stesso in futuro. Il perché una certa modifica è sicura resta insieme all'output dei comandi di allora. Un mese dopo, quando mi chiederò "ma perché l'ho fatto così?", la motivazione è lì accanto al commit.

Il muscolo nuovo da allenare è uno solo

Si parla di varie competenze su come lavorare con l'AI, ma quella che mi è rimasta più impressa è questa: non delegare la verifica a te stesso, delegala al sistema.

La tecnica di scrivere buoni prompt invecchia quando cambia il modello. Il trucco che ieri funzionava, sul nuovo modello non funziona. Ma la disciplina del "riconoscere il completamento solo per prove" è uno strato che sta sopra il modello, quindi non invecchia. Qualunque modello si usi, per quante generazioni cambi il modello, il cancello che esige le prove resta utile. Anzi, più il modello diventa intelligente, più sbaglia in modo plausibile, e quindi il valore del cancello sale.

L'AI ci ha alleggerito dal peso di scrivere codice. In cambio ci ha lasciato il compito di giudicare "posso fidarmi di questo?". Se cerchi di emettere quel giudizio ogni volta con la sola forza di volontà, ti sfianchi e qualcosa sfugge. Se invece fai in modo che sia una macchina a esigere le prove, un cancello instancabile resta rigoroso al posto tuo. Più fai lavorare l'AI, più la cosa su cui vale la pena impegnarsi non è "come farla lavorare", ma "come verificare quando dice che è tutto fatto".

Articoli correlati