Hero background

AI o non AI: questo è il dilemma

DISCLAIMER: Le opinioni contenute in questo articolo sono interamente farina del mio sacco e derivano dalle mie conoscenze, studi ed esperienze vissute in prima persona.

Ai tempi dell'Università ho avuto più volte a che fare con lo strato teorico su cui poggia tutta la teoria delle reti neurali e, più in chiave moderna, degli LLM.

L'idea di mimare il comportamento delle reti neurali biologiche al fine di sviluppare un modello probabilistico che potesse affrontare alcuni problemi che gli algoritmi classici deterministici non potevano spingersi ad affrontare (non in maniera semplice, almeno) - bene questa idea non è certamente nuova e precede di gran lunga la diffusione dei cosiddetti Large Language Model. Le applicazioni classiche di questi modelli erano essenzialmente da ricercarsi in ambiti come riconoscimento vocale, immagini (per esempio testi scritti a mano), voice recognition, pattern recognition, ecc... Tutta questa roba la si usava già a livello consumer negli anni '90 o primi anni 2000 e personalmente ne ho memoria.

Reti neurali in a nutshell

L'idea di base di una rete neurale (informatica) non è così complessa da capire: nella sua forma più semplice, una rete è composta inizialmente da un blocco di "elementi computazionali" chiamati neuroni che ricevono l'input esterno e, attraverso una funzione di attivazione, producono un output. Questo segnale si propaga verso uno o più layer intermedi attraverso delle linee pesate in cui ciascun neurone di input è virtualmente connesso ai neuroni dello strato successivo (potenzialmente a tutti i neuroni, se parliamo di reti fully connected). Ciò che varia è il peso di queste linee e quindi l'influenza che il valore di ciascun neurone esercita sui neuroni dello strato successivo. Alla fine di questa sequenza di layer intermedi, vi è lo strato finale composto da un blocco di neuroni il cui valore calcolato non viene propagato ulteriormente ma rappresenta l'output finale fornito dalla rete.

schema rete neurale
schema rete neurale

Chiaramente il modello fin qui descritto non è sufficiente a spiegare tutto il funzionamento della rete: esistono infatti delle procedure per modificare i pesi di ciascuna linea in base al compito che la rete deve soddisfare o in base al tipo input che la rete deve gestire. Esistono inoltre altri parametri come i bias che consentono di shiftare in alto o in basso (come delle costanti) la soglia di attivazione di un determinato neurone. Generalmente le procedure atte a determinare i valori di questi parametri sono le procedure di training, cioè il procedimento per cui una rete viene addestrata a imparare la conoscenza necessaria per il settore in cui la si sta impiegando. In effetti tutta la conoscenza che viene fornita in fase di training viene immagazzinata sotto forma dei pesi e dei parametri di cui abbiamo parlato prima. Intuitivamente, maggiore è il numero di parametri, maggiore è la capacità della rete di immagazzinare informazione e, quindi, "riusarla" quando verranno presentati i veri input. Non si tratta di una relazione lineare e sicuramente dovremmo almeno menzionare i problemi di overfitting, che si verificano quando la rete impara "troppo bene" i dati di training e non è molto efficace con altri input, vanificando gli intenti predittivi per cui una rete neurale è generalmente progettata. Un possibile modo per aumentare il numero di parametri è aumentare la quantità di hidden layers, cioè il numero di strati di neuroni che l'input deve attraversare per formare l'output finale.

In questa mia breve sintesi ho saltato un mucchio di concetti... Ad esempio: qual è il meccanismo (o funzione) attraverso cui il neurone si attiva? Come vengono usati i dati di training per aggiustare i parametri della rete? Per approfondire questi e altri interessanti temi teorici vi consiglio una lettura free che abbina l'approccio matematico a qualche dritta più pratica per esercitarsi e implementare qualche rete neurale sulla propria macchina:

Preface — Dive into Deep Learning 1.0.3 documentation

Ce n'è per tutti i gusti: algebra lineare, elementi di analisi, matrici jacobiane e algoritmi di back-propagation per il tuning dei parametri.

Dalle reti neurali alle AI moderne

Tornando ai giorni nostri, quello che davvero ha cambiato le regole del gioco rispetto ai tempi in cui bazzicavo all'Università, è l'aumentata potenza di calcolo adesso a disposizione. Il fatto di poter contare su acceleratori grafici molto potenti (particolarmente adatti al calcolo parallelo) rende possibile l'impiego di reti con miliardi di parametri, capaci quindi di immagazzinare un quantitativo di informazione senza precedenti.

Da qui, con un salto quantico spaventoso, arriviamo ai ben noti: ChatGPT, Claude Sonnet, Grok, Deepseek, llama e chi più ne ha più ne metta - modelli capaci di sfornare risposte straordinariamente precise a domande complesse, dove la scelta della risposta (aka token) più probabile si mischia e si fonde con capacità di ragionamento che assomigliano quasi pericolosamente a quelle umane (sebbene sia chiaro a tutti che non sia una reale capacità intellettiva ma solo, appunto, un calcolo probabilistico basato principalmente sui dati di addestramento).

Uno degli ambiti che sta vivendo un momentum è proprio quello relativo al coding: infatti la capacità di questi modelli di tirare fuori soluzioni accurate e ingegnerizzate (a volte forse troppo...) ha impressionato colonie di sviluppatori.

Vibe che?

Approcci come il vibe coding si stanno facendo strada, specialmente tra coloro che approcciano l'AI per la prima volta. A questo proposito, esistono diverse definizioni per questa tecnica di uso dell'AI e non è questa la sede per esplorarle tutte. Sintetizzando, si tratta di creare dei prompt per un agente affinché questi li traduca in codice che implementa le specifiche, fornite in maniera informale, con linguaggio naturale. L'approccio è tipicamente conversazionale e può prevedere una serie di iterazioni attraverso cui l'utente umano rifinisce la soluzione prodotta guidando l'agente, aggiungendo specifiche, suggerendo soluzioni sempre più precise, ecc.

Il vibe coding si rivela uno strumento estremamente potente, specialmente nella produzione rapida di prototipi funzionanti. Potremmo quasi dire che rilascia delle scariche di adrenalina non irrilevanti in chi lo usa per l'immediatezza dei risultati che si riescono a ottenere e, spesso, anche per la buona precisione dell'output.

Vibe coding? No grazie!

Il vibe coding non è però l'unico approccio possibile all'uso dell'AI per task di coding. Anzi, in certi ambiti, come diremo a breve, non è nemmeno il più consigliato! Alcuni developer stanno infatti propendendo sempre di più per un approccio più strutturato, ovvero l'inserimento dell'AI in maniera più organica nel workflow di sviluppo. Secondo questo approccio, l'agente viene prima guidato attraverso delle regole generiche che vengono date a priori dove essenzialmente:

  • si descrive il progetto e le finalità che si prefigge di raggiungere;
  • si descrivono le code convention da adottare (magari il team ha già delle regole ben precise che adotta quotidianamente);
  • si descrivono i pattern e le best practise, oltre che le librerie da adottare e le modalità di sviluppo consentite;
  • si descrive le tipologie di task più comuni per il progetto e il modo corretto di affrontarle (di nuovo, il team potrebbe già avere dei pattern ricorrenti in pancia che usa in determinate situazioni);

A fronte di queste regole, vengono fornite delle specifiche di alto livello all'agente con la richiesta di generare le specifiche tecniche e un piano operativo per l'implementazione. L'output di questa fase non è quindi più codice ma un piano/documentazione tecnica per un successivo step.

La review umana si concentra quindi sulle specifiche prodotte. Al termine di questa fase di controllo viene nuovamente triggerato un agente con lo scopo di tradurre le specifiche in codice, sempre tenendo presenti le regole generali summenzionate. Semplificando, facciamo assumere all'agente prima il ruolo di Senior Analyst/Solution Architect e poi quello di Senior developer.

Il maggiore contesto fornito all'AI in tutte le fasi e il concentrarsi su un task alla volta - prima progettazione e, dopo, coding vero e proprio - fornisce dei risultati molto più precisi e di qualità, paragonabili secondo alcuni all'operato di un analista senior e di un senior developer combinati insieme.

Vibe vs Structured

Si delineano quindi gli scenari in cui le due tecniche possono teoricamente dare i risultati migliori:

VIBE CODING
Creazione rapida di prototipi, validazione di idee, esplorazione di librerie e tecnologie, implementazione di algoritmi ben codificati e che hanno ampia letteratura, implementazione di task ripetitivi.

APPROCCIO STRUTTURATO
Integrazione in flussi di lavoro più articolati, implementazione di pezzi di codice production-ready, rispetto di regole ben precise per integrazione con progetti pre-esistenti, applicazione di pattern non standard o non ampiamente documentati in letteratura, soluzioni custom team-based.

Favorisca l'IDE!

Esistono sul mercato svariati tool (tendenzialmente a pagamento) che integrano un IDE a tutto tondo ad una serie di funzionalità votate all'AI. E possono lavorare sia in modalità vibe coding che approccio strutturato:

  • Cursor è sicuramente uno dei più famosi. Si basa su vscode e aggiunge potenti funzionalità per fornire contesto al prompt in maniera precisa, possibilità di aggiungere regole generali che l'AI dovrà rispettare nel fornire le risposte e anche delle chat mode specifiche per task ricorrenti (bugfix, enhancement, ecc...). Il costo è relativamente basso ed è ad oggi uno dei player da considerare;
    https://cursor.com/pricing
  • MS Copilot, è più un'estensione per vscode piuttosto che un brand new editor e fornisce anche lui funzionalità molto più avanzate della singola "ennesima" chat con l'n-esimo agente AI;
    https://code.visualstudio.com/docs/copilot/overview
  • Kiro, l'IDE di Amazon dedicato all'AI, era in beta fino a poco tempo fa ma già promette funzionalità cutting-edge per chi è interessato a vibe coding e dintorni.
    https://kiro.dev/

Sicuramente ce ne sono altri rilevanti in questo ambito oppure ne verranno fuori in futuro. Aggiungeteli nei commenti con le vostre considerazioni, se vi va, indicando i punti eventuali punti di forza/debolezza se li avete già provati in un vostro progetto.

Personalmente sto testando a fondo le capacità di Cursor e confermo che se la cava bene sia con vibe coding puro, sia utilizzando delle regole più rigide (vedi cursorrules + chat modes per ulteriori approfondimenti).

Non è tutto code quello che compila

Tra i rischi concreti per team di tutte le dimensioni è, a mio parere, impossibile non citare quello di accumulare un forte debito tecnico applicando la tecnica sbagliata in base al tipo di progetto, ad esempio vibe coding a progetti complessi che devono essere production ready e bullet proof. Oppure approcci troppo strutturati a progetti semplici che tendono a over-ingegnerizzare il codice e, quindi, complicandolo inutilmente.

Sempre sul vibe coding, proprio perchè viene dato molto meno contesto all'AI, è più aleatorio il livello di qualità dell'output. Può andare molto bene, può andare molto male (e quindi l'output dovrà essere cestinato). Non si sa. Tutto è possibile.

In generale per evitare questi rischi è necessaria una buona seniority dell'utente umano o del cosiddetto prompt engineer (se qualcuno ha capito esattamente cosa sia...), utile per:

  • individuare la tecnica giusta da applicare;
  • redigere le regole opportune con gli hints corretti per l'AI;
  • revisionare l'output dell'AI (specifiche o codice);
  • valutare se la qualità prodotta è in linea con ciò che il team/progetto/cliente si aspettano;
  • valutare potenziali falle di sicurezza non correttamente gestite dall'AI.

Tutte queste attività non sono banali e non sempre possono essere demandate esclusivamente a dei junior developers. Per esempio è difficile valutare la qualità di una soluzione che non si sarebbe stati in grado di produrre autonomamente o se non se ne conoscono i pattern applicati, i limiti tecnici o le condizioni in cui questa performa al meglio.

Per non parlare dei tanti altri rischi connessi all'adozione incontrollata di strumenti AI: scarso controllo dei costi che possono crescere in maniera significativa man mano che si adottano sempre più tool, potenziale lock-in su determinate aree specifiche come code review, design to code e altre aree affini, sicurezza dei dati, manutenzione dei modelli, ecc ecc. E questi sono solo alcuni dei temi che le organizzazioni stanno affrontando.

Wrap-up

Per come la vedo io, l'AI usata in ambiti come il coding o la produzione di documentazione, è come un amplificatore applicato alle nostre mani, alle nostre menti. Se la mente contiene confusione, l'AI molto probabilmente amplificherà questa confusione. Se siamo invece in grado di guidare con precisione la soluzione avendo già in mente dove andare a parare (e quindi usando l'AI solo per arrivarci prima) allora può davvero rappresentare una straordinaria opportunità di amplificare le nostre capacità e, quindi, produrre valore in ambiti sconfinati, non solo nella produzione di software.