Pattern di Sviluppo nell'Era dell'IA: ConceptDoc e la Collaborazione Uomo-Macchina

Collaborazione tra sviluppatori umani e IA
Un nuovo modello di collaborazione Uomo-Ai nel mondo dello sviluppo software
Matteo 11 min

L’altro giorno stavo cercando di far generare del codice a un assistente IA. Il progetto era complesso, con decine di classi e un flusso di dati non proprio intuitivo. Nonostante i miei tentativi di spiegare chiaramente cosa volessi, l’IA continuava a commettere lo stesso errore: accoppiava codice e dati in modi che non avevano senso per il mio caso d’uso.

Dopo diversi tentativi frustrati con vari prompt testuali, ho avuto un’dubbio: forse il problema non era l’IA, ma il formato con cui stavo cercando di comunicare le mie intenzioni.

Ho deciso di provare un approccio diverso: ho creato un file YAML strutturato con specifiche chiare e alcuni esempi concreti. La differenza è stata immediata - l’IA ha compreso esattamente cosa volevo fare.

È stato in quel momento che ho avuto un’illuminazione: stavo programmando insieme a un collega che ragiona in modo fondamentalmente diverso da me, e avevo appena trovato un modo migliore per comunicare con lui.

Questa esperienza mi ha fatto realizzare qualcosa di fondamentale: le IA comprendono molto meglio le specifiche strutturate rispetto alle descrizioni in linguaggio naturale, specialmente quando si tratta di concetti complessi o relazioni tra entità.

E questa è stata la scintilla che mi ha portato a riflettere su come i nostri pattern di sviluppo, creati da e per gli umani, potrebbero evolvere in un futuro in cui l’intelligenza artificiale è un membro attivo del team di sviluppo. Da questa realizzazione è nato ConceptDoc - un tentativo di standardizzare questo tipo di comunicazione strutturata tra umani e IA nel contesto dello sviluppo software.

Due Cervelli, Due Modi di Pensare

Per decenni abbiamo progettato pattern e pratiche di sviluppo pensando solo alle capacità e ai limiti della mente umana. Ma ora che l’IA sta diventando uno strumento quotidiano per molti sviluppatori, dobbiamo iniziare a considerare come funzionano entrambi i “cervelli”.

Memoria e Contesto

La prima grande differenza che ho notato riguarda la memoria:

Noi umani abbiamo una memoria di lavoro limitata. Possiamo tenere a mente solo circa 7±2 elementi alla volta (ricordate il Magical Number Seven?). È per questo che adoriamo l’incapsulamento e l’astrazione: ci permettono di nascondere la complessità e concentrarci su un problema alla volta.

L’IA, invece, può analizzare contemporaneamente enormi quantità di codice senza “stancarsi” o dimenticare parti importanti. Ma anche lei ha i suoi limiti di contesto e spesso manca della profonda comprensione contestuale che un umano acquisisce dopo anni di lavoro su un progetto.

Astrazione vs Dettaglio

Un’altra differenza fondamentale:

Noi umani amiamo le astrazioni di alto livello. Preferiamo pensare in termini di “questa classe gestisce gli ordini” piuttosto che seguire mentalmente ogni singola chiamata di funzione. I design pattern classici ci aiutano a organizzare il codice in chunk cognitivamente gestibili.

L’IA, invece, eccelle nell’analisi dettagliata e nel tracciamento di relazioni complesse. Non si “confonde” seguendo una catena di 10 chiamate di funzione attraverso diverse classi. Anzi, spesso è più accurata degli umani in questo tipo di analisi.

ConceptDoc: Un Nuovo Standard per la Collaborazione Uomo-IA

Da queste osservazioni è nato ConceptDoc, un progetto open source che sto sviluppando per creare un nuovo standard di documentazione avanzata che funzioni sia per gli umani che per l’IA.

In pratica si tratta di file di documentazione parallela che affiancano i file di codice e forniscono contesto ricco e strutturato sia per gli sviluppatori umani che per i sistemi di IA.

src/
├── file.py
├── file.py.cdoc  <- File di documentazione parallela

Questi file .cdoc (in formato JSON o YAML) contengono metadati strutturati che vanno ben oltre i tradizionali commenti o docstrings:

  • Modello di stato con transizioni esplicite
  • Invarianti che il sistema deve mantenere
  • Precondizioni e postcondizioni per ogni metodo
  • Esempi di input/output
  • Fixtures standardizzate pronte per essere utilizzate in test e simulazioni
  • Test concettuali che descrivono scenari e flussi in linguaggio naturale strutturato
  • Note specifiche per l’IA per guidare la generazione di codice
  • Storia delle modifiche con motivazioni business

ConceptDoc in Pratica: L’App Todo List

Per comprendere meglio il valore di ConceptDoc, diamo un’occhiata a un esempio concreto tratto dal repository: una semplice App Todo List. Questa app di esempio ha tre componenti principali:

1. `todo_item.py`         Il modello di dominio
2. `storage_service.py`   Il servizio di persistenza
3. `todo_service.py`      La logica di business

Ogni file ha un corrispondente .cdoc che fornisce documentazione strutturata. Vediamo come funziona esaminando i concetti chiave di ConceptDoc attraverso questo esempio.

1. Documentazione Parallela Strutturata

ConceptDoc utilizza file di documentazione parallela che affiancano i tuoi file di codice:

├── models/
│   ├── todo_item.py
│   ├── todo_item.py.cdoc  <- File di documentazione ConceptDoc

Questi file .cdoc contengono metadati strutturati in formato JSON che vanno ben oltre i commenti tradizionali. Prendiamo ad esempio todo_item.py.cdoc:

{
  "metadata": {
    "filename": "todo_item.py",
    "version": "1.0.0",
    "lastUpdate": "2025-03-22"
  },
  "purpose": "Provides business logic for managing todo items, including creation, retrieval, updates, and persistence",
  "invariants": [
    "Todo IDs are unique and never reused",
    "The internal list of todos is always in sync with the storage service after operations",
    "Todo titles cannot be empty",
    "Todo titles cannot exceed 100 characters"
  ],
  "stateModel": {
    "states": ["active", "completed"],
    "initialState": "active",
    "transitions": [
      {
        "from": "active",
        "to": "completed",
        "trigger": "complete()",
        "conditions": []
      },
      {
        "from": "completed",
        "to": "active",
        "trigger": "reactivate()",
        "conditions": []
      }
    ]
  }
}

Questo approccio offre il meglio dei due mondi: il codice rimane pulito e leggibile per gli umani, mentre l’IA ha accesso a metadati strutturati che può utilizzare per comprendere meglio il contesto.

2. Test Concettuali

A differenza dei test tradizionali scritti in codice, questi test sono descrizioni ad alto livello che un’IA può interpretare, tradurre in test concreti o utilizzare per verificare la correttezza concettuale del codice. Potrebbero essere particolarmente utili per testare flussi complessi e scenari edge che richiederebbero molte righe di codice per essere implementati.

Ecco un esempio tratto da todo_service.py.cdoc:

"conceptualTests": [
  {
    "name": "Todo CRUD operations",
    "steps": [
      {
        "action": "Initialize TodoService with empty storage",
        "expect": "TodoService instance with empty todos list and _next_id = 1"
      },
      {
        "action": "create_todo('Test todo')",
        "expect": "New TodoItem with id=1, title='Test todo', is_completed=False"
      },
      {
        "action": "get_todo(1)",
        "expect": "Returns the TodoItem with id=1"
      },
      {
        "action": "update_todo(1, 'Updated todo')",
        "expect": "TodoItem with id=1 has title='Updated todo'"
      }
    ]
  }
]

A differenza dei test unitari o di integrazione tradizionali:

  • Sono espressi in un formato dichiarativo ad alto livello
  • Descrivono il comportamento atteso in termini di business logic
  • Possono essere compresi sia da umani che da IA
  • Non sono legati a specifiche implementazioni tecniche
  • Possono essere tradotti in test concreti da un’IA

Questo approccio colma il divario tra i test tecnici e i requisiti di business, fornendo un livello intermedio che verifica la correttezza concettuale del sistema.

3. Componenti ben Documentati

I file ConceptDoc forniscono documentazione dettagliata di ogni componente, inclusi precondizioni, postcondizioni ed errori possibili:

