Menu

Debug con l'IA: prompt che trovano la causa

Per fare debug con ChatGPT o Claude, incolla l'errore completo e il codice che l'ha sollevato, di' cosa ti aspettavi e cosa è successo invece, elenca cosa hai già provato e chiedi la causa prima della correzione.

Ogni prompt qui sotto è modificabile: cambialo, poi aprilo in ChatGPT, Claude o un'altra app di AI.

Il debug con l'IA funziona meglio quando dai al modello quello che daresti a un collega seduto accanto a te: l'errore completo, il codice che l'ha sollevato, cosa ti aspettavi, cosa è successo invece e cosa hai già escluso. Il modello non può eseguire il tuo programma né vedere i tuoi dati, quindi tutto ciò che sa del bug viene da quello che incolli. L'abitudine più utile in assoluto è chiedere la causa prima della correzione.

Incolla tutto, non solo l'errore

Le due schede qui sotto descrivono lo stesso bug. Uno script legge un file CSV esportato da Excel e va in crash con KeyError: 'email', anche se il file ha chiaramente una colonna email.

Correggi questo: KeyError: 'email'
Try it
Example replyReplies vary between models and runs.

Un KeyError significa che il dizionario non ha nessuna chiave chiamata 'email'. Puoi evitare l'errore usando .get(), che restituisce None invece di sollevare un'eccezione:

email = row.get("email")

Oppure controlla prima:

if "email" in row:
    email = row["email"]

La prima risposta ha ragione su cosa sia un KeyError, e qui il suo consiglio è dannoso. Con row.get("email") il crash sparisce, e ogni email diventa None. Il modello ha risposto alla versione più comune dell'errore perché è tutto ciò che il prompt descriveva.

La segnalazione completa ha funzionato grazie a due righe. "Fallisce solo la prima colonna" e "salvato da Excel come CSV UTF-8" sono gli indizi che portano al byte order mark, e nessuno dei due è nel messaggio di errore. Raramente sai quale dei tuoi dettagli è l'indizio, ed è per questo che li incolli tutti.

Le cinque cose da includere

  1. L'errore completo. Tutto il traceback o l'output della console, non una parafrasi. I numeri di riga e la catena di chiamate mostrano dove è iniziato il problema, che spesso sta qualche livello più in là rispetto a dove è emerso.
  2. Il codice che l'ha sollevato. La funzione che fallisce e il codice che la chiama. Se l'errore cita una riga, assicurati che quella riga sia in ciò che incolli.
  3. Atteso contro reale. Una frase per ciascuno. Per i bug senza alcun errore (output sbagliato, pagina bianca, query lenta), questa è l'intera segnalazione del bug.
  4. Il tuo ambiente. Versione del linguaggio, sistema operativo, versioni di framework e librerie quando potrebbero contare. I bug di codifica, percorsi e date spesso dipendono dalla piattaforma.
  5. Cosa hai già provato. Evita che il modello te lo suggerisca di nuovo, e il risultato di ogni tentativo è una prova. "Togliendo la parte dell'email funziona" ha ristretto il bug del CSV a una colonna.

Chiedi la causa prima della correzione

Una richiesta di correzione invita il modello a cambiare codice finché l'errore sparisce. Una richiesta di causa gli chiede di ragionare sul perché l'errore si verifica, e la correzione ne deriva. Chiedi un breve elenco ordinato di cause con un modo per verificarle una per una, poi esegui tu i controlli. Questo template fa proprio questo:

Ordina le cause, niente correzione per ora
Fill in
Parts
Aiutami a trovare la causa di un bug nel mio codice JavaScript. Non scrivere ancora una correzione.
Atteso: l'elenco degli utenti compare quando la pagina si carica Reale: pagina bianca, e questo errore nella console del browser
TypeError: Cannot read properties of undefined (reading 'map')function UserList() { const [users, setUsers] = useState(); useEffect(() => { fetch("/api/users") .then((res) => res.json()) .then((data) => setUsers(data)); }, []); return ( <ul> {users.map((u) => ( <li key={u.id}>{u.name}</li> ))} </ul> ); }
Elenca fino a tre cause probabili, prima la più probabile. Per ciascuna, dai un controllo di una riga che posso eseguire per confermarla o escluderla.
Try it
Example replyReplies vary between models and runs.
  1. Il componente viene renderizzato prima che esistano dati. useState() parte da undefined, e React renderizza il componente una volta prima che l'effetto venga eseguito, quindi users.map viene chiamato su undefined. Questo da solo produce esattamente il tuo errore, a ogni caricamento. Controllo: aggiungi console.log(users) subito prima del return. Se stampa undefined e subito dopo compare l'errore, è questo.
  2. L'API restituisce qualcosa che non è un array. Se restituisse un oggetto come { users: [...] }, l'errore sarebbe diverso (users.map is not a function), quindi non è l'errore che hai incollato. Può comunque essere il problema successivo una volta risolta la causa 1. Controllo: console.log(data) dentro il secondo .then.
  3. La richiesta fallisce. Per ora non c'entra: siccome il primo render solleva l'errore, React non esegue mai l'effetto, quindi la richiesta non viene nemmeno inviata. Controllo: la scheda Rete non mostra alcuna richiesta a /api/users, il che conferma anche la causa 1.

