Question-Driven Specification: prima capire, poi costruire 🧠

Ci hanno raccontato per anni che il problema principale dello sviluppo software fosse scrivere codice abbastanza velocemente. Adesso che abbiamo strumenti capaci di generarlo in pochi secondi, si scopre una verità un po’ scomoda: il collo di bottiglia non era la tastiera, era la comprensione. E infatti molti progetti continuano a inciampare nello stesso punto di sempre: requisiti vaghi, assunzioni non dichiarate, dettagli lasciati alla benevolenza del destino.
La cosa buffa e leggermente tragica è che l’AI può amplificare questo difetto. Se parti da una richiesta confusa, otterrai una risposta confusa ma molto più elegante, molto più rapida e molto più pericolosa. In pratica: automazione del malinteso.
La Question-Driven Specification nasce proprio qui. Non come metodologia dal nome altisonante da appendere alle slide, ma come disciplina molto concreta: invece di correre verso la soluzione, si inizia dalle domande che rendono il problema meno opaco.
Prima di chiedere a una macchina di costruire qualcosa, dovremmo essere in grado di chiederle cosa ci manca per capirlo davvero.
Il vero difetto dei requisiti è la finta chiarezza 🎭
Quando diciamo che un requisito è “chiaro”, spesso intendiamo una cosa diversa: ci sembra abbastanza chiaro da poter iniziare. Non è la stessa cosa. Anzi, a volte è l’anticamera di un rework molto costoso.
Una feature descritta in tre righe può sembrare innocua. Poi scopri che nessuno ha definito cosa succede in caso di errore, chi vede cosa, quali dati sono obbligatori, come si gestiscono le eccezioni, quali limiti di performance esistono, quali vincoli di sicurezza erano sottintesi e quali assunzioni vivevano serene nella testa di una sola persona. Il codice arriva dopo. Il caos, di solito, era già lì.
Qui la differenza non la fa il talento individuale. La fa il coraggio di fermarsi e dire: non abbiamo ancora una specifica, abbiamo una narrativa provvisoria. E finché resta narrativa, ogni implementazione rischia di essere una traduzione arbitraria.
È la stessa onestà tecnica di cui parlavo in Unknowns-Driven Development: se non rendi esplicito ciò che non sai, il progetto non diventa più solido. Diventa solo più teatrale.
Le domande non rallentano: evitano di correre nella direzione sbagliata 🧭
L’idea centrale è semplice: usare le domande non come accessorio della discovery, ma come motore della specifica. Non domande decorative del tipo “avete altri commenti?”, ma domande che costringono a esporre buchi, ambiguità e dipendenze nascoste.
Domande come queste cambiano davvero il livello della conversazione:
- cosa stiamo assumendo senza averlo verificato?
- quali edge case stiamo ignorando perché ci rovinano l’ottimismo?
- quali dati entrano, cambiano, falliscono o spariscono in modi che non abbiamo descritto?
- dove la sicurezza, la coerenza o la performance sono date per scontate senza esserlo davvero?
Non è un interrogatorio per sadici. È igiene progettuale. E qui l’AI può diventare utile non tanto perché “sa tutto”, ma perché sa fare una cosa molto pratica: interrogare con pazienza e senza stancarsi. Se la usi bene, non ti sostituisce nel pensiero. Ti costringe a renderlo più esplicito.
Lo sviluppatore umano, in questo schema, resta la fonte decisionale e la fonte di conoscenza contestuale: conosce il dominio, pesa i compromessi, si assume la responsabilità delle scelte. L’agente AI, invece, funziona meglio quando smette di fingere saggezza universale e diventa ciò che può essere davvero utile: un rilevatore di unknowns, mancanze e omissioni. Non decide al posto tuo. Ti mostra dove stai decidendo con troppo poco materiale.
In questo senso è una naturale estensione di quanto ho scritto in Comunicare con l’intelligenza artificiale: il valore non sta nell’ottenere risposte veloci, ma nel migliorare la qualità delle domande. Perché una richiesta vaga non è democratica, è solo inefficiente.
La domanda giusta non produce automaticamente la soluzione giusta, ma elimina molte soluzioni sbagliate. E già questo, nel software, è quasi un lusso.
Una specifica che nasce per iterazione, non per rivelazione ✍️
La Question-Driven Specification parte da un presupposto molto poco eroico ma molto utile: all’inizio il problema è incompleto. Invece di fingere il contrario, prende quella incompletezza e la trasforma in metodo.
Nel mio approccio più consolidato, questo ciclo vive in una directory dedicata, non in una chat destinata a evaporare. L’agente genera file markdown con le domande e con spazi espliciti in cui posso rispondere; io apro i file, compilo, rileggo e rilancio l’iterazione successiva. Il vantaggio è molto concreto: lo storico di domande e risposte rimane, può essere corretto, discusso, confrontato nel tempo e anche versionato come uno storico decisionale.
Questo rende più difficile scambiare una decisione ragionata per una scommessa andata bene. Niente magia, niente dashboard con l’aria importante. Solo testo, versionamento e attrito utile.
Il punto è che la specifica non viene “scritta” una volta sola: viene raffinata progressivamente. A ogni giro si riduce lo spazio dell’interpretazione arbitraria, e la documentazione smette di essere un reperto amministrativo per diventare un artefatto operativo.
Per me l’effetto più interessante è stato vedere meglio i miei limiti: assunzioni errate, semplificazioni premature, punti che credevo chiari e non lo erano affatto. Questa frizione ha migliorato il modo in cui progetto architetture più o meno complesse, soprattutto quando entrano in gioco temi che il team pensa di aver già capito solo perché li ha nominati di sfuggita: responsabilità, error handling, dati sensibili, superficie di attacco, audit, segregazione dei ruoli. Finché questi aspetti non diventano domande esplicite, anche la sicurezza resta una nota a margine con ambizioni superiori al suo spazio reale.
Il markdown, qui, resta quasi perfetto: semplice, versionabile, leggibile, collaborativo. Non serve un tempio di tooling per fare chiarezza. Serve un contenitore che non faccia finta di essere più importante del contenuto.
Se poi vuoi migliorare il modo in cui costruisci le interazioni con i modelli, la guida su Prompt Engineering può essere un buon complemento operativo. Ma il punto resta questo: il prompt non è una formula magica. È una forma di progettazione del pensiero.
Il flusso reale, visto da fuori 🔁
Se lo vuoi raccontare senza romanticismi inutili, il processo assomiglia più o meno a questo: bozza iniziale, riorganizzazione del documento da parte dell’agente, generazione di un file di domande, compilazione da parte dell’utente, integrazione nella specifica, nuova iterazione di domande e loop finché il documento smette di essere vago e diventa sufficientemente solido da guidare lo sviluppo.
sequenceDiagram
participant U as Utente
participant A as Agente AI
participant F as File markdown
U->>A: Fornisce bozza iniziale del problema o della feature
A->>F: Crea o riorganizza il documento iniziale
A->>F: Scrive un file di domande
U->>F: Compila il file con risposte e chiarimenti
U->>A: Rimanda le risposte per una nuova iterazione
A->>F: Integra le risposte e aggiorna la specifica
alt Specifica non ancora sufficiente
A->>F: Scrive un nuovo file di domande
U->>F: Compila il nuovo file
U->>A: Rimanda nuovi chiarimenti
A->>F: Aggiorna ancora la specifica
else Specifica sufficientemente chiara
A->>F: Consolida la specifica per sviluppo, review e test
end
La parte interessante è che il loop non serve a produrre più testo, ma a produrre meno ambiguità. Se a ogni iterazione emergono punti ciechi, il metodo sta funzionando. Se invece tutto sembra chiaro subito, di solito non è maturità progettuale: è ottimismo con una buona impaginazione.
Dalla specifica ai test, prima ancora del codice 🧪
Quando la specifica raggiunge un livello di completezza sufficiente, puoi usarla come base per far generare all’AI dei test case e trasformarli nel primo artefatto concreto del lavoro. È un passaggio interessante perché sposta l’attenzione dal “scrivi subito l’implementazione” al “dimmi prima come verifichiamo che sia corretta”.
In pratica, una QDS fatta bene si presta molto bene a un flusso TDD: prima chiarisci comportamento, vincoli, edge case e condizioni di errore; poi fai derivare i test da quella specifica; solo dopo inizi a sviluppare davvero. Non garantisce miracoli, ovviamente. Però riduce parecchio la probabilità di scrivere codice elegante che implementa male un requisito capito peggio.
L’AI come revisore critico, non come oracolo di quartiere 🤖
Una delle distorsioni più comuni nell’uso dell’AI è trattarla come un generatore di risposte finali. Più utile, molto più utile, è usarla come revisore critico delle nostre zone cieche.
Se le chiedi di proporti subito la soluzione, tenderà a riempire i vuoti con inferenze plausibili. Se invece le chiedi di trovare ambiguità, assunzioni implicite, punti deboli e scenari non coperti, allora la stai usando in un modo molto più adulto. Non per chiudere il ragionamento in fretta, ma per tenerlo aperto abbastanza a lungo da renderlo affidabile.
Questa differenza conta parecchio. Perché una macchina che completa gli spazi bianchi può sembrare efficiente, ma spesso ti consegna una coerenza apparente. Una macchina che ti restituisce domande scomode, invece, ti obbliga a decidere davvero.
Ed è qui che entra in gioco la parte morale della faccenda: fare domande serie è un atto di responsabilità. Significa rinunciare alla scorciatoia del “ci penseremo dopo”, che è una frase adorabile finché il “dopo” non coincide con la produzione.
Quando funziona davvero, e quando invece stai solo filosofeggiando troppo 🧱
Questo approccio è particolarmente utile quando il dominio è ambiguo, le integrazioni sono critiche, i vincoli sono tanti o il costo dell’errore è alto. Sistemi distribuiti, prodotti con regole di business intricate, SaaS multi-tenant, contesti regolati, architetture con molte dipendenze esterne: lì le domande ben fatte valgono più di una falsa partenza brillante.
Naturalmente esiste anche il lato opposto. Se devi validare un’idea molto piccola, buttare giù un prototipo esplorativo o capire se una direzione ha senso in poche ore, formalizzare troppo presto può diventare un esercizio di estetica processuale. In quei casi non serve una liturgia. Serve discernimento.
La regola pratica, se vogliamo evitarci slogan inutili, è questa: più costa sbagliare, più conviene interrogare prima di implementare. Più il rischio è basso e reversibile, più puoi tollerare una specifica incompleta e imparare facendo. Non è dogma. È proporzione.
Le domande non servono per rallentare tutto. Servono per rallentare solo dove l’errore costerebbe troppo.
La specifica migliore non è quella più dettagliata, ma quella più onesta ✅
Alla fine, la Question-Driven Specification non è un culto della complessità. È un invito alla chiarezza. Ci ricorda che nel software il problema raramente è l’assenza di soluzioni: quelle arrivano sempre, spesso in quantità industriale. Il problema è scegliere una soluzione quando il problema non è ancora stato definito abbastanza bene.
In un’epoca in cui possiamo generare codice, test, refactor e persino architetture con una facilità quasi offensiva, il vantaggio competitivo si sposta altrove: capire meglio, esplicitare meglio, chiedere meglio. Non è glamour, lo so. Ma nemmeno rifare metà sistema dopo tre sprint lo è particolarmente.
Se vuoi provare davvero questo approccio, non partire da un framework mentale troppo elaborato. Parti dalla prossima feature ambigua che ti capita tra le mani. Scrivila in markdown. Chiedi all’AI di non proporre soluzioni ma di generare solo domande. Rispondi con disciplina. Ripeti il ciclo finché la specifica smette di sembrare una promessa e inizia a sembrare un contratto.
È meno spettacolare di un prompt miracoloso. Però funziona meglio. E, dettaglio non irrilevante, ti evita di costruire software sopra intuizioni travestite da requisiti.