Intro

Qualche mese fa ho dovuto mettere mano a un’applicazione complessa su AWS: frontend React su Amplify, diverse Lambda, Bedrock con AgentCore, Knowledge Bases e Prompt Management. Avevo fretta, e la tentazione era fortissima: aprire Claude Code, buttargli dentro un prompt generico e sperare che “capisse”. Invece ho fatto una cosa diversa — ho scritto specifiche, le ho revisionate, ci ho perso una giornata intera — e quel giorno mi è sembrato di non aver combinato nulla. Due giorni dopo avevo un’applicazione funzionante. Se avessi improvvisato, starei probabilmente ancora debuggando.

Questa esperienza mi ha cambiato prospettiva su cosa significhi davvero usare l’AI per sviluppare software. Non si tratta di “vibe coding” — scrivere un prompt vago e sperare nel meglio — ma di qualcosa di molto più strutturato, e paradossalmente più faticoso. Ma prima di entrare nel merito, guardiamoci intorno: i segnali di una trasformazione radicale sono già ovunque.

  • Lo scorso dicembre, Boris Cherny, ingegnere di Anthropic e creatore di Claude Code (praticamente il prodotto di punta dell’azienda), ha dichiarato che nei 30 giorni precedenti il 100% delle attività sul repository di Claude Code sono state fatte da Claude Code stesso
  • Il forte rallentamento in borsa di alcune società SaaS fa pensare che il mercato abbia già prezzato la propensione delle aziende a svilupparsi il software in casa piuttosto che comprarlo dai classici big
  • Spotify ha dichiarato che da dicembre 2025 i loro migliori sviluppatori non scrivono più una riga di codice: inviano istruzioni via Slack al loro sistema interno “Honk” (basato su Claude Code), che implementa le modifiche, mentre gli ingegneri si occupano di revisione e architettura Per affrontare questa discussione, però, dobbiamo lasciarci alle spalle l’hype del “Vibe Coding” e capire fin da subito che stiamo parlando di un modo diverso di concepire la professione dello sviluppatore e la catena di montaggio del software. Questo modo richiede metodo e disciplina e potrebbe addirittura essere indigesto per alcuni, perché rischia di comprimere certe fasi “creative” del lavoro, che talvolta possono essere le più gratificanti.

Lo sviluppatore è una professione morta?

Secondo molti analisti parliamo di una “trasformazione”, quindi in un certo senso la risposta è negativa. Tuttavia, io penso che la trasformazione sarà talmente radicale che nel giro di 5 o 10 anni nessuno di noi vedrà più un annuncio di lavoro che parla semplicemente di “Sviluppatore”. Lo sviluppatore del software di domani richiede expertise molto variegate (architetture, reti, processi, linguaggi, dati, …). Non so come si chiamerà colui il quale farà questo lavoro in futuro, ma per semplicità io lo chiamerò il “PROGETTISTA”.

Lo stesso concetto di Progettista, lo si sta applicando anche ad altri ambiti meno ortodossi, come ad esempio la scrittura o il giornalismo. Per fare un esempio estremo, qualche mese fa Luciano Floridi, uno dei massimi esponenti della filosofia dell’informazione e del Digitale, ha pubblicato un libro intitolato Distant Writing: Literary Production in the Age of Artificial Intelligence., in cui Floridi realizza un suo ambizioso progetto di intrecciare storie di personaggi secondari (minori ma nominati) dei romanzi classici inglesi, da Jane Austen a Virginia Woolf, in brevi storie (1500-2000 parole ciascuna) dove si incontrano in catene narrative plausibili per epoca, luogo e status sociale. Nelle interviste che ha rilasciato, Floridi ha dichiarato di aver sostanzialmente “progettato” il libro e di averlo nel casetto già da molti anni, ma di essere riuscito a realizzarlo solo tramite l’uso di LLM per espandere e scrivere le singole storie, e per fare in modo che i personaggi si incontrassero in modo coerente con le loro caratteristiche e con la trama complessiva.

Prerequisiti

Per prepararsi a questa trasformazione io vedo principalmente 2 prerequisiti, uno tecnico e uno mentale. Nessuno dei due è facoltativo: senza le skills giuste non si producono specifiche di qualità; senza il mindset giusto non si ha la pazienza di scriverle.

Skills