La risposta fa qualcosa che una risposta centrata sulla correzione salta: esclude alcune cause perché l'errore che produrrebbero è diverso da quello che hai incollato, o perché il codice non arriva mai abbastanza avanti perché si verifichino. È anche per questo che conta il testo esatto dell'errore. Chiedere al modello di elencare le cause prima di rispondere è una forma leggera di chain of thought prompting: prima viene il ragionamento e la conclusione si basa su di esso.

Crea una riproduzione minima

Una riproduzione minima è il programma più piccolo che mostra ancora il bug: dati scritti a mano invece di una chiamata al database, una funzione invece dell'intero modulo. Costruirla spesso fa trovare il bug prima ancora di chiedere a qualcuno, perché ogni pezzo che togli o mantiene il bug (non era coinvolto) o lo fa sparire (lo era). Quando non basta, la riproduzione è il prompt ideale: abbastanza corta perché il modello legga ogni riga, e priva di codice non collegato che potrebbe mandarlo a inseguire il problema sbagliato.

Se il bug dipende dai dati, includi qualche riga che lo provoca. Un modello può ragionare su [{"id": 1, "name": null}]; non può ragionare su "alcune righe in produzione".

Quando le correzioni smettono di funzionare

Se la terza correzione del modello fallisce allo stesso modo, una quarta richiesta di correzione difficilmente andrà meglio. Due cose aiutano di più:

  • Dagli prove nuove. Aggiungi un print o una riga di log che mostri i valori reali nel punto del problema, eseguilo e incolla l'output. Una prova che contraddice la teoria del modello è la strada più veloce verso una teoria migliore.
  • Apri una nuova conversazione. I thread di debug lunghi si riempiono di teorie abbandonate e vecchie versioni del codice, e il modello potrebbe continuare a costruirci sopra. Una nuova chat con il codice attuale, l'errore, le prove e una riga che dice "già escluso: X e Y" spesso arriva più lontano in una sola risposta.

Fai attenzione alle risposte molto sicure sul comportamento delle librerie. Un modello può descrivere un'opzione o una funzione che non esiste; vedi allucinazioni dell'IA per capire come verificare. Quando il codice non è rotto ma non capisci perché fa quello che fa, un prompt per spiegare il codice è lo strumento migliore.

Domande frequenti

Come chiedo a ChatGPT o Claude di correggere il mio codice?

Incolla il messaggio di errore completo e il codice che l'ha sollevato, poi aggiungi tre brevi righe: cosa ti aspettavi, cosa è successo invece e cosa hai già provato. Chiedi la causa più probabile e come confermarla prima di chiedere una correzione. Un semplice "correggi questo" ottiene una correzione per la versione più comune dell'errore, che potrebbe non essere la tua.

Devo incollare tutto il mio progetto nell'IA?

No. Incolla la funzione in cui si verifica l'errore, il codice che la chiama e un campione dei dati che riceve. Meglio ancora, riduci il problema al programma più piccolo che lo mostra ancora. I file non collegati rallentano la risposta e danno al modello più posti in cui cercare un problema che non c'è.

Perché la correzione dell'IA fa sparire l'errore ma il programma continua a non funzionare?

La correzione ha curato il sintomo. Per esempio, sostituire row["email"] con row.get("email") evita un KeyError, ma se la chiave manca per un bug a monte, ora ogni email è silenziosamente None. Chiedere prima la causa, e un modo per confermarla, evita correzioni che nascondono soltanto il problema.

E se l'IA continua a proporre correzioni che non funzionano?

Smetti di chiedere correzioni e dagli invece delle prove. Riferisci cosa ha cambiato ogni tentativo, aggiungi un print o una riga di log che mostri i valori reali e incolla quell'output. Se la conversazione è lunga, aprine una nuova con un riepilogo pulito: il codice, l'errore, le prove e le correzioni già scartate.

Illustrazione dei linguaggi di programmazione di Coddy

Impara a programmare con Coddy

INIZIA