"components": [
  {
    "name": "TodoService.create_todo",
    "signature": "create_todo(title: str) -> TodoItem",
    "description": "Creates a new todo item",
    "preconditions": [
      "title must be a valid string"
    ],
    "postconditions": [
      "A new TodoItem is created with the specified title",
      "The new TodoItem is added to the todos list",
      "The todos list is saved to storage",
      "_next_id is incremented"
    ],
    "errors": [
      {
        "condition": "title is empty",
        "response": "ValueError",
        "mitigation": "Validate title before calling"
      }
    ]
  }
]

Questa documentazione strutturata rende immediatamente comprensibili le aspettative e i comportamenti di ogni componente, sia per gli sviluppatori umani che per le IA.

La Questione degli Attributi e delle Annotations

Alcuni linguaggi moderni come PHP 8+, Java e Python hanno introdotto annotations o attributi che permettono di associare metadati al codice in modo strutturato:

#[Route("/api/users", methods: ["GET"])]
#[Security("is_granted('ROLE_ADMIN')")]
public function getUsers(): Response
{
    // ...
}

Questi costrutti vanno nella direzione giusta, ma hanno alcune limitazioni:

  1. Sono principalmente orientati alla configurazione piuttosto che alla documentazione completa
  2. Hanno limitata espressività e si concentrano su casi d’uso specifici
  3. Mescolano metadati con il codice, portando a file sovraccarichi

ConceptDoc risolve questi problemi con un sistema di metadati più completo e separato dal codice, mantenendo il codice pulito e la documentazione ricca.

Vantaggi per Sviluppatori e Team

L’adozione di ConceptDoc porta numerosi vantaggi:

  • Onboarding più rapido: I nuovi sviluppatori hanno accesso a contesto ricco e strutturato
  • Generazione di codice più accurata: Gli strumenti IA producono codice più aderente ai requisiti
  • Testing più intelligente: L’IA può eseguire test concettuali che verificano l’aderenza alla logica di business
  • Dati di test consistenti: Le fixtures standardizzate garantiscono coerenza nei test automatici e manuali
  • Verifica automatica di invarianti: L’IA può controllare che il codice rispetti tutte le invarianti dichiarate
  • Documentazione sempre aggiornata: Con gli strumenti giusti, mantenere sincronizzati codice e documentazione diventa più facile

Development-by-Specification: Prima il ConceptDoc, Poi il Codice

Una delle idee più rivoluzionarie di ConceptDoc è la possibilità di invertire il tradizionale flusso di sviluppo. Invece di scrivere prima il codice e poi documentarlo (cosa che, ammettiamolo, spesso non succede), possiamo adottare un approccio “specification-first”:

  1. Scrivi il ConceptDoc: Definisci stati, invarianti, precondizioni, test concettuali
  2. L’IA genera il codice: Basandosi sulle specifiche strutturate nel ConceptDoc
  3. Raffina e migliora: Perfeziona il codice generato con la tua esperienza e feedback

Questo approccio rende più facile mantenere il codice sincronizzato con le specifiche, riduce il rischio di errori e migliora la qualità del prodotto.

┌────────────┐      ┌─────────────┐      ┌──────────────────────────┐
│ ConceptDoc │─────▶│ L'Ai genera │─────▶│ Raffinamento \ Revisione │
└────────────┘      └─────────────┘      └──────────────────────────┘

Un Esempio Concreto

Immagina di voler implementare un servizio di autenticazione. Seguendo l’approccio ConceptDoc, inizieresti definendo un file auth_service.py.cdoc:

{
  "purpose": "Gestisce l'autenticazione e l'autorizzazione degli utenti",
  "stateModel": {
    "states": ["unauthenticated", "authenticated", "locked"],
    "transitions": [
      {
        "from": "unauthenticated",
        "to": "authenticated",
        "trigger": "login(credentials)",
        "conditions": ["Valid credentials", "Account not locked"]
      },
      {
        "from": "authenticated",
        "to": "unauthenticated",
        "trigger": "logout()",
        "conditions": []
      },
      {
        "from": "unauthenticated",
        "to": "locked",
        "trigger": "failedLoginAttempt()",
        "conditions": ["Failed attempts >= 5"]
      }
    ]
  },
  "components": [
    {
      "name": "AuthService.login",
      "signature": "login(username: str, password: str) -> AuthResult",
      "preconditions": [
        "username must not be empty",
        "password must not be empty"
      ],
      "postconditions": [
        "If credentials are valid, user session is created",
        "If credentials are invalid, failedLoginAttempt() is called"
      ]
    }
  ]
}

