Context7 e la fine delle allucinazioni di versione: docs in-context per Laravel 13 e Symfony 7.4

Context7 e la fine delle allucinazioni di versione: docs in-context per Laravel 13 e Symfony 7.4

Chiedi a un modello di portare avanti l'upgrade di un'applicazione Laravel e, con tutta la sicurezza del mondo, ti dice di aprire app/Http/Kernel.php e aggiungere il tuo middleware all'array $middleware. Il problema è che in Laravel 11, 12 e 13 quel file non esiste più: la registrazione dei middleware è stata spostata in bootstrap/app.php da Laravel 11, uscito a marzo 2024. Il modello non sta mentendo e non è "stupido": sta ricordando con precisione un mondo congelato alla sua data di addestramento, un mondo in cui quel file c'era ancora. È la classica allucinazione di versione, e non è un caso limite: è il modo strutturale in cui un LLM sbaglia su qualunque libreria che si muova più in fretta del suo training cutoff. Con Laravel 13 uscito il 17 marzo 2026 e Symfony 7.4 LTS dal novembre 2025, lo scarto tra la versione che il modello "ricorda" e quella che hai davvero in composer.json è spesso di una o due major. Nel mio lavoro su codebase Laravel e Symfony questo è il punto dove l'AI fa perdere più tempo di quanto ne faccia guadagnare, a meno di chiudere il buco. Lo strumento con cui lo chiudo si chiama Context7, e vale la pena capire cosa fa davvero, e cosa no.

Cos'è davvero un'allucinazione di versione

Un'allucinazione di versione non è un errore casuale del modello: è la conseguenza diretta di come un LLM è costruito. Il modello viene addestrato su uno snapshot statico del web e della documentazione, con una data di taglio oltre la quale non sa nulla. Tutto ciò che è cambiato dopo (una API rimossa, un metodo rinominato, una struttura di file riorganizzata) per il modello semplicemente non è accaduto. Quando gli chiedi codice per una libreria, lui ti restituisce il pattern più probabile secondo quello snapshot, e se la libreria nel frattempo è andata avanti, quel pattern è obsoleto. La parte insidiosa è il tono: il modello propone l'API rimossa con la stessa sicurezza con cui propone quella corretta, perché internamente non ha modo di sapere quale delle due appartiene al passato.

Un LLM non distingue tra "questo metodo esiste" e "questo metodo esisteva quando sono stato addestrato". Per lui sono la stessa frase. È questa indistinguibilità, non la mancanza di intelligenza, a generare il codice per la versione sbagliata.

Perché il problema esplode proprio sui framework che si muovono in fretta

Lo scarto pesa in proporzione alla velocità con cui la libreria cambia. Su un linguaggio stabile l'allucinazione di versione è rara; su un framework con una cadenza di release annuale e refactoring strutturali diventa la norma. Laravel è un caso da manuale: tra la 10 e la 11 è cambiata l'intera procedura di bootstrap dell'applicazione, con la rimozione delle classi Kernel e lo spostamento di middleware, routing e scheduling. Un modello addestrato sui documenti della 10 non può che sbagliare, perché il mondo a cui attinge non contiene quella riorganizzazione.

C'è anche un effetto economico che si tende a sottovalutare. Quando il modello genera codice per la versione sbagliata, il costo nascosto non è il momento in cui scrive la riga: è il tempo che spendi tu a capire perché quella riga non funziona, a cercare nella documentazione cosa è cambiato e a correggere. Su un upgrade reale, dove le API toccate sono molte, questo costo nascosto erode tutto il vantaggio dell'automazione. Per chi vuole davvero usare l'AI nel ciclo di sviluppo di un team, chiudere il buco della versione non è un dettaglio, è la differenza tra un acceleratore e un generatore di bug plausibili, un tema che ho già affrontato parlando di agenti che analizzano una codebase PHP legacy.

Se stai integrando strumenti AI nel ciclo di sviluppo del tuo team e vuoi capire come imposto un ambiente che non genera questo tipo di debito tecnico nascosto, nel mio hub dedicato all'AI per lo sviluppo raccolgo gli articoli con la metodologia che applico sul campo.

Come Context7 inietta la documentazione della versione giusta

Context7, sviluppato da Upstash, è un MCP server che attacca il problema alla radice: invece di sperare che il modello ricordi la versione giusta, gli mette davanti la documentazione corrente, recuperata dalla fonte e iniettata nel contesto al momento della richiesta. Il principio è semplice e per questo solido: se la conoscenza affidabile del modello è ferma al passato, gliela si aggiorna a runtime con la versione presente.