Le specifiche software esistono da sempre, non sono certo una novità del 2026. Tuttavia è sorprendente notare come il mondo tech torni ad attenzionare l’importanza di questo concetto dopo aver inventato il transformer, disboscato foreste e funestato i mercati azionari con potenziali bolle AI.

Le tecniche di Spec-Driven Development si basano ovviamente sul concetto di “Specifica”, che può essere inteso a vari livelli di astrazione (es: user story, specifica tecnica, code template, …). Il Progettista deve dunque saper leggere e scrivere le specifiche su tutto lo stack e deve avere un approccio metodico e rigoroso per industrializzare il lavoro.

Ma come faccio a scrivere specifiche per una soluzione con componenti frontend, backend, un message broker, diversi container, e la necessità di distribuirla su un hyperscaler piuttosto che su un altro?

Nel passato, dovevi sapere le basi dei calcolatori, le CPU, le memorie, la modellazione dati e le reti di telecomunicazioni. Adesso, bisogna alzare il livello di astrazione e allargare la prospettiva. Serve dunque conoscere le piattaforme dati, gli hyperscaler, i pattern di autenticazione, i modelli di deploy e la containerizzazione, le pipeline di automazione e la gestione del software su decine o potenzialmente centinaia di branch.

Per poter evolvere da “Sviluppatore” del 2020 a “Progettista” del 2026, serve dunque:

  • conoscere le basi delle tecniche DevOps
  • avere competenze di base di Solution Design e sapersi districare tra i pattern di sviluppo e deploy più noti (microservizi, message brokers, containers, protocolli di trasporto e applicativi, Security, IaC, …)
  • avere forti competenze tecniche su un’area specifica (es: frontend, data engineering, …)
  • conoscere le basi degli LLM, in particolare il ruolo del contesto e le tecniche di context engineering

Mindset

Per molte persone lo sviluppo è una passione oltre che un lavoro, e lo dimostrano le numerosissime community di sviluppo Open Source. Dobbiamo abituarci all’idea che il lavoro del Progettista potrebbe essere molto meno divertente di quello dello Sviluppatore di oggi. Questo passaggio potrebbe essere uno sforzo non accettabile per tutti, ma è molto probabile che sia proprio qui che si giocherà la partita sulle competenze che verranno apprezzate dal mercato del lavoro: sarà infatti fondamentale saper leggere e scrivere specifiche.

Bisogna inoltre combattere con l’impulso di avere “tutto e subito”: non possiamo pensare di scrivere un prompt e avere il software pronto. Bisogna realmente applicare un certo livello di effort e utilizzare per davvero le skills che citavamo sopra. Come raccontavo nell’introduzione, la giornata “persa” a scrivere specifiche mi ha risparmiato circa due settimane di lavoro. Ma la sensazione iniziale era esattamente quella: di perdere tempo. È un investimento controintuitivo, e il mindset giusto consiste proprio nell’accettarlo.

Concetti di base

Context window

La maggior parte delle persone pensa: “più cose metto dentro il contesto, meglio è”. È un’idea che può portare fuori strada, e capire il perché richiede un minimo di comprensione di come funzionano i modelli.

Gli LLM sono modelli autoregressivi basati sull’architettura Transformer. Il cuore di questa architettura è il meccanismo di self-attention: per ogni token generato, il modello calcola un punteggio di “attenzione” rispetto a tutti i token precedenti nel contesto. Questo ha due implicazioni pratiche importanti:

  1. Complessità quadratica: il costo computazionale dell’attenzione cresce come O(n²) rispetto alla lunghezza del contesto. Raddoppiare il contesto quadruplica il costo. Questo non è solo un problema di latenza e di costi (che pure sono rilevanti), ma degrada la qualità stessa dell’output.

  2. “Lost in the middle”: diversi studi (tra cui il noto paper di Liu et al., 2023) hanno dimostrato che gli LLM tendono a prestare maggiore attenzione alle informazioni che si trovano all’inizio e alla fine del contesto, “dimenticando” quelle centrali. In pratica, se la specifica cruciale della tua API si trova a metà di una conversazione da 80.000 token, il modello potrebbe semplicemente non tenerla in considerazione.

Sebbene l’interfaccia degli LLM si presenti come una chat, dobbiamo sempre valutare ogni singola interazione come se fosse un task isolato, che si porta dietro una storia conversazionale che spesso è inutile, inquina la context window e porta il modello fuori strada. Questo fenomeno si chiama Context Bloat.

Context Engineering