Con questa specifica dettagliata, un assistente IA può generare un’implementazione iniziale che:

  1. Gestisce correttamente tutti gli stati possibili
  2. Implementa le transizioni definite
  3. Mantiene le invarianti specificate
  4. Include gestione degli errori appropriata

Il risultato è un codice molto più robusto rispetto alla generazione basata su prompt testuali, perché deriva da una specifica formale e strutturata.

Affrontare la Sfida della Manutenzione

La sfida principale sarà l’overhead della manutenzione, ma ironicamente, le stesse IA potrebbero aiutare a mantenere questa documentazione aggiornata.

Immaginate un flusso di lavoro dove:

  1. Gli sviluppatori modificano il codice
  2. L’IA analizza i cambiamenti e suggerisce aggiornamenti corrispondenti ai file .doc
  3. Gli sviluppatori approvano o modificano questi aggiornamenti
  4. L’IA verifica la coerenza tra codice e documentazione

Questo creerebbe un ciclo virtuoso dove la documentazione rimane sincronizzata con il minimo sforzo umano, e dove sia il codice che la documentazione si migliorano reciprocamente nel tempo.

Verso un Futuro di Collaborazione

Credo che nei prossimi anni vedremo emergere nuovi pattern e pratiche specificatamente progettati per migliorare la collaborazione tra sviluppatori umani e IA. ConceptDoc potrebbe essere l’inizio di questa evoluzione, un ponte tra il modo di pensare umano e quello dell’IA.

Alcuni cambiamenti che prevedo:

  1. Più enfasi sulla documentazione strutturata che può essere facilmente analizzata sia da umani che da macchine
  2. Workflow “specification-first” dove il codice viene generato a partire dalle specifiche strutturate
  3. Convenzioni di codice più rigorose che facilitano l’analisi automatica
  4. Sistemi di tipi più forti che rendono esplicite le relazioni e i vincoli
  5. Strumenti che integrano l’analisi dell’IA direttamente nel flusso di sviluppo
  6. IDE evoluti che possono passare facilmente tra la “vista umana” e la “vista IA” del codice, e che permettono di editare sia il codice che le specifiche ConceptDoc

Conclusione: Un Nuovo Tipo di Collaborazione

Come sviluppatori, abbiamo costantemente evoluto le nostre pratiche per adattarci a nuove realtà: dal waterfall all’agile, dai server fisici al cloud, dai monoliti ai microservizi.

Ora è il momento di evolvere nuovamente, ripensando la documentazione e il testing per un’era in cui i nostri collaboratori non sono solo umani.

Immaginate un mondo dove:

  • Le IA eseguono automaticamente test concettuali ad ogni commit
  • Gli sviluppatori ricevono feedback immediato su violazioni di invarianti
  • I nuovi membri del team possono comprendere rapidamente la logica di business
  • La documentazione è sempre aggiornata perché è parte integrante del processo di sviluppo

Vi invito a sperimentare con questa idea nei vostri progetti. Creiamo insieme uno standard che porti la documentazione e il testing del software nel futuro.

Se sei interessato a esplorare o contribuire a ConceptDoc, puoi trovare il progetto su GitHub.

E tu, hai già notato cambiamenti nel tuo modo di programmare quando collabori con assistenti IA? Hai sviluppato pattern o pratiche specifiche per facilitare questa collaborazione? Condividi le tue esperienze nei commenti!

P.S. Mi chiedo se tra dieci anni, quando saremo in pieno “AI-Driven Development”, (sempre che l’IA non ci abbia sostituiti tutti) avremo libri di pattern intitolati “Design Patterns per Team Ibridi”. E mi chiedo anche se saranno scritti da umani, da IA, o da una collaborazione tra i due… 🤔


Risorse utili

content_copy Copiato