Skip to content

Intent-driven development: quando scrivere codice diventa opzionale

SigmaJunction · Ingegneria9 min di lettura

Chieda a un team che cosa porterebbe via se l’edificio andasse a fuoco: per settant’anni la risposta è stata il codice sorgente. Perderlo significava perdere le decisioni accumulate dall’azienda, le migliaia di piccoli giudizi che fanno aderire un sistema al proprio business. Quella risposta sta cambiando, in silenzio. Quando gli agenti sanno rigenerare un’implementazione funzionante a partire da un enunciato preciso di ciò che il sistema deve fare, il codice smette di essere il gioiello di famiglia. Lo diventa l’enunciato. Chiamiamo sviluppo guidato dall’intento la pratica che nasce dal prendere sul serio questo fatto: la disciplina di fare dell’intento - e non del codice - l’artefatto che il team scrive, revisiona, versiona e possiede.

L’affermazione del titolo richiede subito una precisazione. «Scrivere codice diventa opzionale» non significa che nessuno legga più il codice, né che il codice generato non conti, né che la competenza ingegneristica sia superata. Significa qualcosa di più stretto e più interessante: per una classe crescente di lavoro, digitare l’implementazione a mano è ormai una scelta e non una necessità - e i team dovrebbero decidere in modo deliberato dove continuare a compierla, invece di compierla ovunque per abitudine.

L’intento non è una sensazione

La parola «intento» si presta agli abusi. Sembra qualcosa che si possa soddisfare con una dichiarazione di missione e una tavola di ispirazione. In pratica, un intento capace di guidare lo sviluppo è un insieme di affermazioni verificabili sul comportamento - affermazioni rispetto alle quali una macchina o un collega possono controllare un sistema e rispondere superato o non superato. «I clienti devono avere un checkout fluido» è un sentimento. «Un cliente di ritorno completa il checkout in tre passaggi; un pagamento fallito conserva il carrello e spiega l’errore nella lingua del cliente; un doppio addebito è impossibile anche se il pulsante di conferma viene premuto due volte» è un intento. La differenza è la verificabilità, ed è tutta lì la differenza.

L’intento si impila su tre livelli. In cima sta l’intento di prodotto: quale risultato il sistema esiste per produrre, per chi, misurato come. Sotto vivono gli invarianti di sistema: le proprietà che devono valere a prescindere dall’implementazione - il denaro si conserva, le tracce di audit si accodano, i dati personali restano dentro il confine, le cancellazioni sono recuperabili. In fondo stanno i test di accettazione e i set di valutazione: la forma eseguibile, il livello che una pipeline può davvero far girare. Ogni livello giustifica quello sotto; ogni livello sottostante rende verificabile quello sopra. Un team che mantiene tutti e tre può affidare l’implementazione a un agente come un committente affida la costruzione a un’impresa: contro disegni, non contro aggettivi.

Se suona come un parente stretto della scrittura di contratti per gli agenti AI, è perché lo è. Lo sviluppo guidato dalle specifiche è la disciplina della singola attività: un pezzo di lavoro, un contratto, un ciclo di verifica. Lo sviluppo guidato dall’intento è ciò che diventa una base di codice quando quella disciplina si capitalizza - quando i contratti, gli invarianti e i set di valutazione accumulati diventano la vera descrizione del sistema, e una qualsiasi implementazione è solo la sua compilazione corrente.

Il codice come prodotto di una compilazione

La conseguenza pratica è uno spostamento nel significato di «il sorgente». In un linguaggio compilato nessuno mette le mani sul binario: si cambia il sorgente e si ricompila. I team guidati dall’intento cominciano a trattare allo stesso modo il codice di implementazione: quando un comportamento deve cambiare, la prima modifica atterra sul livello dell’intento - un nuovo test di accettazione, un invariante modificato, un enunciato di prodotto più affilato - e l’implementazione viene rigenerata o rilavorata per soddisfarlo. Il codice resta leggibile, revisionato e portante. Ciò che cambia è il suo statuto: è derivato, e la cosa da cui deriva è la cosa su cui si discute.

Anche la revisione sposta il bersaglio. Revisionare tremila righe generate alla velocità di lettura è teatro: chi revisiona approva ciò che non riesce davvero a tenere in testa. Revisionare il diff dell’intento è invece trattabile: quale nuovo comportamento è stato promesso, quali invarianti sono stati toccati, i nuovi test inchiodano davvero la promessa, e c’è qualcosa nel diff dell’implementazione che l’intento non spiega? L’attenzione dell’ingegnere senior sale di un livello - da «questo ciclo è corretto?» a «questa è la promessa giusta, ed è imposta?». Non è una retrocessione del giudizio ingegneristico. È giudizio ingegneristico applicato dove oggi rende di più.

Il codice è derivato. L’intento è il sorgente. I team che discutono del sorgente consegnano più in fretta dei team che discutono della compilazione.

Dove il codice scritto a mano vince ancora

