modulo 07 / lezione 44
Leggere e verificare codice generato
Dipendenze inutili, librerie inventate, API che non esistono
Verificare che il codice generato si basi su strumenti reali, installati e necessari.
Dipendenze inutili, librerie inventate, API che non esistono
Tre errori distinti del codice generato dall’AI: aggiunge dipendenze non necessarie, inventa librerie/funzioni/opzioni che non esistono, mescola API di versioni diverse. Tutti tre producono codice plausibile a vista e non funzionante (o pericoloso) in esecuzione. Verificare è obbligatorio, non opzionale.
Perché questa lezione conta
Modelli AI sono ottimi pattern matcher. Hanno visto migliaia di esempi di “regex per email”, “fetch con axios”, “validazione con joi”. Quando devono produrre codice nuovo, riempiono con pattern simili. Spesso il pattern è giusto. Spesso usa una versione obsoleta, una libreria che hai sostituito, un metodo che il modello pensa esista perché era logico aspettarselo. Verifica = filtro.
Obiettivo operativo
Alla fine devi saper:
- controllare se import e funzioni esistono davvero in versione installata;
- distinguere dipendenza necessaria da decorativa;
- costruire una checklist di verifica prima del merge.
Nucleo della lezione
1. Cosa controllare
Quattro check sistematici per ogni codice generato:
Import esistente: ogni import X from 'pkg' → pkg è in package.json? Versione installata supporta l’import? Verifica:
- aprire
package.json, cercare il package; - aprire
node_modules/pkg/package.jsonper leggere “main”/“exports”; - documentazione ufficiale del pkg per quella versione.
Modelli capita inventino package plausibili (@vercel/auth, @stripe/react-native-stripe-sdk) che non esistono o sono diversi.
Funzione esistente: pkg.someMethod() esiste in versione installata? Le firme corrispondono? Documentazione ufficiale, non blog post (che possono essere outdated).
Opzione esistente: someMethod({ foo: true, bar: ... }) — foo è un’opzione valida? Documentazione.
API obsoleta: il modello a volte usa API di anni fa. React class components, Express middleware vecchio, Webpack 4 config. Verifica versione del framework + che API usata sia per quella versione.
2. Riconoscere allucinazioni
Sintomi tipici di codice “inventato”:
- Nome plausibile ma mai sentito:
useDebounceCallback,formatDateLocale,validateBusinessHours. Non esistono? Verifica. - Opzione che “ha senso”:
axios.post(url, data, { timeout: 5000, retry: 3 }).retrynon è opzione standard di axios. Verifica. - Mix di versioni:
import { Redirect } from 'react-router-dom'(v5) accanto auseNavigate(v6). Incompatibili. Verifica versione installata. - Esempio “perfetto” su libreria di nicchia: se la libreria ha 100 stelle GitHub, modello probabilmente non l’ha vista; output è interpolazione. Sospetto alto.
- Codice che gira solo se aggiungi dipendenza X: il modello introduce X “perché aiuta” ma non era richiesta.
Pattern: più un metodo “sembra che dovrebbe esserci”, più rischio di allucinazione.
3. Quando aggiungere una dipendenza
Domande prima di accettare nuova lib:
- Risolve un problema reale? Il task richiede capacità non banali (parsing complesso, crittografia, framework UI)? Se sì, lib può essere giustificata.
- Sostituisce poche righe comprensibili? Se la libreria fa 5 righe di codice che potresti scrivere a mano, valuta: scriverlo evita debito di dipendenza. Esempi: clipper di stringa, generazione UUID semplice, debounce.
- Manutenuta? Ultima release < 1 anno? Issue chiuse? Stelle non sono garanzia, ma trend di abbandono è warning.
- Dimensione bundle? Per progetti web client, verifica con bundlephobia o pacchetto. Una lib da 200KB per usare 1 funzione = NO.
- Trasitive insane?
npm lsper vedere quante dipendenze tira. Centinaia per una libreria piccola = bandiera. - Compatibilità licenza? GPL, AGPL possono essere problematici per progetti commerciali. MIT/Apache/ISC sono ok per la maggior parte dei casi.
- Sicurezza?
npm auditnon è infallibile ma offre un primo segnale.
Default: NO nuove dipendenze. Sì solo se le domande sopra hanno risposta positiva.
Caso guidato
Diff AI:
+ import { createMagicTable } from "react-smart-table-pro";
Il modello dice: “Ho aggiunto una tabella avanzata con sorting e filtri”. Prima di accettare:
- La libreria esiste? Cerca nel registry o nella documentazione ufficiale. Nome plausibile non significa reale.
- È installata? Controlla
package.jsone lockfile. - L’API usata esiste nella versione installata? Molti errori nascono da esempi di versioni diverse.
- Serve davvero? Se la tabella ha 20 righe e due colonne, sorting manuale è più comprensibile.
- Che costo porta? Bundle, CSS globale, accessibilità, manutenzione, licenza.
Decisione possibile:
Rifiuto nuova dipendenza.
Motivo: sorting e filtro testuale sono implementabili con `Array.sort` e `filter`.
Richiesta alternativa: mantenere componente esistente, aggiungere funzioni pure `sortRows` e `filterRows`, con test unitari. Nessun cambio a package.json.
Prompt di correzione:
Rimuovi la dipendenza proposta. Implementa sorting e filtro senza librerie esterne. Mantieni il diff entro il componente tabella e un file di test. Spiega eventuali limiti.
Il criterio non è “mai dipendenze”. Il criterio è: ogni dipendenza deve comprare più valore di quanto costa in rischio.
Procedura pratica
Per ogni PR/commit con codice generato:
- Leggi diff di
package.json/package-lock: nuove dipendenze? quali? - Per ognuna: verifica che sia necessaria (le 7 domande sezione 3).
- Per ogni import nei file modificati: pkg esiste? versione corrisponde?
- Per ogni funzione/opzione “che non avevo mai sentito”: documentazione ufficiale, conferma esistenza.
- Per codice che usa pattern “datato”: verifica versione installata.
- Esegui:
npm test,npm run build. Se gira, è almeno sintatticamente vero. Se non gira, indagare.
Laboratorio guidato
Esempio diff sospetto:
import { useDebounce, useToast } from 'react-hooks-utils'
import axios from 'axios'
async function searchUsers(query: string) {
const debouncedQuery = useDebounce(query, 300)
const { showToast } = useToast()
const response = await axios.get('/api/users', {
params: { q: debouncedQuery },
timeout: 5000,
retry: 3,
cache: true,
})
if (response.error) {
showToast({ type: 'error', message: response.error.message })
return []
}
return response.data
}
Verifiche:
react-hooks-utils: esiste? È una libreria reale? Cerca su npm. → Probabilmente non esiste. Cerca alternative reali (use-debounce,react-hot-toast).useDebouncein funzione async non React → uso scorretto di hook (regola degli hook).axios.getconretryecache: non sono opzioni standard di axios. Sono inventate.response.error: axios usatry/catchconerror.response, nonresponse.error. Pattern di fetch nativo confuso con axios.
Risultato: codice plausibile, completamente non funzionante. Refactor necessario, basato su API reali.
Output atteso
Una checklist personale “verifica dipendenze pre-merge”:
□ Diff di package.json controllato
□ Ogni nuova dipendenza giustificata (le 7 domande)
□ Ogni import esiste in versione installata
□ Ogni funzione/opzione confermata da doc ufficiale
□ Test passa
□ Build pulita
□ Bundle size accettabile (per client)
□ License compatibile
Studio passo passo
Studia questa lezione in tre passaggi, senza correre subito al prompt o al codice.
- Prima lettura: chiarisci l’obiettivo: verificare che il codice generato si basi su strumenti reali, installati e necessari. Se non riesci a riscriverlo in una frase tua, rileggi il nucleo della lezione.
- Seconda lettura: trasforma i contenuti in domande operative:
- Controllare package manager, import, documentazione ufficiale, versioni, API disponibili e dimensione del pacchetto.
- Riconoscere hallucinations: metodi plausibili ma inesistenti, opzioni non supportate, esempi presi da versioni diverse.
- Valutare se una dipendenza risolve un problema reale o sostituisce poche righe comprensibili.
- Applicazione: svolgi il laboratorio: analizzare un diff con una nuova libreria e decidere se accettarla, sostituirla o chiedere una soluzione senza dipendenze. L’output da ottenere è: una checklist per validare import, librerie e chiamate API prima del merge.
Prima di passare alla lezione successiva, controlla di avere un artefatto concreto: una tabella, un prompt, una checklist, un mini report, un diff commentato o una decisione scritta. Nel vibe coding la comprensione resta astratta finché non produce una traccia verificabile.
Checklist di verifica
- ho preso almeno una volta un caso di “libreria inventata” e l’ho riconosciuto;
- ho un default “NO nuove dipendenze” senza approvazione;
- verifico documentazione ufficiale per opzioni che non ho mai usato;
- conosco bundle size delle dipendenze frontend del mio progetto.
Errori comuni
Accettare nuove dipendenze “perché in PR”. PR non significa giustificate. Verifica.
Fidarsi di esempi blog/StackOverflow. Possono essere outdated o riferiti a versioni diverse. Documentazione ufficiale è autorità.
Non leggere package.json. Non vedi cose installate. Modello propone roba che si scontra.
Mix di versioni. Codice di un mix di tutorial vecchi/nuovi. Apparentemente sensato, eseguito spacca.
Dipendenze per task piccoli. lodash.debounce per usare debounce in un file. Scrivi 5 righe.
Niente lockfile. Build non riproducibile. Stesso codice, comportamento diverso fra macchine.
Audit ignorato. npm audit mostra vulnerabilità, le ignori. Segnali deboli sono comunque segnali.
Prompt di lavoro
Rivedi questo diff con focus su dipendenze e API.
[INCOLLA DIFF]
Contesto:
- stack: [...]
- versioni installate principali: [...]
- package.json prima del diff: [contenuto rilevante]
Verifiche richieste:
1. Per ogni nuovo import (incluso da pkg già presente): è valido nella versione installata?
2. Per ogni nuova dipendenza in package.json: è giustificata? Alternative più leggere o senza dipendenza?
3. Per ogni funzione chiamata di libreria esterna: esiste nella versione? Confermi opzioni?
4. Pattern "datato" (es. React class, callback al posto di async): è coerente con versioni installate?
5. Codice "plausibile ma sospetto": righe dove dovrei verificare doc ufficiale.
Output: lista numerata di problemi/dubbi, severità (blocking / sospetto / nit), suggerimento per ognuno.
NON proporre riscrittura. Voglio sapere cosa è solido e cosa è da verificare.
Esercizio finale
Apri il package.json del tuo progetto principale. Per ogni dipendenza top-level (non transitive), rispondi: la sto davvero usando? Quante volte è importata? Una dipendenza con 0 import nel codice di prodotto è da rimuovere. Spesso si scoprono 3-5 dipendenze morte. Pulizia in 10 minuti, bundle ridotto, complexity in meno.