Il termine “Context Engineering” viene spesso confuso con il prompt engineering, ma sono concetti distinti. Il prompt engineering riguarda la formulazione della singola richiesta all’LLM. Il Context Engineering è qualcosa di più ampio: è il controllo sistematico di tutto ciò che entra nella context window del modello — system prompt, istruzioni persistenti (come il CLAUDE.md), risultati di tool, file di codice caricati, memoria delle interazioni precedenti, e solo in ultimo il prompt dell’utente.

Pensate al contesto come a un programma: ogni elemento che vi inserite è un’istruzione che il modello eseguirà (o tenterà di eseguire). Più istruzioni contraddittorie o irrilevanti inserite, più il “programma” diventa imprevedibile.

Con questa prospettiva, le tecniche di SDD sono essenzialmente tecniche di Context Engineering: massimizzano l’efficacia della context window rendendo modulare lo sviluppo (SPEC → PIANO → CLARIFY → IMPLEMENTATION) e soprattutto minimizzando il rumore. Ogni fase opera in un contesto pulito e dedicato, con solo le informazioni rilevanti per quel task specifico.

Divide et impera

Nell’ambito dello sviluppo software, molti (anche molti sviluppatori di oggi) pensano che l’LLM serva solo per scrivere il codice, mentre le tecniche di SDD si basano sull’assunto che il Progettista utilizzi l’LLM su tutta la pipeline di lavoro del software.

FaseObiettivoUtilizzo LLM
IdeazioneEsplorazione dello spazio delle soluzioniPer un determinato problema, esiste un numero potenzialmente infinito di soluzioni e gli LLM sono uno strumento formidabile per esplorarle
SpecificheDefinizione dettagliata dei requisiti utenteOltre a definire le specifiche di dettaglio, in questa fase vengono anche individuati eventuali gap e aree di ambiguità
DisegnoAvere una solida baseline su cui scrivere il codice senza “improvvisare”Ricerca, espansione, approfondimento e selezione delle componenti software da creare/modificare e del piano di sviluppo e della modalità di test
ImplementazioneTradurre il disegno in codiceScrittura del codice e dei test
TestVerifica del softwareEsecuzione dei test e identificazione dei bug
💡 Tip
  • Per ogni fase, vale la pena valutare di volta in volta l’LLM più adatto. Ad esempio, al momento della scrittura Claude Opus 4.6 è tra i più performanti nel coding puro, ma modelli come le ultime versioni di ChatGPT, Gemini 3 o Kimi k2.5 possono essere più efficaci e creativi nelle fasi di esplorazione delle soluzioni.
  • Riutilizzare lo stesso contesto per un intero ciclo di sviluppo è fortemente sconsigliato, anche se il modello supporta milioni di token. Il motivo è il Context Bloat discusso sopra: le decisioni architetturali della fase di Piano, i dettagli delle user story della fase di Specifica, e il codice della fase di Implementazione competono tutti per l’attenzione del modello. Il risultato è un degrado progressivo della qualità su tutte le fasi, non solo sull’ultima.

Cos’è l’SDD

La Spec-Driven Development (SDD) è un paradigma che tratta le specifiche come fonte primaria di verità di un sistema software. Il codice diventa un artefatto secondario, generato o verificato rispetto alla specifica. Invece del classico approccio “scrivi il codice prima, documenta dopo”, l’SDD inverte il flusso: si scrivono specifiche chiare e strutturate del comportamento atteso e poi si genera, implementa o verifica il codice rispetto ad esse.

In altre parole: la specifica è il prodotto, il codice è un sottoprodotto.

Questo concetto non è nuovo in assoluto. L’API-first development con OpenAPI, il BDD (Behavior-Driven Development) e i contract-driven testing esistono da anni. Ciò che cambia oggi è che gli LLM rendono possibile automatizzare l’intero flusso: dalla specifica al piano tecnico, dal piano ai task, dai task al codice, dal codice ai test. La specifica diventa un vero e proprio control plane che orchestra agenti AI e sviluppatori umani.

Un recente paper su arXiv formalizza l’SDD così: “Le specifiche sono la fonte di verità; il codice deriva da esse. La specifica è la descrizione autoritativa che umani e macchine usano per comprendere, costruire e far evolvere il sistema.”

I livelli dell’SDD

