All’ultimo evento a cui ho partecipato con un talk, ho fatto alzare la mano al pubblico tre volte: chi avesse mai provato il vibe coding, chi avesse generato un intero progetto a suon di prompt e caffè e chi, infine, avesse poi buttato tutto per riscriverlo da zero. Le mani si sono alzate quasi in sincrono e, quasi sempre, erano le stesse persone tutte e tre le volte.
Volti sconsolati, quasi rassegnati a dover riscrivere qualcosa che sembrava perfetto dopo i primi giorni di sviluppo. Sembrava, appunto.
La realtà, però, è ben diversa da quella raccontata a colpi di sberleffi e titoli clickbait. La verità è che lasciare un’AI senza governo è come dare un pennarello in mano a un bambino e uscire dalla stanza, convinti che quel foglio verrà usato per realizzare un capolavoro e non per essere ridotto in coriandoli, come invece accadrà.
La colpa è (anche) di un tweet
Se cercate un colpevole, il nome più citato è Andrej Karpathy. Co-fondatore di OpenAI, ex responsabile dell’Autopilot in Tesla e oggi in forze ad Anthropic, Karpathy è uno che di modelli linguistici se ne intende. Nel gennaio 2023 twitta che “il nuovo linguaggio di programmazione più caldo è l’inglese“. Il tweet raggiunge milioni di visualizzazioni e scatena titoli apocalittici per chi scrive codice. Due anni dopo rincara la dose e conia il termine “vibe coding”: accetti tutto quello che genera l’AI, non leggi più i diff, incolli gli errori senza commentarli e chiedi modifiche a caso finché il bug non sparisce. Lui lo diceva sorridendo, riferendosi a progetti usa-e-getta da weekend, ma mezza Internet l’ha presa come una metodologia di lavoro seria.
Il risultato ricorda una celebre battuta di Nanni Moretti in “Ecce Bombo”: “faccio cose, vedo gente”. Sembra tutto molto produttivo, finché qualcuno non ti chiede cosa tu abbia effettivamente costruito.
C’è poi quella che potremmo definire come “pigrizia da Avanti, Avanti, Avanti”: quanto piacere provate quando installate un software cliccando su “Avanti” a ripetizione, senza dover rispondere a nessuna domanda? Nel vibe coding accade la stessa cosa: scriviamo un prompt sgrammaticato, di quelli che la nostra maestra delle elementari ci avrebbe stracciato davanti alla classe, ma il modello, allenato su trilioni di parametri, capisce e interpreta tutto nel modo corretto.

Il mito dello zero-to-prod
Il vibe coding funziona benissimo nelle demo online, dove l’AI si comporta come uno sviluppatore senior fullstack capace di risolvere tutto in cinque minuti. Il problema sorge quando lo si applica al gestionale legacy di un’azienda reale: centomila righe di codice scritte da persone che nel frattempo hanno cambiato lavoro.
In quel contesto, l’AI smette di sembrare senior e comincia a somigliare a uno stagista iperattivo al suo primo giorno di caffè gratis: quello che, preso dal panico, prova a risolvere i bug commentando linee di codice a caso pur di farti vedere che “compila”. E tu rimani lì a fissare lo schermo, chiedendoti perché hai accettato quella pull request.
La ragione è tecnica e ha un nome preciso: context rot. Più token entrano nella finestra di contesto, meno affidabile diventa la risposta del modello. Con l’allungarsi della chat, il sistema dimentica le decisioni prese all’inizio e ignora i vincoli stabiliti dieci messaggi prima. Quante volte avreste voluto tirare un pugno al monitor quando il modello, per l’ennesima volta, ha iniziato a includere quella libreria che avevate detto in modo esplicito di non includere, o si è fissato a creare variabili in camelCase quando tutto il programma è impostato in snake_case? Senza una specifica che ancori la conversazione, non si ottimizza nulla: si perde semplicemente contesto a ogni scambio.
L’effetto pratico è uno “spaghetti code” nato da sessioni di chat differenti: tre conversazioni distinte producono tre modalità diverse per gestire gli errori all’interno dello stesso progetto, e nessuno ricorda più quale sia quella “giusta”.
Il pericolo maggiore, tuttavia, non è l’errore evidente che salta subito all’occhio, ma l’allucinazione verosimile: codice che appare corretto, supera una review superficiale e nasconde un bug insidioso. L’esempio che propongo più spesso è il fantomatico Array.shuffle() nativo in JavaScript, che in realtà non esiste. Il codice generato lo invoca con tale naturalezza da spingerci ad annuire, pensare “ah, finalmente l’hanno standardizzato” e lasciar correre perché “tanto si tratta di un caso limite”. Poi, il sistema in produzione va giù.
Cavallo, cavaliere e imbracatura
La tesi che ho sostenuto sul palco non è che il vibe coding sia superato in assoluto, ma che sia ormai impraticabile come approccio unico. Esiste una via per trasformare l’AI da assistente imprevedibile a esecutore governabile, e prende il nome di Spec-Driven Development (SDD).

