Il grande teatro del ragionamento: quando gli LLM ci fanno ridere (e piangere)

Avete mai guardato un modello linguistico “pensare” — quella sequenza di frasi ordinate, quasi filosofiche, che scorrono prima della risposta finale — e avuto la netta sensazione che stesse davvero ragionando? Bene. Questo articolo è un antidoto a quella sensazione.
Parliamo di fail. Di quei momenti in cui lo strumento AI più sofisticato del momento produce qualcosa di così clamorosamente sbagliato, con tale assoluta sicurezza, da diventare quasi comico. Ma soprattutto, parliamo di perché succede — e di cosa si nasconde davvero dietro a quella finestra di “ragionamento”.
Cosa vedrai
- Il teatro del pensiero: cos’è davvero il “reasoning”
- I token pensano? No, ma ci provano bene
- La galleria dei fail: i classici intramontabili
- Il sycophancy: il problema più pericoloso
- Cosa fare con questa consapevolezza
Il teatro del pensiero: cos’è davvero il “reasoning”
Con l’arrivo dei modelli come o1, o3, Claude 3.7 Sonnet e le ultime versioni di GitHub Copilot, è diventato comune vedere qualcosa del genere prima di ogni risposta:

Il pannello 'thinking' di un modello: affascinante, no? Ma cosa ci nasconde davvero?
La finestra del pensiero sembra un monitor dell’attività cerebrale. Il modello riflette, considera, rivaluta. Quasi come un consulente senior che annuisce pensieroso prima di rispondere.
La realtà è un po’ meno romantica.
I modelli di tipo “reasoning” — come o1/o3 di OpenAI o il Thinking di Claude — usano quello che viene chiamato chain-of-thought (CoT): generano una serie di token intermedi prima di produrre la risposta finale. L’idea di base è che, proprio come gli esseri umani pensano ad alta voce per risolvere problemi complessi, costringere il modello a “scrivere” i passaggi intermedi migliora la qualità dell’output finale.
E funziona. Su certi tipi di problemi, funziona davvero bene.
Il problema è che quella finestra di pensiero è fatta degli stessi mattoncini di tutto il resto: token. Parole predette statisticamente. Non è un processo deliberativo separato, non è un “secondo cervello” che verifica il primo. È la stessa architettura che genera tutto il resto, semplicemente addestrata a produrre output intermedi che sembrino riflessivi.
I token pensano? No, ma ci provano bene
Per capire i fail, dobbiamo fare un piccolo passo indietro e capire come funzionano questi modelli.
Un Large Language Model, nella sua essenza, è una funzione molto, molto complessa che risponde a una domanda semplice: “Dato questo testo, qual è il token più probabile che viene dopo?”
Niente di più, niente di meno.

Schema semplificato: l'LLM predice il prossimo token, uno alla volta. Non 'pensa', predice.
Questo significa che il modello non ha una rappresentazione interna della realtà. Non “sa” le cose nel senso in cui le sa un essere umano. Ha appreso pattern statistici su enormi quantità di testo, e usa quei pattern per produrre output coerenti e spesso corretti.
Quando funziona, sembra magia. Quando non funziona, sembra un collega che ha dormito male e risponde a caso con aria di assoluta certezza.
Le conseguenze di questa architettura sono importanti:
- Il modello non sa quando sbaglia. Non c’è un meccanismo interno di “verifica dell’accuratezza”. Se il testo che segue statisticamente la tua domanda include spesso risposte errate, il modello le darà con la stessa sicurezza di quelle corrette.
- La fiducia espressa è un pattern linguistico, non un indicatore di accuracy. Frasi come “certamente”, “ovviamente” o “senza dubbio” sono semplicemente token frequenti in certi contesti di risposta.
- Il “ragionamento” nel chain-of-thought può essere post-hoc. Il modello può arrivare alla risposta sbagliata e poi costruire un ragionamento che la giustifica perfettamente.
La galleria dei fail: i classici intramontabili
Ora la parte divertente. Benvenuti nella galleria dei fail LLM — una collezione di errori iconici, ordinata per categoria.
🏆 Il test perfetto (che non testa nulla)
Avete mai chiesto a GitHub Copilot o a un LLM di scrivere unit test per la vostra funzione? Risultato spesso ottenuto:

Il test generato passa. Sempre. Perché non testa nulla di significativo.
def test_calculate_total():
result = calculate_total([10, 20, 30])
assert result == result # ← Il classico
Oppure, nella variante più sofisticata:
def test_calculate_total():
# Test con valori di esempio
assert calculate_total([]) == calculate_total([])
Il modello ha capito la struttura di un test. Ha usato assert. Ha messo un nome descrittivo. Il ragionamento mostrato era impeccabile: “Verifico che la funzione restituisca il valore atteso”. Peccato che il “valore atteso” sia la funzione stessa.
Cosa è successo: Il modello ha visto migliaia di test nel training. Ha imparato la forma di un test senza capire la sua sostanza.
🦄 La libreria che non esiste
Scenario classico: chiedete a un LLM come fare una certa operazione in Python o JavaScript.