Non esiste un unico modo di applicare l’SDD. Si possono identificare tre livelli di rigore:

  • Spec-first: la specifica viene scritta prima dell’implementazione e guida lo sviluppo iniziale. Ideale per nuovi servizi, API o feature con più consumatori.
  • Spec-anchored: specifica e codice evolvono insieme, mantenuti in sincronia tramite test e validazione. È il livello più pratico per la maggior parte dei team in produzione.
  • Spec-as-source: gli umani editano solo le specifiche; il codice viene generato da esse. Adatto a domini altamente regolamentati o strutturati dove la tracciabilità dal requisito al codice deve essere rigorosa.

La maggior parte dei team troverà nello spec-anchored il giusto compromesso tra rigore e agilità.

Overview dei principali framework

L’ecosistema di strumenti per l’SDD si sta sviluppando rapidamente. Ecco i tre framework più rilevanti:

Spec Kit (GitHub)

Spec Kit è il toolkit open-source di GitHub per l’SDD. Propone un workflow multi-fase (Specify → Plan → Tasks → Implement) e genera artefatti Markdown versionati nel repository. È compatibile con GitHub Copilot, Claude Code, Cursor e Gemini CLI. Approfondiremo Spec Kit nel prossimo capitolo.

OpenSpec (Fission AI)

OpenSpec è un framework leggero e open-source (TypeScript) pensato per portare determinismo nello sviluppo AI. Le sue caratteristiche distintive:

  • Delta Specs: cattura i cambiamenti incrementali nei requisiti, anziché riscrivere l’intera specifica
  • Brownfield-first: progettato per evolvere codebase esistenti, non solo per progetti greenfield
  • Nessuna API key o installazione complessa: le specifiche vivono nel repository accanto al codice
  • Supporta oltre 20 strumenti, tra cui Claude Code, Cursor e GitHub Copilot

BMAD Method

Il BMAD Method (Breakthrough Method for Agile AI-Driven Development) è un framework open-source più ambizioso, con:

  • 21 agenti AI specializzati (Analyst, Product Manager, Architect, Developer, QA, Scrum Master, …) ognuno con ruoli e responsabilità definiti
  • 50+ workflow guidati per diversi tipi di progetto e fasi
  • Architettura multi-agente: gli agenti collaborano dall’ideazione all’implementazione
  • Compatibile con Claude Code, Cursor, Windsurf e altri IDE AI

Ecco una guida rapida per orientarsi nella scelta:

CriterioSpec KitOpenSpecBMAD
Complessità di setupBassa (CLI + Markdown)Molto bassa (file nel repo)Media-alta (21 agenti da configurare)
Ideale perProgetti greenfield con GitHubEvoluzione di codebase esistentiProgetti enterprise con team strutturati
Curva di apprendimento~1 ora~30 minuti~1 giorno
Lock-inBasso (Markdown + Git)Nessuno (file nel repo)Medio (dipendenza dal framework)
Supporto brownfieldLimitatoEccellente (Delta Specs)Buono

In generale: partite con Spec Kit se usate GitHub e volete un workflow strutturato ma leggero. Scegliete OpenSpec se dovete evolvere una codebase esistente senza stravolgere il workflow. Valutate BMAD solo se il vostro progetto richiede coordinamento multi-ruolo e avete il budget di tempo per configurare l’intera orchestra di agenti.

Deep dive su Spec Kit

Spec Kit merita un approfondimento perché rappresenta lo stato dell’arte dell’SDD applicata ai coding agent ed è sostenuto direttamente da GitHub e Microsoft.

Il workflow di Spec Kit si articola in passi ben definiti, ognuno con un comando dedicato:

1. Costituzione del progetto (/speckit.constitution)

Si definiscono i principi non-negoziabili del progetto: standard di codifica, requisiti di test, regole di sicurezza, principi UX, target di performance. La constitution viene consultata automaticamente in ogni fase successiva come vincolo.

2. Specifica funzionale (/speckit.specify)

Si trasforma un’idea in una specifica funzionale strutturata: user story, requisiti funzionali, criteri di accettazione. Nessun dettaglio tecnico qui — solo il cosa e il perché. Spec Kit crea automaticamente un branch Git dedicato alla feature.

3. Chiarificazione (/speckit.clarify)

L’agente AI pone domande strutturate per eliminare ambiguità dalla specifica: casi limite, vincoli, gestione degli errori, permessi. Questa fase è fondamentale: una specifica ambigua produce codice ambiguo.

4. Piano tecnico (/speckit.plan)