La metafora dell’harness engineering rende l’idea meglio di qualsiasi definizione formale: i progetti basati sull’AI falliscono in produzione per mancanza di un’infrastruttura di supporto attorno al modello, e non per via delle sue capacità intrinseche.
Il modello linguistico è come un cavallo potente e veloce che non sa dove andare da solo. L’imbracatura rappresenta l’insieme di vincoli, guardrail e cicli di feedback che indirizzano questa energia in modo controllato. In questo scenario, chi scrive codice è il cavaliere: indica la direzione e convalida il percorso, senza dover tenere le mani sulle redini a ogni singolo passo.
Lo Spec-Driven Development è una metodologia in cui le specifiche assumono il ruolo di artefatti eseguibili di prima classe. Il flusso si inverte: si redige prima il contratto e poi si lascia che l’AI generi il codice rispettandolo. La sintesi più efficace è racchiusa in questo principio:
Il prompt non deve far indovinare all'AI cosa vuoi. La specifica deve dirle esattamente cosa eseguire.
Scrivere un contratto che l’AI non possa fraintendere
L’istruzione “Voglio un login sicuro” può essere sufficiente per uno sviluppatore esperto che ha già affrontato il problema e conosce gli standard aziendali in materia.
Per un agente AI, invece, non basta. Senza dettagli precisi, riempirà i vuoti con supposizioni, e le ipotesi di un modello linguistico sono statisticamente plausibili, ma non necessariamente corrette. Lo schema di specifica che adotto per ogni attività complessa è essenziale, occupa poche righe in Markdown ed è sufficiente per eliminare gran parte delle ambiguità:
## OBIETTIVO
Cosa deve fare il sistema: una riga chiara
## NON-GOAL
Cosa NON deve fare (refresh token, OAuth, librerie non approvate...)
## VINCOLI
Stack, librerie ammesse, performance attese
## OUTPUT ATTESO
- [ ] Criterio di successo verificabile 1
- [ ] Criterio di successo verificabile 2Code language: PHP (php)
Non occorrono strumenti proprietari: il formato Markdown è facilmente leggibile dal team e rappresenta, al contempo, la lingua madre dei Large Language Model. Se si desidera azzerare le ambiguità del linguaggio naturale, si può ricorrere a EARS (Easy Approach to Requirements Syntax), una notazione rigorosa creata da Alistair Mavin in Rolls-Royce nel 2009 per i requisiti dei motori aeronautici. Strutture come “QUANDO [evento] IL sistema dovrà [azione]” associano ogni decisione a un vincolo logico testabile in modo automatico.
Pur non essendo nata per l’intelligenza artificiale, questa sintassi neutralizza il principale punto debole degli agenti autonomi. Una soluzione ideata per prevenire le incomprensioni tra esseri umani si è rivelata ideale per regolare la comunicazione tra sviluppatore e macchina.
Un caso vero: da due ore di caos a mezz’ora
La differenza emerge chiaramente analizzando un caso reale.
Un’API in PHP che smette di funzionare in seguito al passaggio a PHP 8.1. Con l’approccio vibe coding, il flusso di lavoro degenera rapidamente: si scrive “non funziona più”, il modello propone una patch, si risponde “non funziona ancora”, il sistema genera una seconda versione che rompe un altro componente, e infine una terza che ripristina la prima introducendo un nuovo bug. Il bilancio? Due ore perse, risorse sprecate e nessuna traccia delle modifiche effettuate.
Con una specifica minima, lo stesso problema si risolve in una frazione del tempo:
## PROBLEMA
API /v2/orders ritorna 500 dopo upgrade a PHP 8.1
## CONTESTO
Errore: [log specifico] | File: OrderController.php:45-67
## OBIETTIVO
Fix mantenendo la retrocompatibilità con il client v1
## NON TOCCARE
src/Models/* | file di migration
## VALIDAZIONE
- [ ] La suite di test passa
- [ ] L'API v1 continua a funzionareCode language: PHP (php)
Se un test evidenzia un dettaglio mancante, come la serializzazione delle date nel fuso orario del server anziché in UTC, la soluzione non consiste nel discutere in chat. Si aggiorna la specifica inserendo il vincolo sul fuso orario e si riesegue il task. In questo modo, la conoscenza rimane formalizzata e tracciata su Git, a disposizione di chiunque debba rimettere mano al codice, anziché finire dimenticata nella cronologia di una chat.

Lo scollamento tra documentazione e codice sorgente rappresenta da sempre una delle cause principali di bug e regressioni. Lo Spec-Driven Development risolve questa criticità alla radice, trasformando la specifica in un contratto indissolubile che guida l’evoluzione del codice.
Quando l’approccio non serve
Sarebbe ingenuo presentare SDD come una soluzione priva di costi. Scrivere quindici minuti di specifica per un bug risolvibile in due minuti è burocrazia, non ingegneria: per gli interventi elementari, il vibe coding rimane l’opzione più logica. Inoltre, le specifiche sono codice a tutti gli effetti e richiedono manutenzione. Se il software evolve tramite hotfix manuali mentre il contratto rimane obsoleto, la specifica si trasforma da fonte di verità in fonte di bugie. È necessario un processo costante di allineamento: non basta redigere il documento una volta e scordarsene.
Esiste poi un rischio più subdolo: una specifica estremamente precisa ma errata produrrà, con rigore deterministico, il software sbagliato. Il documento di requisiti va convalidato con la stessa cura riservata al codice, poiché non costituisce un salvacondotto automatico.
Il codice è un effetto collaterale
Il vero valore dello Spec-Driven Development emerge nei progetti a medio-lungo termine o sviluppati in team: in questi scenari, i vantaggi si concretizzano già dopo pochi giorni, con una drastica riduzione delle iterazioni e degli imprevisti.
Si tratta di una rivoluzione culturale: il codice sorgente passa dall’essere il prodotto principale del lavoro al ruolo di semplice artefatto di compilazione.
La specifica diventa il vero asset. Oggi, saperla redigere in modo chiaro, verificabile e privo di ambiguità rappresenta il vero vantaggio competitivo per chi vuole governare l’AI invece di subirla.
Se anche tu hai premuto più volte “Accetta” dopo milioni di domande che ti avevano ormai fuso la corteccia cerebrale e, pur di finire il lavoro e andare a casa, hai accettato una PR con la promessa “lo riguardo lunedì”; se anche tu fai parte di questo gruppo, lo SDD non risolverà tutti i tuoi problemi, ma ridurrà il numero di caffè che dovrai offrire ai tuoi colleghi per aver perso la gara del codice con meno errori.