Il server espone due strumenti, coerenti con il Model Context Protocol. Il primo, resolve-library-id, traduce un nome generico di libreria (per esempio "laravel") in un identificativo interno con la sintassi a slash, come /laravel/docs. Il secondo, get-library-docs, recupera la documentazione versione-specifica per quell'identificativo, con un parametro opzionale di topic per restringere il campo (per esempio "middleware" o "routing"). Dietro le quinte gira una pipeline documentata che estrae gli snippet di codice dalle fonti ufficiali, li arricchisce, li vettorizza per la ricerca semantica e li riordina per rilevanza, servendoli da cache. Nell'uso quotidiano non si tocca niente di tutto questo: si aggiunge la frase "use context7" alla richiesta, o si indica direttamente la libreria con la sintassi a slash, e il targeting della versione avviene citando la versione nel prompt. Su Claude Code l'integrazione è una riga di terminale, claude mcp add, e il progetto è open source con licenza MIT per la parte server. La copertura dichiarata è di oltre novemila librerie. I riferimenti ufficiali sono il repository di Context7 e il post di lancio di Upstash, da cui questi dettagli sono verificati.

Esempio concreto: l'upgrade dove il modello avrebbe proposto API rimosse

Torniamo all'upgrade Laravel da cui siamo partiti. Senza la documentazione corretta in contesto, alla richiesta di registrare un middleware globale il modello, ancorato alla 10, propone qualcosa di simile a questo:

// Suggerimento del modello "fermo" a Laravel 10: in Laravel 11+ è codice morto,
// perché app/Http/Kernel.php non esiste più
namespace App\Http;

class Kernel extends HttpKernel
{
    protected $middleware = [
        \App\Http\Middleware\EnsureTokenIsValid::class,
    ];
}

Quel file, in Laravel 11 e successivi, semplicemente non c'è. La registrazione corretta vive in bootstrap/app.php, dentro la closure di withMiddleware(), ed è quella che il modello propone quando ha in contesto la documentazione giusta:

// bootstrap/app.php - la forma corretta da Laravel 11 in poi
return Application::configure(basePath: dirname(__DIR__))
    ->withRouting(
        web: __DIR__.'/../routes/web.php',
        commands: __DIR__.'/../routes/console.php',
        health: '/up',
    )
    ->withMiddleware(function (Middleware $middleware) {
        $middleware->append(\App\Http\Middleware\EnsureTokenIsValid::class);
        $middleware->alias([
            'subscribed' => \App\Http\Middleware\RedirectIfNotSubscribed::class,
        ]);
    })
    ->create();

La differenza non è cosmetica. Il primo blocco fa perdere mezz'ora a chi non conosce il cambiamento, perché è codice sintatticamente valido che non viene mai eseguito; lo scheduling e i comandi, allo stesso modo, sono migrati in routes/console.php. Un segnale tipico di questo disallineamento è l'errore Call to undefined method ...Middleware::configure(), che spunta quando il modello inventa un metodo plausibile su una API che non conosce più. Con Context7 che inietta la doc della versione reale, il modello salta direttamente alla forma corretta, e l'upgrade procede senza il giro di correzioni manuali.

E per Symfony 7.4? Lo stesso principio, una cadenza diversa

Su Symfony il meccanismo dell'allucinazione di versione è identico, ma la forma cambia, perché cambia il modello di rilascio. Symfony non riorganizza i file come Laravel: governa l'evoluzione con le deprecation. Una minor introduce un avviso di deprecazione, la major successiva rimuove l'API deprecata. Il risultato, per un LLM, è insidioso quanto la rimozione di un file: il modello fermo a una minor vecchia propone un metodo che nella tua versione è già deprecato o sparito, e lo fa senza l'avviso che invece vedresti a runtime. Con Symfony 7.4 LTS (la versione da raccomandare oggi, uscita a novembre 2025) accanto a una 8.1 già current stable, lo scarto tra ciò che il modello ricorda e ciò che gira nel tuo progetto è facilmente di una major intera, con in mezzo un giro completo di deprecazioni.