La specifica validata viene tradotta in un piano tecnico dettagliato: decisioni architetturali, modelli dati, API, integrazioni. Qui si sceglie lo stack, i pattern e le interfacce. Gli artefatti generati includono plan.md, data-model.md, e una cartella contracts/ con le specifiche API.

5. Validazione (/speckit.checklist, /speckit.analyze)

Controllo di qualità e coerenza tra tutti gli artefatti prima di scrivere codice. Si verificano inconsistenze, gap e problemi di qualità.

6. Scomposizione in task (/speckit.tasks)

Il piano viene scomposto in unità di lavoro piccole e reviewable: ogni task ha input, output e criteri di successo espliciti legati alla specifica. I task sono ordinati per dipendenze e quelli parallelizzabili sono marcati.

7. Implementazione (/speckit.implement)

L’agente AI esegue i task, generando e modificando codice, test e configurazioni secondo il piano. Il codice viene prodotto in piccoli diff, facilmente reviewable.

Un esempio pratico

Immaginiamo di voler sviluppare una semplice API per la gestione di una libreria di libri. Ecco come si svolgerebbe il flusso con Spec Kit:

Fase 1 - Constitution:

/speckit.constitution
Il progetto segue un approccio API-first. Usiamo Python con FastAPI.
Ogni endpoint deve avere test unitari. Sicurezza: autenticazione JWT.
Database PostgreSQL con Alembic per le migrazioni.

Fase 2 - Specify:

/speckit.specify
Costruire un'API REST per gestire una libreria di libri.
Gli utenti possono cercare libri per titolo, autore o ISBN.
Gli amministratori possono aggiungere, modificare e rimuovere libri.
Ogni libro ha: titolo, autore, ISBN, anno di pubblicazione, genere.
Include user story e criteri di accettazione.

A questo punto Spec Kit genera un file spec.md strutturato con user story del tipo:

  • Come utente, voglio cercare libri per titolo, così da trovare rapidamente il libro che mi interessa
  • Come amministratore, voglio aggiungere un nuovo libro al catalogo, specificando tutti i metadati

Fase 3 - Clarify: L’agente chiede ad esempio: “Ci sono limiti sul numero di risultati per pagina? Cosa succede se si tenta di inserire un ISBN duplicato? Quali campi sono obbligatori?”

Fase 4 - Plan: Viene generato un piano tecnico. Ecco un estratto realistico del plan.md generato:

# Piano Tecnico - API Libreria

## Architettura
- Framework: FastAPI con Pydantic v2 per validazione
- Database: PostgreSQL 16 con SQLAlchemy 2.0 (async)
- Migrazioni: Alembic con autogenerate
- Auth: JWT (access token 15min + refresh token 7d)

## Modello Dati

### Book
| Campo        | Tipo         | Vincoli                    |
|-------------|-------------|---------------------------|
| id          | UUID        | PK, auto-generato         |
| title       | VARCHAR(255)| NOT NULL, INDEX            |
| author      | VARCHAR(255)| NOT NULL, INDEX            |
| isbn        | VARCHAR(13) | UNIQUE, NOT NULL           |
| year        | INTEGER     | CHECK (year >= 1450)       |
| genre       | VARCHAR(100)| NULL                       |
| created_at  | TIMESTAMP   | DEFAULT now()              |

## Endpoint REST
- `GET /books?title=&author=&isbn=&page=1&size=20` → 200 + paginazione
- `GET /books/{id}` → 200 | 404
- `POST /books` → 201 | 400 (validazione) | 409 (ISBN duplicato)
- `PUT /books/{id}` → 200 | 404
- `DELETE /books/{id}` → 204 | 404
- Tutti i metodi POST/PUT/DELETE richiedono header `Authorization: Bearer <token>`

Notare il livello di dettaglio: tipi, vincoli, codici di risposta, regole di autenticazione. Non c’è ambiguità, e l’agente AI che riceverà questo piano non dovrà “indovinare” nulla.

Fase 5-6 - Checklist & Tasks: Vengono generati task come:

  1. Creare i modelli SQLAlchemy (Book, User)
  2. Configurare Alembic e creare la migrazione iniziale
  3. Implementare l’endpoint GET /books con filtri e paginazione
  4. Implementare l’endpoint POST /books con validazione
  5. Aggiungere autenticazione JWT
  6. Scrivere i test per ogni endpoint

Ogni task ha input, output e criteri di successo espliciti. I task parallelizzabili sono marcati con [P], quelli sequenziali sono ordinati per dipendenze.

Fase 7 - Implement: L’agente esegue ogni task, producendo codice e test verificabili.

Il punto chiave è che ogni fase produce artefatti Markdown versionati nel repository, creando una tracciabilità completa dall’idea al codice. Se tra sei mesi qualcuno chiede “perché questa API funziona così?”, la risposta è nella specifica.

Coding Agents

L’SDD è la metodologia, ma per metterla in pratica servono gli strumenti giusti. I coding agent sono la componente operativa di questo nuovo paradigma: agenti AI che non si limitano al completamento automatico, ma pianificano task, modificano codebase, eseguono test e collaborano attraverso i workflow DevOps esistenti.

Come funziona un coding agent (sotto il cofano)

Prima di passare in rassegna gli strumenti, vale la pena capire cosa distingue un “agente” da un semplice chatbot. Un coding agent opera secondo un loop agentico continuo, che in pseudo-codice si può rappresentare così:

while task is not complete:
    context  = gather(specs, code, test_results, errors)
    plan     = reason(context)           # l'LLM decide cosa fare
    action   = select_tool(plan)         # scelta del tool: edit, bash, search...
    result   = execute(action)           # esecuzione reale nel filesystem/terminale
    feedback = verify(result)            # test, lint, output del comando
    if feedback.has_errors:
        context.append(feedback)         # l'errore diventa input per il prossimo ciclo

Il meccanismo chiave è il tool use (o function calling): l’LLM non genera solo testo, ma emette chiamate strutturate a strumenti esterni — editor di file, terminale bash, browser, API. Questo gli permette di interagire con il mondo reale: leggere un file, modificarlo, eseguire i test e reagire ai risultati.

La differenza fondamentale tra i vari agenti sul mercato sta in quali tool hanno a disposizione e in quale ambiente operano:

  • Agenti con accesso diretto al filesystem (Claude Code, Cursor): operano sulla tua macchina, con accesso completo a terminale e file. Massima flessibilità, ma richiedono supervisione.
  • Agenti in sandbox isolata (Devin, GitHub Copilot coding agent): operano in un ambiente cloud dedicato. Più sicuri per l’autonomia completa, ma meno flessibili per workflow personalizzati.

Il panorama dei coding agent si è evoluto rapidamente e oggi possiamo distinguere diverse categorie:

Agenti integrati nell’ecosistema

  • GitHub Copilot coding agent: lavora direttamente nel workflow delle Pull Request. Puoi assegnare una issue a @copilot e l’agente pianifica, modifica il codice, esegue i test e apre una PR autonomamente. È il target nativo di Spec Kit.
  • Amazon Q Developer: l’assistente AI di AWS, particolarmente forte per lo sviluppo cloud-native, IaC e le trasformazioni applicative (es. migrazione Java 8→17).
  • Google Gemini Code Assist: forte integrazione con i servizi Google Cloud (BigQuery, Firebase, Apigee). Supportato esplicitamente da Spec Kit come target SDD.

Agenti editor-first

  • Cursor: un fork di VS Code nativamente AI-first. La modalità Agentic + Composer permette di pianificare task multi-step, modificare più file, eseguire comandi nel terminale e iterare fino al superamento dei test.
  • JetBrains AI Assistant & Junie: integrato in tutti gli IDE JetBrains, Junie offre programmazione agentica per implementare fix, refactoring e test.

Piattaforme agente

  • Claude Code / Claude Agent SDK: piattaforma di Anthropic basata sul principio “dai all’agente un computer”. Claude Code ha accesso a terminale e file system e opera con un ciclo continuo: raccogli contesto → agisci → verifica → ripeti. L’Agent SDK permette di costruire agenti personalizzati.
  • Devin (Cognition): agente completamente autonomo con il proprio ambiente di sviluppo integrato (shell, editor, browser). Ancora sperimentale e poco “enterprise”

Quale agente scegliere?

Per un’azienda che vuole adottare l’SDD oggi, un approccio pragmatico è:

  • GitHub Copilot o Amazon Q per il lavoro issue/PR-driven sui servizi core
  • Gemini Code Assist per workflow SDD su analytics e integrazioni GCP
  • Cursor o JetBrains nell’IDE per implementazione ad alta fedeltà dalle specifiche
  • Claude Code / Agent SDK per pipeline SDD personalizzate dove gli strumenti standard sono troppo rigidi

Il valore aggiunto dei file istruzione: CLAUDE.md

Uno dei concetti più potenti emersi con i coding agent è quello dei file di istruzione persistente: file Markdown che l’agente legge automaticamente all’inizio di ogni sessione per comprendere il contesto del progetto. Ogni agente ha il suo formato (.github/copilot-instructions.md per Copilot, .cursorrules per Cursor, ecc.), ma il più noto e maturo è il CLAUDE.md di Claude Code.

Che cos’è CLAUDE.md

CLAUDE.md è un file di istruzione specifico per progetto che Claude Code legge automaticamente all’avvio in una directory. Il suo scopo è:

  • Dare a Claude il contesto minimo che non può inferire dal codice
  • Codificare regole critiche e caveat che devono essere rispettati in ogni task
  • Migliorare affidabilità e velocità evitando spiegazioni ripetute

Va pensato come un system prompt curato con attenzione, non come una wiki. È un contratto vivente tra la codebase e gli agenti AI.

Come impostare un buon CLAUDE.md

Le best practice, confermate sia dalla documentazione Anthropic che dalla esperienza empirica della Community, convergono su alcuni principi chiave. Questi principi non sono specifici di Claude Code ma derivano dalle caratteristiche generali degli LLM, di conseguenza valgono per qualsiasi assistente o coding Agent, anche se il formato specifico può variare a seconda dello strumento.

1. Less is more

Ogni riga aggiuntiva può ridurre la qualità complessiva del rispetto delle istruzioni. Gli LLM possono seguire con alta fedeltà solo un numero limitato di istruzioni distinte. Quando ce ne sono troppe, l’aderenza a tutte le regole degrada — non vengono ignorate le ultime, peggiorano tutte.

2. Alto segnale, basso rumore

Includere solo informazioni che sono:

  • Difficili da inferire per Claude leggendo il codice
  • Rilevanti per la grande maggioranza dei task quotidiani

3. La struttura minima efficace

Un buon CLAUDE.md contiene tipicamente tre blocchi:

# CLAUDE.md

## Progetto
Questo è un portale e-commerce Next.js + TypeScript che comunica
con le nostre API interne di pagamento e catalogo.

## Comandi chiave
- Installare dipendenze: `pnpm install`
- Dev server: `pnpm dev`
- Build: `pnpm build`
- Test: `pnpm test`
- Lint: `pnpm lint`

## Caveat IMPORTANTI
- IMPORTANTE: Non modificare `prisma/schema.prisma` direttamente.
  Usare `pnpm db:migrate` e `pnpm db:generate`.
- IMPORTANTE: L'endpoint `/api/webhooks/stripe` si aspetta il body
  raw della request. NON usare un body parser.
- Le immagini in `public/` devono essere ottimizzate prima del commit;
  file > 200KB faranno fallire la CI.

4. Non mettere regole di stile

Regole come “usa due spazi per l’indentazione” o “usa single quotes” sono uno spreco di istruzioni: Claude le inferisce dal codice esistente, e comunque linter e formatter le gestiscono meglio.

5. Disclosure progressiva

Per informazioni dettagliate ma raramente necessarie, non appesantire il file principale. Piuttosto:

## Documentazione aggiuntiva
- Schema database e migrazioni: leggere `docs/schema.md` quando
  si modificano i modelli.

Claude aprirà docs/schema.md solo quando necessario, invece di caricarlo ad ogni task.

6. Regole path-specific con .claude/rules/

Claude Code supporta file di istruzione specifici per path:

# .claude/rules/tests.md
paths: ["**/*.spec.ts", "**/*.test.ts"]

## Regole di test
- Usare Vitest, non Jest.
- Usare gli helper in `test-utils/` per il rendering dei componenti.

Questo file viene caricato solo quando Claude lavora su file di test, mantenendo il CLAUDE.md globale più snello.

7. Manutenzione continua

Trattare CLAUDE.md come un documento vivente: aggiornarlo quando si nota che Claude ripete errori evitabili, rimuovere istruzioni obsolete, riordinare per importanza. Le regole più importanti vanno sempre in cima al file.

Limiti e rischi dell’SDD