Essere onesti sul confine impedisce che tutto questo diventi ideologia. Una parte del codice va ancora scritta a mano, e le categorie sono sempre le stesse. Il nucleo caldo- il motore di prezzo, l’algoritmo di abbinamento, il modello di rischio - dove ogni ramo incarna una decisione di business e la comprensione del codice da parte del team è essa stessa un bene. Il lavoro algoritmico inedito, dove l’intento non può essere enunciato con più precisione dell’implementazione, perché scoprire l’implementazione è il lavoro. I confini critici per la sicurezza - autenticazione, crittografia, avvio dei pagamenti - dove la profondità della revisione conta più della velocità di produzione e si vogliono le impronte di una persona su ogni riga. E il livello dell’intento stesso: test, invarianti, set di valutazione e schemi meritano una paternità umana proprio perché tutto il resto viene verificato contro di loro.

La domanda utile, per un dato pezzo di lavoro, non è «un agente riesce a scriverlo?» - sempre più spesso ci riesce - ma «che cosa perdiamo se non lo scrive nessuna persona?». Dove la risposta è «niente, purché l’intento sia imposto», la generazione è l’impostazione razionale. Dove la risposta è «la nostra comprensione della cosa che ci fa guadagnare», lo scriva a mano.

Come si guasta

Il marciume dell’intentoè il primo modo di fallire. Il livello dell’intento è fonte di verità soltanto finché viene mantenuto come si mantiene un sorgente. Nel momento in cui un team comincia a correggere il comportamento direttamente - un hotfix qui, una modifica manuale veloce lì - senza riportare la modifica dentro i test e gli invarianti, l’intento inizia a descrivere un sistema che non esiste più. Poi la rigenerazione successiva, compilata fedelmente da un intento vecchio, cancella le correzioni non documentate. La regola che lo previene è la stessa che tiene onesti gli schemi: i cambi di comportamento atterrano prima come cambi di intento, nella stessa pull request, oppure non atterrano.

Rigenerare senza riverificareè il secondo. La rigenerazione non è idempotente: due esecuzioni sullo stesso intento producono codice diverso, con comportamenti accessori diversi, e tutto ciò che il livello dell’intento non inchioda è libero di cambiare. I team si scottano quando danno per scontato che la pipeline verde di ieri risponda della rigenerazione di oggi. Non è così. Ogni rigenerazione è una nuova implementazione e si guadagna il ciclo di verifica completo - test, set di valutazione, controllo degli invarianti - ogni volta. Se è troppo costoso farlo girare a ogni rigenerazione, la soluzione è rendere la verifica più economica, non più rara.

Trattare come usa e getta un codice generato che invece è portanteè il terzo, e il più sottile. Un team interiorizza che «il codice è solo un prodotto di compilazione» e smette del tutto di leggerlo: niente revisione, niente profilazione, nessuna familiarità operativa. Poi arriva un incidente alle due di notte, e chi è di turno si trova a fare debug su un sistema che nessuno ha mai letto, guidato soltanto dall’intento che avrebbe dovuto soddisfare. Derivato non vuol dire ignorabile. Il codice in produzione richiede una presa in carico operativa a prescindere da chi l’abbia digitato; il livello dell’intento dice che cosa il sistema dovrebbe fare, ma la risposta agli incidenti avviene dentro ciò che il sistema fa davvero. I team che gestiscono bene questa parte assegnano un responsabile a ogni componente generato, esattamente come farebbero per uno scritto a mano - qualcuno che l’ha letto, l’ha profilato e sa attraversarlo sotto pressione.

Un percorso di adozione pragmatico

Niente di tutto questo richiede una rivoluzione, e i team che ci provano di solito producono un manifesto e nessun cambiamento. Il percorso che funziona è incrementale. Si cominci col rendere esplicito l’intento del sistema che già esiste: mettere per iscritto gli invarianti che si crede valgano, trasformare la conoscenza tribale in test di accettazione ed essere onesti su dove i test e il sistema non vanno d’accordo. Questo passo si ripaga da solo anche se nessun agente toccherà mai la base di codice: è semplicemente la documentazione e la copertura di test che il team doveva già a se stesso.

Poi si scelga un componente circoscritto e ben compreso e ci si faccia girare l’intero ciclo: intento scritto e revisionato, implementazione generata a partire da quello, verifica meccanica, revisione umana puntata sul diff dell’intento. Si misuri onestamente - tempo di ciclo, tasso di difetti, sforzo di revisione - rispetto alla linea di base scritta a mano. Si estenda lungo i confini dove il ciclo vince; si continui a digitare dove non vince. Nel giro di qualche trimestre la base di codice si ordina da sola in un nucleo scritto a mano con una periferia generata, e la scarsa attenzione senior del team si concentra sul livello in cui si capitalizza: decidere, in modo preciso e verificabile, che cosa il software deve fare.

Il settore c’è già passato. Nessuno rimpiange di scrivere assembly a mano: abbiamo tenuto la capacità e lasciato l’abitudine, perché un sorgente di livello più alto più un compilatore affidabile era semplicemente un affare migliore. Intento più agenti più verifica sta prendendo la forma dello stesso affare, un livello più su. Scrivere codice sta diventando opzionale. Sapere esattamente che cosa il codice deve fare - ed essere in grado di dimostrare che lo fa - sta diventando il mestiere.

Continua a leggere

Ricevi il prossimo saggio via email

Il software come investimento, AI applicata e pratica ingegneristica - scritto per chi firma le fatture.

Uno o due saggi al mese, senza rumore. Conferma via email, disiscrizione in un clic.

Sta modernizzando il modo in cui il suo team costruisce?

Aiutiamo i team ad adottare l'ingegneria dell'era degli agenti senza rompere ciò che funziona. La call di diagnosi è gratuita.