Your codebase is the actual prompt
Tutti tarano i prompt, cambiano modello, allargano la context window. E Claude annaspa lo stesso. La versione scritta del talk al Claude Torino #2.
Sul palco ho fatto un esperimento con la sala. Alzi la mano chi usa Claude Code: tutti. Tenetela su se fa quello che gli chiedete, esattamente come gliel'avete chiesto: un gruppo. E ora alzatela se invece va per i fatti suoi: un altro gruppo, bello nutrito pure quello. Stesso pubblico, stesso Claude, due esperienze opposte. Verrebbe da dire che è un problema di prompt. Da noi in azienda succedeva uguale, e la domanda mi è rimasta addosso: com'è possibile?
All'edizione di maggio, Dario Martinelli aveva raccontato una cosa importante: il prompt è un set di coordinate nello spazio semantico, dice al modello dove andare a pescare. E il ping pong con la chat per correggere la rotta, quello che lui chiama "remare", aggiunge solo rumore: conviene collocare il modello nel punto giusto da subito, con un prompt costruito bene. Mi aveva convinto, e mi aveva lasciato una curiosità: di prompt engineering parliamo da anni. Ma che cos'è, davvero, il prompt?
Prima serve una definizione di AI, e io uso quella che mi ha dato il mio amico Federico (da bravo manager, appena l'ho sentita ho fatto la cosa più giusta: gliel'ho rubata). L'AI è un amplificatore. Amplifica quello che il team ha già: se il team è confuso, amplifica confusione; se è bravo, amplifica la bravura. E lo stesso fa con quello che le date da leggere: le passate confusione, amplifica confusione. Le passate ordine, amplifica ordine.
Con questo in mente, ho cominciato a osservare cosa fa Claude Code nel primo secondo dopo l'invio. Legge i file. Deve capire dove si trova, e il vostro codice gli finisce dritto nel contesto. Vi sembra un dettaglio? Provate a tornare con la memoria all'ultima volta che avete fatto onboarding a una persona nuova sulla vostra codebase. Io ci andavo tutto ringalluzzito: "guarda, la nostra codebase è semplicissima, è questa roba qua". E la persona, ragionevolmente, faceva domande. "Bello, ma questa parte mi sembra diversa: come mai?" E lì l'imbarazzo: "no, quella non guardarla, l'ha fatta Michele che poi è andato via, ma tranquillo, è l'unico caso". "E questa?" "Quella è di Germano, se la segue lui. Però è l'unica fatta così." E man mano che rispondevo, gli unici casi si accumulavano: il terzo, il quarto, il quinto. A fine giro, di parti senza una storia da spiegare ne restavano due. Lavoravo in una codebase fatta di eccezioni, dove la norma era semplicemente l'eccezione che andava più comoda a me.
Se quella codebase la racconti a una persona, la persona ti giudica: per quello mi imbarazzavo. Claude invece la legge tutta e mica ti giudica. Anche se certe volte, secondo me, dovrebbe. Però tutto quello che legge finisce nel contesto e diventa parte degli insegnamenti di quella sessione. E cosa fa con quello che ha imparato? La parola di prima: amplifica.
Qui entra il paradosso che mi ha cambiato idea. In azienda c'era un progetto dove le cose uscivano praticamente sempre al primo colpo. La parte interessante? A me quella codebase faceva assolutamente schifo. Era contraria a tutto quello che ho imparato in trent'anni: astrazione, niente; interfacce "perché non si sa mai", niente; tutto in una singola classe. E il colpo di grazia: l'intero applicativo era scritto così. Sono andato dal mio capo a chiedere spiegazioni, e la risposta è stata una lezione: "Siamo una startup, il codice lo mantengono dei junior. Perché un junior possa mantenerlo dev'essere semplice, chiaro, tutto in un posto. Le pippe architetturali che ti fai tu di solito le abbiamo buttate alle ortiche." Codice costruito per i junior, prima che Claude Code esistesse.
Si dice spesso che l'AI è come un junior: poca memoria, nessuna mappa del sistema, le serve tutto in un posto solo. C'è del vero, con una differenza che cambia tutto. Il junior il casino lo giudica, e compensa. L'agente no: l'agente lo copia.
Il motivo sta nel meccanismo con cui questi modelli leggono. Mentre scorre il vostro codice, il modello predice quello che viene dopo, e la predizione la fa chiedendosi: questa cosa l'ho già vista? L'ultima volta, cosa veniva dopo? Se nel vostro codice dopo ogni catch c'è un log, lui vede catch e spinge su log. Se in giro avete anche dei catch con un ignore dentro (ma chi mai metterebbe un ignore in un catch?), la spinta può andare là, e l'errore è servito. La parte importante è che gli basta la forma: ordine, fattura, documento, per lui è lo stesso pattern. Ed è lo stesso identico circuito che lo rende utile, perché è quello con cui impara al volo da ciò che gli mettete davanti. La versione che impara i pattern buoni e ignora quelli marci non esiste. Se il meccanismo ricorrente è marcio, lui lo ripete tale e quale. Chi vuole la spiegazione seria, con le induction heads e gli studi di Anthropic, la trova nei riferimenti del talk.
La conseguenza pratica è che la coerenza conta più di qualunque altra cosa. Più il modello vede cose fatte sempre allo stesso modo, più ha un'idea chiara di come muoversi. Le eccezioni, che un umano giudicherebbe, per lui sono solo direzioni alternative in cui partire. E la mia codebase complessa, quella con dieci file e quattro layer per cambiare un campo? Una coerenza ce l'aveva pure lei, ma spalmata su troppi file: il modello faticava a tenerla insieme, e io mi arrabbiavo a ogni interfaccia saltata.
Poi c'è la domanda scomoda, quella che mi ha costretto a disimparare. Perché ho passato una carriera a costruire astrazioni e future-proofing? Perché cambiare le cose era un costo, e l'interfaccia mi prometteva che l'avrei pagato a rate. Quel costo non è sparito, c'è ancora. Ma il conto è passato all'agente, che tra l'altro paga senza lamentarsi. Quanto regge, allora, tutta quell'impalcatura difensiva?
I principi che mi sono portato a casa sono tre. Coerenza: le cose si fanno sempre allo stesso modo, anche a costo di duplicare, perché quel costo per un agente conta poco. Località: se un'operazione sta tutta in un file, il modello legge quel file e ha finito. Leggibilità: il modello fa associazioni sulla semantica, è pure pigro; se vede un getOrder crede che legga, e se quel getOrder muta qualcosa, sbaglia esattamente come sbaglieresti tu. Nomi onesti: contavano per gli umani, contano il doppio adesso.
Sul come partire, la mia ricetta è poco eroica. Avevo codebase legacy da convertire, e ho creato delle cartelle nuove con dentro le mie regole: un file markdown che si carica da solo quando l'agente tocca quei file, e gli dice "qui le cose funzionano così, sono tutte uguali, sono scritte così, ricordatelo". Le cose nuove nascono lì dentro, e ogni volta che tocco qualcosa di vecchio colgo l'occasione: "trasponilo, portalo nella cartella". Sul vecchio Claude continuava a sbagliare. Sul nuovo andava come un treno.
E quindi torniamo alla domanda dell'inizio: com'è possibile che due gruppi con prompt simili abbiano risultati così diversi? È la vostra codebase. Voi scrivete tre righe in chat, lui legge duecento righe di file: indovinate quale delle due parti pesa di più. Dario vi ha dato il dove: il prompt orienta il modello, gli dice cosa fare e in che zona operare. La codebase è il come: è lì che impara a muoversi. Quella parte lì è il prompt vero.
Chiudo come ho chiuso sul palco. Claude legge la vostra codebase e mica vi giudica. Il punto è che dovete giudicarvi voi: mettetevi nei panni di uno sviluppatore che quella codebase la apre per la prima volta, e chiedetevi se riesce a leggerla, a capirla, a lavorarci da junior. Se la risposta è sì, il vostro Claude lavorerà meglio con voi. Perché la vostra codebase sarà diventata il vostro prompt.
Il video del talk arriva sul canale di Claude Torino; intanto qui ci sono i riferimenti, studi inclusi.