Il Cambiamento Che Conta Davvero#
La versione naive dello sviluppo assistito dall’AI è: descrivi cosa vuoi, l’AI lo scrive, tu revisioni e vai avanti. Questo è reale e utile, ma è anche la cosa meno interessante che l’AI fa per me.
Il cambiamento più importante è che l’AI rende l’indagine economica. Prima, quando incontravo un problema sconosciuto, dovevo scegliere: passare un’ora a leggere documentazione e tracciare percorsi nel codice, oppure fare un’ipotesi e iterare. Con l’AI, l’indagine ha un costo quasi nullo. Posso esplorare una codebase che non ho mai visto, capire il comportamento di un sistema dai suoi log, o ragionare sui modi in cui può fallire — in minuti invece di ore.
Questo cambia la forma del mio lavoro. Indago di più, assumo meno. Leggo l’errore con attenzione prima di tentare una soluzione. Mi chiedo “perché” prima di chiedermi “come risolverlo”.
Il Pattern Investigation-First#
Il pattern più costante che ho sviluppato è: prima di fare qualsiasi cosa, indaga.
Quando qualcosa si rompe, non vado direttamente alla soluzione. Incollo l’errore, i log rilevanti, il contesto circostante, e chiedo: cosa sta succedendo davvero? L’AI ragiona sul problema, spesso individuando la causa principale più velocemente di quanto farei tracciandola manualmente. Poi sistemiamo la cosa giusta.
Lo stesso pattern si applica alle decisioni di design. Prima di scrivere codice, descrivi il problema e chiedi: come lo affronteresti? Quali sono i trade-off? Non perché tu non possa pensarci da solo, ma perché farlo in conversazione fa emergere cose che avresti mancato lavorando da solo.
Autonomia Graduata#
Una delle dinamiche più interessanti è come concedo l’autorità in modo diverso a seconda del compito. La cosa fondamentale è mantenere ogni fase distinta — non saltare mai da “ho un problema” direttamente a “sistema tutto”.
flowchart TD
A([Qualcosa da investigare o costruire]) --> B[Esplorazione]
B -->|controlla, analizza, trova| C[Proposta]
C -->|cosa ne pensi?| D{Decisione}
D -->|raffina o reindirizza| C
D -->|approva| E[Esecuzione]
E -->|ok, sì, procedi| F([Fatto])
La fase di proposta è dove intercetto le assunzioni errate prima che diventino codice sbagliato.
Il Contesto È Tutto#
La qualità dell’output AI scala direttamente con la qualità del contesto che fornisci.
| Cosa fornire | Invece di |
|---|---|
| Il messaggio di errore reale | Una parafrasi di cosa è andato storto |
| Il codice rilevante | Una descrizione di cosa fa |
| Il documento di piano o spec | “Ecco più o meno cosa vogliamo” |
| Vincoli rigidi | Lasciarli impliciti |
Un prompt vago produce una risposta generica. Un prompt specifico con contesto ricco produce una risposta utile. I pochi secondi in più spesi a formulare bene una domanda producono una differenza enorme nella qualità dell’output.
Concatenare Compiti in una Sessione#
I tool AI sono più potenti quando usati come una sessione di lavoro sostenuta, non come una serie di domande isolate.
sequenceDiagram
participant Me
participant AI
Me->>AI: Perché questo servizio è lento?
AI-->>Me: Query N+1 in questo handler
Me->>AI: Sistemalo
AI-->>Me: Fatto, ecco cosa è cambiato
Me->>AI: Aggiungi anche un indice su quella colonna
AI-->>Me: Aggiunto
Me->>AI: Scrivi un test per il percorso corretto
AI-->>Me: Test scritto
Me->>AI: Commit e push
AI-->>Me: Fatto
Ogni passo costruisce sul precedente. L’AI ha pieno contesto di cosa abbiamo cambiato e perché. I pattern “anche” e “adesso” sono fondamentali — una volta stabilito il contesto, estendere il compito non costa quasi nulla.
AI per l’Infrastruttura, Non Solo per il Codice#
Una delle cose che mi ha sorpreso è quante valore aggiunge l’AI al di fuori della scrittura di codice applicativo.
Terraform, policy IAM, pipeline CI/CD, manifest Kubernetes — sono tutti testo strutturato con semantica complessa. L’AI è utile qui come nel codice applicativo, spesso di più, perché il costo degli errori è più alto e la documentazione è densa.
Descrivi cosa deve fare il servizio e ottieni una policy a privilegi minimi. La leggi, la verifichi, la applichi.
{
"Statement": [{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::my-bucket/*"
}]
}Incolla un confuso terraform plan e chiedi cosa significano davvero le modifiche prima di applicarle.
# ~ aggiornamento in-place
resource "aws_security_group_rule" "egress" {
~ cidr_blocks = ["10.0.0.0/8"] -> ["0.0.0.0/0"]
}Incolla il log di un job fallito e ottieni una diagnosi della causa. Niente più lettura solitaria di 500 righe di YAML.
ERROR: Failed to push to registry
unauthorized: authentication required
hint: check REGISTRY_TOKEN secret expiryL’Abitudine del Dry-Run#
Per qualsiasi compito che tocca la produzione o fa modifiche irreversibili, ho sviluppato un’abitudine costante: chiedere prima un dry-run.
“Cosa faresti se ti chiedessi di ruotare tutte le API key di questo servizio?”
L’AI descrive il suo piano. Verifico se ha capito bene l’ambito, se la sequenza delle operazioni ha senso, se ci sono casi limite che non ha considerato. Poi dico “ok, fallo”.
def run(task, dry_run: bool = False):
plan = agent.plan(task) # pianifica sempre prima
if dry_run:
return plan # restituisce il piano, nessun side effect
return agent.execute(plan)Il dry-run non riguarda solo la cattura degli errori. Riguarda la costruzione della fiducia nel tempo. Se il piano sembra giusto in modo costante, diventi più sicuro nel concedere piena autonomia.
Cosa Non Funziona#
Chiedere design completi in anticipo
“Progetta un sistema di autenticazione completo per la mia applicazione” produce una risposta generica.
“Ho un’app FastAPI, gli utenti sono già in Keycloak, e ho bisogno di proteggere questi tre endpoint” produce qualcosa di utilizzabile.
Problemi specifici ottengono soluzioni specifiche.
Usare l'AI come timbro di approvazione
Chiedere all’AI di revisionare codice che hai già deciso essere corretto produce un accordo educato.
Chiedi invece in modo avversariale: “Cosa potrebbe andare storto?” “Cosa mi sto perdendo?” “C’è un modo più semplice?”
Sovra-specificare compiti semplici
Ignorare le domande dell'AI
La Realtà Pratica#
L’AI non mi ha reso più veloce nello scrivere codice. Mi ha reso più veloce nel risolvere problemi. La distinzione è importante. Scrivere codice è raramente il collo di bottiglia nell’ingegneria del software. Capire cosa costruire, trovare l’approccio giusto, debuggare comportamenti inattesi, navigare sistemi sconosciuti — queste sono le parti difficili, e l’AI le rende tutte più veloci.
Spendo anche più tempo a leggere di quanto facessi prima. Quando l’AI produce codice, lo leggo per bene prima di fare il commit. Quando dà un piano, ci penso prima di dire “procedi.”
Gli ingegneri che ottengono di più dai tool AI non sono quelli che scrivono i prompt migliori. Sono quelli che indagano prima di agire, forniscono contesto reale, fanno domande avversariali e restano genuinamente nel loop. L’AI è un moltiplicatore di forza per le abitudini che rendono bravi gli ingegneri bravi, e un povero sostituto per esse.
Se stai lavorando su problemi simili o vuoi discuterne, scrivimi a manuel.fedele+website@gmail.com.