Sarebbe disonesto presentare l’SDD come una soluzione priva di criticità. Ci sono limiti concreti che è bene conoscere prima di adottarla:

  • Non-determinismo. Gli LLM non sono deterministici: la stessa specifica, data allo stesso modello in due momenti diversi, può produrre codice strutturalmente diverso. Questo significa che l’SDD non garantisce riproducibilità. La specifica riduce drasticamente la varianza rispetto a un prompt generico, ma non la elimina. Per questo i contract test e la validazione automatica sono indispensabili — sono il “guardrail deterministico” che compensa la natura probabilistica del modello. Allo stesso tempo, però, vale la pena riflettere sul fatto che, in generale, lo stesso concetto vale anche per gli esseri umani: lo stesso sviluppatore, leggendo la stessa specifica in due momenti diversi, può scrivere codice diverso.
  • Garbage in, garbage out (spostato di livello). Se uso un LLM per generare le specifiche stesse, chi le valida? Il rischio è di automatizzare la produzione di specifiche plausibili ma errate — ad esempio, un modello dati che sembra ragionevole ma viola una regola di business non esplicitata. La revisione umana delle specifiche non è opzionale: è il punto di controllo critico dell’intero workflow.
  • Scalabilità. L’esempio della libreria di libri funziona bene, ma cosa succede con un sistema distribuito di 200 microservizi? L’SDD scala bene fino a quando le specifiche restano modularizzabili — un servizio alla volta, una feature alla volta. Quando le dipendenze cross-service diventano troppo intricate, le specifiche rischiano di diventare esse stesse un problema di manutenzione. Non è un motivo per non adottare l’SDD, ma è un motivo per non pensarla come una bacchetta magica.
  • Costi. Un workflow SDD completo (specify → clarify → plan → tasks → implement) consuma significativamente più token di un singolo prompt. Ogni fase è una o più chiamate all’LLM, ognuna con il proprio contesto. Su modelli di punta come Claude Opus o GPT-4, un ciclo completo per una feature di media complessità può costare tra i 5 e i 20 dollari in token. È un investimento che si ripaga ampiamente in termini di tempo risparmiato, ma va pianificato — soprattutto per team che lavorano su decine di feature in parallelo.
  • Overhead per progetti semplici. Un workflow SDD completo per uno script di 50 righe è over-engineering. L’SDD dà il meglio su feature con complessità medio-alta, dove le ambiguità sono il vero costo. Per task banali, un buon prompt diretto resta la scelta migliore.

Tutti questi limiti sono tuttavia gestibili attraverso un approccio disciplinato e consapevole. In altre parole, un approccio naive in stile “vibe-coding” può andar bene per un piccolo prototipo, ma all’aumentare della complessità del progetto è necessario applicare le tecniche di SDD sempre con maggior rigore per evitare di incorrere in questi problemi.

Conclusioni

La Spec-Driven Development non è una moda passeggera né un esercizio accademico.

L’SDD è un approccio metodologico e disciplinato allo sviluppo del software tramite AI Agents, che sfrutta le capacità degli agenti su tutto lo stack di sviluppo, dalla esplorazione dello spazio delle soluzioni, alla scrittura di specifiche dettagliate, alla pianificazione tecnica, fino all’implementazione e al testing.

Ma come abbiamo visto, non è priva di limiti: il non-determinismo degli LLM, il rischio di specifiche errate, i costi in token e l’overhead per progetti semplici sono tutti fattori da considerare. L’SDD funziona meglio quando applicata con giudizio, non come dogma.

Per chi lavora nello sviluppo software oggi, il messaggio è chiaro:

  1. Investite nelle competenze trasversali: architettura, DevOps, modelli dati, sicurezza. Il Progettista del futuro non è chi scrive il codice più veloce, ma chi scrive le specifiche più precise.
  2. Adottate gradualmente: partite con l’API-first e i contract test. Poi aggiungete un framework SDD come Spec Kit su una feature nuova. Misurate i risultati.
  3. Abbandonate il Vibe Coding: scrivere prompt vaghi e sperare nel meglio non scala. Investire una giornata in specifiche per risparmiare due settimane di lavoro non è “perdere tempo” — è il mestiere del Progettista.
  4. Preparatevi al cambio di mentalità: sarà meno “divertente” nel senso tradizionale, ma la soddisfazione di orchestrare un sistema complesso attraverso specifiche che producono software funzionante è, a suo modo, altrettanto appagante.

Il futuro dello sviluppo software non è scrivere codice. È progettare sistemi e lasciare che il codice si scriva da solo — ma sotto il controllo rigoroso di chi sa cosa vuole ottenere.