Qui Context7 lavora allo stesso modo: si risolve l'identificativo /symfony/symfony, si indica la versione nel prompt, e la documentazione iniettata è quella della 7.4, non quella di una 6.x che il modello potrebbe avere in memoria. Il valore non è solo evitare il metodo rimosso: è ricevere il pattern idiomatico della versione corrente, perché su Symfony la differenza tra due major non è solo cosa è scomparso, ma come si scrive oggi la stessa cosa. Per chi mantiene piattaforme Symfony di lunga vita, dove l'upgrade è un processo continuo guidato proprio dalle deprecazioni, avere in contesto la doc della versione giusta è la differenza tra un assistente che accelera la migrazione e uno che la sporca di chiamate morte.

Context7 elimina del tutto le allucinazioni di versione?

No, e venderlo come una garanzia sarebbe disonesto. Context7 riduce drasticamente le allucinazioni di versione, ma resta soggetto a due limiti che vanno dichiarati. Il primo è la qualità della documentazione indicizzata: i progetti su Context7 sono spesso mantenuti dalla community e dai rispettivi proprietari, non dal team di Context7, che non garantisce accuratezza o completezza di ogni libreria. Il secondo è il retrieval: se la ricerca recupera la sezione sbagliata, o una versione diversa da quella in uso, il modello riceve un contesto fuori bersaglio. Per questo continuo a indicare esplicitamente la versione nel prompt e a verificare l'identificativo della libreria, invece di affidarmi al match automatico al buio. Vale anche la regola opposta a quella dei tutorial entusiasti: se la libreria che stai usando è di nicchia o appena uscita, la sua documentazione su Context7 potrebbe essere incompleta o assente, e in quel caso il recupero a vuoto dà al modello una falsa sicurezza invece di chiudere il buco. La fiducia nello strumento va calibrata sulla maturità della libreria, non data per scontata.

La conseguenza pratica è che Context7 sposta il lavoro, non lo elimina. Toglie la classe di errori più frequente e più stupida (l'API che non esiste più) e libera l'attenzione del senior per gli errori che contano davvero: la logica, le scelte di design, gli effetti collaterali di una migrazione. Non sostituisce la lettura della guida di upgrade ufficiale su una major delicata, e non sostituisce il giudizio di chi rivede il codice. È un correttore di realtà, non un pilota automatico.

Dove lo tengo acceso e dove no

Nel mio workflow Context7 è uno standard quando lavoro su librerie a cadenza rapida e su upgrade: Laravel, Symfony, l'ecosistema JavaScript. Lì il guadagno è netto, perché è esattamente il terreno dove la memoria del modello invecchia più in fretta. Lo abbino sempre al vincolo di versione che ho già in composer.json: la doc che voglio in contesto è quella della versione che gira davvero nel progetto, non l'ultima in assoluto. Su una libreria stabile, che non cambia API da anni, lo lascio spento: aggiungere un recupero di documentazione che non serve è solo context speso a vuoto, la stessa disciplina di parsimonia che applico alla scelta degli MCP server personalizzati per il workflow aziendale.

C'è infine un punto che un consulente serio deve sollevare con il cliente: il backend di Context7 (parsing, crawling, ranking) è proprietario e il contenuto del prompt passa per un servizio esterno. Per la maggior parte del lavoro su documentazione pubblica è un non-problema, ma su contesti con codice o dati sensibili va valutato come qualunque altra dipendenza esterna, con la stessa attenzione che dedico al setup di Claude Code in produzione per uno sviluppatore PHP senior.

Messo insieme, il quadro è meno magico e più utile di come lo si racconta di solito. Le allucinazioni di versione non sono un difetto che sparirà con il prossimo modello più grande: sono una proprietà strutturale di sistemi addestrati su uno snapshot del passato, e il modo per neutralizzarle non è sperare in una memoria migliore, è dare al modello la documentazione presente nel momento in cui gli serve. Context7 fa esattamente questo, bene, entro i limiti onesti di un sistema che dipende dalla qualità di ciò che indicizza. Per un team che usa l'AI sul codice di tutti i giorni, adottarlo significa togliere di mezzo la categoria di errore più frequente e meno interessante, e tenere le persone concentrate sulle decisioni che la macchina non può prendere. Se stai introducendo strumenti AI nel ciclo di sviluppo e vuoi capire dove ti fanno guadagnare tempo e dove invece ti stanno generando bug plausibili che pagherai dopo, puoi usare il modulo di preventivo gratuito: sette domande, due minuti, e ti dico se il tuo caso rientra nel mio perimetro o se ti conviene un'altra figura.

Ultima modifica: