Fondamenti: tre livelli da non confondere

Un esempio ipotetico, piccolo.

Stai lavorando con un agente al modulo di fatturazione di un ERP proprietario. Per risolvere un caso particolare, l’agente propone di aggiungere un parametro booleano al costruttore di TaxCalculator. Sarebbe il decimo parametro, l’ennesimo inserito dopo diverse variazioni dei requisiti da parte del cliente.

La modifica funziona. Il codice compila, il test è verde e il problema immediato scompare. Eppure qualcosa non torna. Rileggi la classe e intuisci che quel nuovo flag rende ancora più difficile l’uso della classe e apre la strada ad altre eccezioni dello stesso tipo.

L’agente sta risolvendo il caso che ha davanti. Tu riconosci anche il problema che quella soluzione creerà, forse non subito, ma a distanza di qualche settimana. Perciò lo fermi e ne discutete: cambio di rotta, niente nuovo flag; le opzioni variabili vanno raccolte in un oggetto separato, e così, senza troppa fantasia nel nome, nasce la classe TaxCalculatorOptions.

Questa scelta coinvolge i tre livelli annunciati alla fine di L’esperimento: principio, metodo e implementazione. Distinguerli è importante, perché non invecchiano alla stessa velocità e non si delegano nello stesso modo.

Il principio: ciò che deve restare vero

Il principio che orienta la scelta è semplice: ciò che è essenziale per un oggetto non va confuso con le opzioni che cambiano da caso a caso. Quando tutto finisce nella stessa firma, la complessità non scompare. Diventa soltanto più difficile da vedere.

Questo principio non dipende dalla classe TaxCalculator, dal linguaggio usato o dal nome scelto per la soluzione. Può restare valido anche quando cambiano il progetto e gli strumenti.

Un principio indica quindi ciò che si vuole preservare. Non dice ancora quali passi compiere né quale forma debba avere il codice.

Il metodo: come orientare la scelta

Per applicare il principio, distingui nella firma le dipendenze necessarie dalle impostazioni facoltative. Poi serve verificare se il problema è isolato o se le eccezioni si stanno accumulando, nella stessa firma o in altre classi. Nel primo caso, un parametro dedicato può restare un compromesso locale; nel secondo, il nuovo flag prolunga un pattern di eccezioni. È questo passaggio a cambiare l’esito: la stessa analisi può portare a mantenere il parametro, raccogliere le opzioni o intervenire su una struttura più ampia.

Una terza verifica non si legge nel codice: chiedere se su quella firma pesa già una decisione, e a quali condizioni. Una scelta presa per questo cliente e per un periodo definito non lascia segno nella firma né nei requisiti: se non torna sul tavolo, l’analisi resta corretta e l’esito cambia.

Questo è il metodo: osservare il sistema, interrogare ciò che è già stato deciso e scegliere senza ridurre l’analisi alla regola «molti parametri, sempre un oggetto di opzioni». Rende il principio utilizzabile, ma non decide al posto tuo.

L’implementazione: la forma scelta adesso

In questo caso la scelta è introdurre la classe TaxCalculatorOptions: un oggetto che raccoglie le opzioni e lascia nel costruttore soltanto ciò che è necessario.

Questa è l’implementazione. È la forma tecnica adottata per lo specifico caso d’uso. In un altro linguaggio potrebbe essere un record, una configurazione o un costruttore dedicato. Domani una soluzione migliore potrebbe sostituirla senza rendere falso il principio e senza cancellare il metodo usato per arrivarci.

La differenza può essere riassunta così:

  • il principio chiarisce che cosa va preservato;
  • il metodo guida il modo in cui si valuta il problema;
  • l’implementazione realizza la scelta con gli strumenti disponibili.

Perché questa distinzione conta con un agente

Un agente lavora sempre attraverso un’implementazione concreta: modifica quel file, usa quella libreria, esegue quello strumento. Può anche confrontare alternative e prendere decisioni operative entro il mandato ricevuto.

Il Senior, però, riconosce quale principio è in gioco e quali scelte richiedono una decisione direzionale: non perché l’agente sia incapace di proporre una buona soluzione, ma perché il livello in cui l’agente si muove non è quello in cui la scelta si giudica.

Confondere i tre livelli produce due errori opposti. Il primo consiste nel trattare un’implementazione come una verità permanente: «per ogni costruttore di ogni classe si usa sempre un oggetto di opzioni». Il secondo lascia il principio troppo vago: «mantieni il codice pulito». Nel primo caso lo strumento diventa una regola. Nel secondo la regola non aiuta a decidere.

Una buona collaborazione rende espliciti tutti e tre i livelli: che cosa deve restare vero, come valutare il caso e quale soluzione adottare in quel momento.

Il giudizio deve sopravvivere alla scelta

Tra un mese, in una nuova sessione, l’agente vede TaxCalculatorOptions e basta. Dal codice ricava che le opzioni sono state separate; non ricava perché. È la domanda che, un mese dopo, faresti davvero:

«Il cliente chiede l’ennesima variante fiscale. La aggiungo a TaxCalculatorOptions?»

L’agente risponde. Risponde anche bene: sì, è il posto previsto, la classe esiste per quello. La risposta è plausibile, coerente con tutto ciò che ha davanti, e ti riporta dentro l’accumulo di eccezioni che avevi fermato — perché quel giorno, davanti al flag, non avevi deciso «raccogliere le opzioni»: avevi deciso di smettere di trattare come opzione ciò che cambia il calcolo. Un agente senza tracce non risponde «non lo so»: risponde, e ti aiuta volentieri a rifare la strada che avevi chiuso.

Quando la decisione è registrata, invece, quella domanda ne apre altre, e sono tutte domande a cui si può rispondere:

  • un flag qui è già stato proposto, e rifiutato?
  • per quale ragione — e quella ragione vale ancora oggi?
  • che cosa la decisione ha toccato, e che cosa ha lasciato deliberatamente fuori?
  • quale condizione la riaprirebbe?
  • quale alternativa era sul tavolo, e perché è stata scartata?
  • esiste una decisione successiva che l’ha superata?

Nessuna di queste risposte sta nel codice.1 Qualcuna potrebbe stare nella conversazione di un mese prima, se non è andata persa: ma starci non basta, perché nessuno sa più in quale, e niente dice se quella decisione sia ancora in vigore.

Tre di quelle domande — che cosa la decisione ha toccato, quale alternativa è stata scartata, quale decisione successiva l’ha superata — non si risolvono registrando: si risolvono collegando, come ha già mostrato l’Introduzione. Ne segue una regola di scrittura: una scheda si scrive già collegata, perché formalizzare significa registrare la decisione e dichiarare a che cosa si lega, nello stesso gesto.

Perciò, chiusa la discussione, Senior e agente fanno un passo che il codice non richiede: rileggono ciò che si sono detti ed estraggono la parte che vale oltre il caso presente — il problema incontrato, le alternative confrontate, la decisione e le condizioni che potrebbero riaprirla. È l’operazione che l’Introduzione chiama distillazione, e non è un gesto a mano libera: il System Harness ne detta la forma. Il Senior decide quali esiti meritino di essere distillati e risponde di ciò che resta scritto; a scriverlo è l’agente, che quella discussione l’ha appena attraversata. Il risultato ha una forma, e quella forma è la scheda.

Il prompt orienta, la scheda ricorda

A prima vista, davanti a un problema ricorrente, verrebbe da affidarsi a una soluzione nativa del framework agentico in uso: aggiungere una riga nel system prompt («quando un costruttore cresce troppo, separa le opzioni») oppure scrivere una skill che guidi l’agente a riconoscere il problema e ad applicare il pattern previsto.

Entrambe le strade sono utili, ma risolvono un problema diverso. Il prompt orienta il comportamento; la skill rende ripetibile una procedura generale. Né il prompt né la skill conoscono la decisione presa in questo progetto e in questo momento: valgono ovunque, ed è proprio questa universalità a renderli sordi quando la domanda riguarda il perimetro esatto di TaxCalculator.

Il vero banco di prova è il vincolo che nasce dentro il rapporto di lavoro tra Senior e agente: un regime fiscale tenuto fuori dal calcolo perché vale soltanto per quel cliente e soltanto fino alla chiusura dell’esercizio. Nessun requisito di sistema lo documenta e nessuna regola generale lo prevede; il Senior e l’agente lo hanno stabilito discutendo un caso reale, e fuori da quella discussione quel vincolo non esiste. Se la decisione non viene registrata e collegata al punto del codice su cui incide, alla sessione successiva l’agente la ignorerà: tratterà quel regime come un’eccezione da correggere, oppure non vedrà affatto il perimetro in cui il vincolo vive.

È di nuovo la distinzione dei tre livelli, applicata questa volta a ciò che si decide di conservare:

  • Un principio va conservato perché resta vero ovunque.

  • Una decisione va conservata insieme alle condizioni che la tengono in vita, altrimenti la sessione successiva la interpreterà come una regola astratta, da applicare ovunque.

Distinguere i livelli serve a questo: sapere che cosa merita di restare, e con quali confini.

La scheda porta anche un nome più preciso: traccia cognitiva, un termine che sposta l’attenzione dal formato del documento alla sostanza di ciò che vi è custodito. La scheda non è il log o il riassunto della conversazione. È il verbale strutturato del giudizio che la collaborazione ha reso esplicito e che il Senior ha validato. Una scheda reale, con la lettura di ciò che vi si vede, è riportata in appendice.

Da qui derivano i due elementi del System Harness che rendono operativa questa separazione, e che riprenderò più avanti:

  1. Il binario di scrittura: detta la forma della scheda e guida l’agente che la scrive, così che la decisione conservi il problema da cui nasce, i collegamenti e le condizioni che potrebbero riaprirla; non rende la decisione corretta, la rende leggibile, contestabile e coerente con le altre.

  2. L’accesso semantico: cerca per significato le tracce che potrebbero servire. Davanti a un problema simile, l’agente non deve ricordare le parole esatte di mesi prima: può recuperare un principio generale o una decisione specifica insieme alle rispettive ragioni e ai rispettivi confini.

Il principio resta. Il metodo permette di applicarlo. L’implementazione cambia. Il giudizio tiene insieme i tre livelli, risponde delle conseguenze e, quando la scelta lo merita, lascia una traccia persistente. Da questa distinzione parte il resto del libro, esattamente là dove finisce il metro con cui uno sviluppatore misurava il proprio contributo — scrivere codice — e comincia il lavoro di governo.


  1. Peter Naur, «Programming as Theory Building», Microprocessing and Microprogramming 15, n. 5 (maggio 1985), pp. 253–261; letto il 5 agosto 2026 in trascrizione digitale, non sull’originale a stampa. Naur sostiene che la parte essenziale di un programma — la teoria di come certe faccende del mondo vengono trattate dal programma — vive in chi lo ha costruito, e che il testo del programma insieme alla sua documentazione si è rivelato «insufficient as a carrier of some of the most important design ideas». La tesi riguarda squadre di persone che si sciolgono; portarla su un agente che riparte da zero a ogni sessione è mio.↩︎