Agents and code

Agentic Coding

Essere tecnicamente all’avanguardia è uno dei principi fondanti di D/Vision Lab e come CTO dell’azienda, ho un ruolo attivo nel monitorare e valutare le nuove tecnologie. Benché ormai sia pratica diffusa usare gli LLM, un uso consapevole non è da dare per scontato. Acquisire i requisiti, sviluppare un software, metterlo in produzione, testarlo, sono attività complesse e gli agenti LLM possono portare un contributo in tutti questi passaggi. Molti degli sviluppatori con cui ho parlato concordano che spesso gli LLM sono molto efficaci specialmente su codebase nuove, su problemi piccoli e circoscritti, e faticano ad essere usati su repository più corposi con molti dettagli di dominio. In questo articolo vorrei fare alcune considerazioni, condividere alcune idee che ho trovato funzionare nell’uso degli LLM per la scrittura del codice.

Agenti? LLM?

Prima di continuare, una doverosa premessa: io userò le parole “agenti” e “LLM” in modo intercambiabile, in questo articolo, ma non sono la stessa cosa. Nel campo di ricerca che è l’Intelligenza Artificiale, gli “agenti” sono entità che possono interagire in un ambiente, percependone uno stato e agendo su di esso. Gli LLM, i Large Language Models, sono modelli basati su reti neurali che si sono rivelati particolarmente efficaci per l’interazione tramite linguaggio naturale umano e, in particolare, per scopi generativi (ovvero produrre testi che siano sensati). Essendo reti neurali con decine o centinaia di miliardi (se non migliaia di miliardi) di parametri, sono definiti “Large” Language Models. Ne esistono di diversi tipi, ma quelli di cui parleremo sono solitamente modelli autoregressivi che apprendono le distribuzioni di probabilità del linguaggio (o, almeno, cercano di approssimarle) tramite apprendimento auto-supervisionato (self-supervised learning) su corpus di testo molto vasti e con l’obiettivo di predire il prossimo token (pensiamo ad una lettera o una sillaba) di un certo testo.

Il nome LLM suggerisce l’esistenza di modelli non “large”, di cui però non ci occuperemo in questo articolo. Parlando in generale, gli LLM non sono agenti e gli agenti non sono LLM. In questo contesto, però, li userò in modo intercambiabile, perché parliamo di agenti per l’assistenza alla scrittura del codice basati su LLM. Nello specifico, parlo degli agenti come Claude (Anthropic), GPT (OpenAI), Llama (Meta), Gemini (Google), Qwen (Alibaba) e molti altri.

Fatta questa doverosa premessa, abbandoniamo gli aspetti un po’ più “teorici” e concentriamoci su quelli più “pratici”: come possiamo usare in modo efficace questi agenti per la scrittura del codice? È una domanda assolutamente legittima e molti programmatori stanno ancora sperimentando quali tecniche funzionino meglio e quali invece sono da scartare. Di seguito, condivido alcune osservazioni sulla mia esperienza.

Il codice è (ancora) una responsabilità

C’è un adagio, in inglese, che dice “code is a liability”: più codice abbiamo, più ne dobbiamo manutenere. Più codice c’é, più è alta la probabilità di bug. Tipicamente c’è anche una forte correlazione tra la complessità di una applicazione e la lunghezza del suo codice. La complessità si manifesta non solo nel numero di feature che un software ha, ma anche nel modo in cui queste feature interagiscono, e più interazioni ci sono, più diventa difficile controllare e far funzionare il software nel modo desiderato: senza bug, senza inconsistenze, soddisfando i requisiti nel modo più logico possibile.

Perché dico questo? Perché gli LLM permettono di scrivere molto codice molto in fretta. Ma questo codice è di qualità? Spesso lo è. I modelli recenti, come Opus 4.6 o Gemini 3.1 tendono a scrivere codice che contiene molte poche allucinazioni, che è sensato, scritto bene. Ricordate quando, appena 2 anni fa, la probabilità di ricevere codice completamente allucinato era tutt’altro che bassa? Ora questa cosa, nella mia esperienza, succede molto più di rado: gli agenti sono più efficaci, informati e possono fare ricerche per ottenere informazioni aggiornate. Che il codice sia buono è sicuramente una buona notizia, ma che l’agente faccia esattamente quello che serve a noi è un’altra. Quindi, magari il codice è di qualità, ma capita ancora di sovente che il codice scritto non vada nella direzione che mi serve.

È importante che un LLM sia ben allineato con le nostre intenzioni, con la nostra visione. Quindi il primo, forse ovvio, consiglio è: pianificate abbondantemente.

Se il codice è facile da produrre, sfruttate questa caratteristica. Non partite con un’idea per produrre subito il codice: ragionate con l’agente, come se stesse facendo pair programming, sul codice. Fatevi generare dei prototipi, dello pseudocodice, leggetelo, capitelo, fatevelo spiegare se qualcosa non è chiaro. Pensate ai prossimi passi. Pensate alla forma che secondo voi quel codice dovrà avere prima che venga generato. Pensate alle API che il vostro codice esporrà, pensate all’esperienza utente di chi dovrà interfacciarsi con esso e/o metterci le mani. Poi confrontatevi con la mezza-realtà che l’agente potrà sintetizzare per voi e iterate fino ad avere il codice ideale, rendendolo una realtà completa.

Questo, chiaramente, non è vibe-coding. Non credo che ci sia nulla di male nell’avere codice scritto da un LLM, ma credo che non sia saggio avere troppo codice – almeno in questa fase in cui l’AGI è ancora lontana.

C’è un secondo motivo per cui penso che sia utile adottare una strategia simile: il vostro codice verrà letto da umani. Gli umani non andranno necessariamente da un LLM a chiedere “come mai questa cosa è fatta così?”, ma più probabilmente verranno da voi, gli autori (o, almeno, gli editori) di quel codice. E cosa farete quando vi faranno domande su un codice che non conoscete? Se su git blame c’è il vostro nome, le persone sapranno a chi dare la colpa se qualcosa non funziona. Quindi, credo sia importante avere un’idea piuttosto buona di che forma abbia il codice generato, di come funzioni, di quali siano le componenti fondamentali e le loro interazioni. Non solo per rispondere a delle domande, ma per sapere che eventuali modifiche future verranno fatte con cognizione di causa, non solo da un agente, ma da due (e uno è umano). Più occhi ci sono su un codice, più bug si trovano.

Conosci il tuo codice

Ed ecco un punto dolente nell’uso degli LLM: se lo usate pervasivamente per scrivere il vostro codice, la conoscenza che avrete su quel codice calerà significativamente. Per il solo fatto che non spenderete ore a muovere il cursore avanti e indietro, a fare modifiche incrementali e fare debug, non sarete più intimamente connessi con quella codebase. Il vostro intervento sarà più simile a quello di un manager, che però non si sta interfacciando ad umani che conosce, ma con delle macchine che talvolta sono imprevedibili, lente, confusionarie. Fate quindi attenzione a questo aspetto, perché a seconda del vostro ruolo, del progetto che state sviluppando o delle persone con cui vi dovrete interfacciare, vorrete avere gradi diverso di controllo sul codice.

L’uso di LLM per la scrittura di codice è un continuum: esiste il “puro vibe coding”, in cui si chiede ad un agente quello che si vuole e ci si fida del risultato, ed esiste il “completamento intelligente”, che si affida agli LLM per avere suggerimenti sugli errori, sui nomi, su piccoli snippet di codice da completare. Io, attualmente, sto nel mezzo: se scrivo tutto il codice io, a volte mi annoio col boilerplate, introduco bachi triviali o faccio più passi prima di convergere ad una soluzione che apprezzo; se faccio scrivere tutto a lui, la probabilità che qualcosa vada male aumenta abbastanza velocemente e mi ritrovo a perdere tempo a spiegare come fare cose triviali; se invece supervisiono da vicino, mi sembra di avere il miglior trade off.

Generazione guidata dai test

Un’altra pratica che ho trovato funzionare piuttosto bene è l’uso di LLM per generare dei test e per fare TDD (Test-Driven Development): chiedo ad un LLM di scrivere un test, lo leggo, lo valido, decido se le API mi piacciono, e se va tutto bene gli chiedo di generare il codice. Insieme a questo, trovo che funziona un approccio del tipo “riempi gli spazi”: io scrivo codice con una certa struttura, degli esempi stabilisco pratiche e convenzioni, poi chiedo agli LLM di fare qualcosa di simile per altri casi nuovi. In questo modo non sono in balia dello strumento, ma lo guido per la strada che mi interessa percorrere.