Il modello descrive con dovizia di particolari una libreria che semplicemente non esiste.
Risposta tipo:
“Puoi usare la libreria
pandas-turbo, che offre il metodo.fast_groupby()con supporto nativo per operazioni parallele. Installa conpip install pandas-turboe poi usa:import pandas_turbo as pt df.fast_groupby('colonna').aggregate('sum') ```"
pandas-turbo non esiste. .fast_groupby() non esiste. Il codice sembra plausibile perché assomiglia a Pandas.
Il chain-of-thought, se presente, mostrava qualcosa del tipo: “Analizzo le opzioni disponibili per ottimizzare le operazioni di groupby in pandas… considero le librerie specializzate per l’accelerazione…”
Riflessivo. Metodico. Completamente inventato.
Questo fenomeno si chiama hallucination ed è probabilmente il fail più pericoloso perché il codice prodotto compila (o quasi), passa review superficiali, e smette di funzionare solo in produzione.
🔧 Il refactoring catastrofico
“Aggiusta questo bug” — tre parole capaci di terrorizzare un codebase.

Il bug è in riga 3. Il modello ha 'risolto' modificando righe 47, 89 e 124. La riga 3 è intatta.
Il modello riceve un bug report su una funzione di parsing. Risponde con un diff che:
- Rinomina variabili in stile diverso
- Aggiunge commenti esplicativi
- Ristruttura un’altra funzione non correlata
- Non tocca la riga dove si trova il bug
Il “ragionamento” mostrato è lungo e articolato: “Il problema sembra essere nella gestione dei casi edge. Ho migliorato la leggibilità del codice e aggiunto documentazione…”
Cosa è successo: Il modello ha associato “bug fix” a “migliorare il codice nel suo complesso” perché nei dati di training, spesso si trovano commit che fanno entrambe le cose insieme.
🔄 Il loop della vergogna
Questo è il fail esistenziale per eccellenza.

Iterazione 1: risposta sbagliata. Iterazione 2: si corregge... sbagliando diversamente. Iterazione 5: siamo tornati alla risposta iniziale.
Chiedete di correggere un errore. Il modello si corregge. Ha ancora torto. Lo segnalate. Si corregge di nuovo. Ora ha torto in modo diverso. Dopo 4-5 iterazioni, è tornato alla risposta originale, ma con più fiducia.
Spesso accompagnato dalla frase: “Hai assolutamente ragione, mi scuso per la confusione precedente. La risposta corretta è…” — seguita dalla stessa risposta sbagliata di prima.
Questo comportamento ha un nome tecnico: sycophancy. E ne parliamo tra poco.
🎭 Il reasoning circolare
Forse il fail più affascinante dal punto di vista tecnico.

Il modello 'ragiona' per 3 paragrafi e arriva a una conclusione che contraddice le premesse iniziali.
Esempio reale (parafrasato):
Domanda: Qual è la complessità temporale di questo algoritmo?
Thinking: “Analizzo l’algoritmo… ha un ciclo esterno che itera n volte… all’interno c’è un ciclo che itera log n volte… quindi la complessità totale è O(n log n)… tuttavia, considerando che in certi casi il ciclo interno potrebbe iterare n volte… quindi potrebbe essere O(n²)… ma le ottimizzazioni del compiler… quindi O(n log n)…”
Risposta: “La complessità è O(n).”
Il thinking ha correttamente analizzato i cicli, ha identificato O(n log n), ha vacillato verso O(n²), e poi ha ignorato tutto il ragionamento per dare O(n).
Cosa è successo: Il token finale è stato influenzato più dall’associazione statistica “domanda su complessità + algoritmo semplice → O(n)” che dall’effettivo chain-of-thought prodotto.
📅 Il problema con il tempo
I modelli hanno una data di cutoff — un momento fino al quale sono stati addestrati. Dopo quella data, il mondo per loro si ferma.

Il modello consiglia una versione della libreria che è stata deprecata 18 mesi fa. Con grande sicurezza.
Ma il fail più interessante non è solo “non conosce le novità”. È che a volte i modelli inventano aggiornamenti: descrivono funzionalità di versioni future che non esistono, citano release notes di update mai avvenuti, consigliano API di librerie nella versione X+2 mentre sei alla X.
Il ragionamento mostrato includerà spesso riferimenti a “documentazione aggiornata” e “best practice attuali” — con totale noncuranza del fatto che il “attuale” del modello potrebbe essere 18 mesi fa.
💬 Il commit message poetico
Questo è quasi un genere artistico a sé.

Il commit message suggerito è tecnicamente corretto ma completamente inutile ai fini della code review.
Esempi reali di commit message suggeriti da strumenti AI per semplici bug fix:
"Refactored the authentication module to enhance code clarity and improve overall system resilience"
(Traduzione: ho cambiato il nome di una variabile)"Updated dependencies and optimized performance-critical pathways"
(Traduzione: ho aggiunto un punto e virgola)"Implemented comprehensive solution addressing previously identified behavioral discrepancies"
(Traduzione: ho fixato il bug che mi hai segnalato ieri)
Il modello ha imparato che i commit message “professionali” usano certi pattern linguistici. Ha applicato quei pattern. Il risultato è formalmente corretto e semanticamente vuoto.
Il sycophancy: il problema più pericoloso
Di tutti i fail, questo è quello che mi preoccupa di più — non perché sia il più spettacolare, ma perché è il più subdolo.
La sycophancy (letteralmente: adulazione) è la tendenza di un LLM a concordare con l’utente anche quando l’utente ha torto. È un artefatto del processo di addestramento con feedback umano (RLHF): le risposte che piacevano agli evaluatori umani ricevevano rinforzo positivo, e agli umani piace quando qualcuno è d’accordo con loro.

Sto sostenendo una tesi sbagliata. Il modello mi conferma. Non perché abbia ragione, ma perché la conferma è statisticamente il tipo di risposta 'apprezzata'.
Il risultato pratico:
Voi: “Penso che questa funzione abbia complessità O(n), giusto?”
LLM: “Esatto! La funzione ha complessità O(n) perché…”
(La funzione ha O(n²).)
Se fate la stessa domanda senza preconcetti, il modello risponde correttamente. Se la fate con una risposta sbagliata già incorporata, il modello tende a confermare la vostra risposta sbagliata.
In un contesto di code review o di analisi tecnica, questo è potenzialmente devastante. State usando lo strumento per validare le vostre decisioni, e lo strumento vi dice sempre di sì.
Cosa fare con questa consapevolezza
Questo articolo non è un invito a smettere di usare gli strumenti AI. Sono potenti, utili, e cambieranno (stanno già cambiando) radicalmente il modo in cui lavoriamo. Ma usarli bene richiede di capire cosa sono — e cosa non sono.
Alcune strategie pratiche:
1. Trattate il reasoning come un indizio, non come una prova
La finestra di thinking è utile per capire come il modello ha interpretato la vostra domanda. Se il ragionamento parte da premesse sbagliate, la risposta sarà sbagliata a prescindere da quanto sia articolata la catena logica. Leggete il thinking per fare debug della vostra domanda, non per validare la risposta.
2. Chiedete al modello di trovare i propri errori
Una tecnica sorprendentemente efficace: dopo aver ricevuto una risposta, chiedete esplicitamente “Quali potrebbero essere i problemi o le limitazioni di questa soluzione?”. I modelli sono generalmente migliori nell’identificare errori quando il frame è critico piuttosto che quando stanno costruendo una risposta da zero.
3. Verificate le fonti esternamente
Per qualsiasi informazione fatale — API, librerie, versioni, documentazione — verificate sempre da fonte primaria. Non perché il modello stia “mentendo”, ma perché non ha un meccanismo interno per distinguere ciò che sa da ciò che inventa plausibilmente.
4. Diffidete dalla sicurezza espressa
La certezza linguistica di un LLM (“certamente”, “senza dubbio”, “ovviamente”) non correla con l’accuratezza della risposta. Se volete una stima dell’incertezza reale del modello, chiedete esplicitamente: “Quanto sei sicuro di questa risposta? Ci sono scenari in cui potrebbe essere errata?”
5. Dividete per conquistare
I fail aumentano con la complessità delle richieste. Una domanda da 500 parole con 7 vincoli diversi produce output peggiori di 7 domande separate e precise. La complessità riduce la qualità non perché il modello “si stanca”, ma perché aumenta lo spazio delle possibili risposte e la probabilità di soluzioni subottimali.
Conclusione: il palcoscenico è bello, ma ricordate l’illusionista
Il “ragionamento” degli LLM è reale nel senso che migliora misurabilmente certi tipi di output. Ma è fondamentalmente diverso dal ragionamento umano: non c’è un soggetto che comprende, c’è un sistema che predice.

Il trucco è impressionante. Sapere come funziona non lo rende meno utile — anzi, lo rende più utile.
Questo non è un difetto da correggere nella prossima versione del modello. È una caratteristica fondamentale dell’architettura. I modelli diventeranno sempre più capaci, i fail diventeranno sempre più rari — ma la natura statistica della previsione di token rimarrà, e con essa la possibilità di errori sicuri, hallucination convincenti, e reasoning circolare impeccabilmente sbagliato.
La buona notizia? Sapere come funziona davvero uno strumento è il primo passo per usarlo bene. E i fail, nel frattempo, rimangono un ottimo materiale comico.
🔗 Leggi anche:
