I test sono una parte che spesso gli sviluppatori lasciano fuori, dimenticano o trascurano se non il team non adotta pratiche che li includono. Gli agenti possono aiutare anche in questo caso: se sviluppate applicazioni web, potete usare MCP (o tool come Google Antigravity) per permettere all’agente di controllare il browser e automatizzare qualche test. Non solo facendo usare l’applicativo all’agente, ma anche facendogli generare in modo più efficiente dei test end-to-end.

E non fermatevi ai test: visto che il codice è una responsabilità, allora pensate anche al debito tecnico. Non usate gli LLM per generare codice alla cieca, ma usateli per ridurre il debito tecnico che avete nella vostra code base. Fateglielo analizzare, producete dei report, capite dove si può migliorare e iterate più in fretta per ridurre il codice e renderlo migliore, anziché aumentarlo.

Una vista dall’alto

Anche il deploy, la sicurezza e le performance possono beneficiare molto dall’uso degli LLM. Questi strumenti sono pervasivi: “il limite è la vostra immaginazione”, direbbe qualcuno, ma questo non vuol dire che dobbiamo lasciarci abbandonare in un mondo di sogni. È importante non perdere contatto con la realtà.

Ad esempio, esplorare il mondo degli agenti è certamente affascinante e, come abbiamo visto, molti processi possono beneficiarne, ma siamo davvero sicuri che portino così tanti vantaggi? Articoli usciti di recente mettono in dubbio l’efficacia degli LLM e il loro impatto sulla qualità del lavoro e della vita: alcuni sviluppatori pensano di essere più produttivi perché la quantità di codice scritto è maggiore o perché sono più impegnati a fare cose, ma poi l’effettivo tempo impiegato per risolvere i problemi è maggiore; oppure la produttività non aumenta significativamente indipendentemente da quanto avanzati sono gli LLM che vengono usati. Gli agenti si sono diffusi molto velocemente, ci sono interessi diversi nel sostenere che essi siano più o meno d’aiuto allo sviluppo del software, ma i dati di qualità scarseggiano ancora.

E quindi, prima di concludere, vi invito a fare un meta-ragionamento: è sicuramente bello sperimentare con gli LLM. È utile e interessante provare modelli e strumenti diversi: funziona meglio Claude o ChatGPT? Codex o Gemini? Claude Code, OpenCode, Cursor o Antigravity? Tutto bello e interessante, ma il tempo investito a provare questi strumenti lo misurate? E, banalmente, il tempo per passare le informazioni in giro, quanto tempo impiega? Ve lo paga il cliente del progetto? È tempo di ricerca e sviluppo? O è il vostro tempo personale che impiegate sperando di diventare più efficaci sul lavoro (e quindi, magari, lavorare meno)?

Se un cliente mi dà delle specifiche di massima su un progetto, io devo metterci tempo e risorse per ragionarci, disambiguare, avere una visione d’insieme, dare elementi nuovi e innovativi che lo facciano felice, mettere insomma a frutto le conoscenze che mi rendono un esperto, e poi passare del tempo per fare in modo che gli LLM siano allineati con la mia visione. Quanto tempo ci metto rispetto al farlo io? Le risposte non sono definitive.

Sicuramente bisogna fare attenzione: gli LLM non sono strumenti semplici e ci sono implicazioni importanti nel loro uso. Anche se vi sembra di trarne vantaggio, vi consiglio di essere cauti e mantenere una prospettiva oggettiva perché, e questo lo sappiamo da tempo, nove donne non fanno un bambino in un mese.

Ultimi articoli

Deep machine learning
Deep machine learning: cos’è, differenze con il machine learning e applicazioni pratiche
iot cloud
Piattaforma IoT: guida completa alle soluzioni IoT Cloud e alle tecnologie connesse
Tecniche Avanzate di Visualizzazione Volumetrica nel Web

area contatti

Per informazioni, progetti, idee, scrivici