Depurar com IA funciona melhor quando você dá ao modelo o que daria a um colega sentado ao seu lado: o erro inteiro, o código que o gerou, o que você esperava, o que aconteceu e o que você já descartou. O modelo não consegue rodar o seu programa nem ver os seus dados, então tudo o que ele sabe sobre o bug vem do que você cola. O hábito mais útil de todos é pedir a causa antes da correção.
Cole tudo, não só o erro
As duas abas abaixo descrevem o mesmo bug. Um script lê um arquivo CSV exportado do Excel e quebra com KeyError: 'email', mesmo o arquivo tendo claramente uma coluna de e-mail.
Um KeyError significa que o dicionário não tem nenhuma chave chamada 'email'. Você pode evitar o erro usando .get(), que retorna None em vez de gerar o erro:
email = row.get("email")
Ou verifique antes:
if "email" in row:
email = row["email"]
A primeira resposta está certa sobre o que é um KeyError, e o conselho dela é prejudicial aqui. Com row.get("email"), o erro desaparece e todo e-mail vira None. O modelo respondeu à versão mais comum do erro porque foi só isso que o prompt descreveu.
O relato completo funcionou por causa de duas linhas. "Só a primeira coluna falha" e "salvo no Excel como CSV UTF-8" são as pistas que apontam para o byte order mark, e nenhuma delas está na mensagem de erro. Você raramente sabe qual dos seus detalhes é a pista, e é por isso que cola todos.
As cinco coisas para incluir
- O erro completo. O traceback inteiro ou a saída do console, não uma paráfrase. Os números de linha e a cadeia de chamadas mostram onde a falha começou, o que muitas vezes fica algumas chamadas antes de onde ela apareceu.
- O código que gerou o erro. A função que falha e o código que a chama. Se o erro menciona uma linha, confira se essa linha está no que você colou.
- Esperado e real. Uma frase para cada. Para bugs sem nenhum erro (saída errada, página em branco, consulta lenta), isso é o relato de bug inteiro.
- O seu ambiente. Versão da linguagem, sistema operacional e versões de framework e bibliotecas quando puderem importar. Bugs de codificação, caminhos e datas muitas vezes dependem da plataforma.
- O que você já tentou. Isso impede que o modelo sugira a mesma coisa de novo, e o resultado de cada tentativa é uma evidência. "Tirar a parte do e-mail faz funcionar" reduziu o bug do CSV a uma coluna.
Peça a causa antes da correção
Um pedido de correção convida o modelo a mudar o código até o erro sumir. Um pedido de causa pede que ele raciocine sobre por que o erro acontece, e a correção sai daí. Peça uma lista curta e ordenada de causas com um jeito de verificar cada uma e depois faça as verificações você mesmo. Este template faz isso:
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>
);
}- O componente renderiza antes de existir qualquer dado. O
useState()começa comoundefined, e o React renderiza o componente uma vez antes de o efeito rodar, entãousers.mapé chamado emundefined. Isso sozinho produz exatamente o seu erro, em todo carregamento. Verificação: acrescenteconsole.log(users)logo antes doreturn. Se ele mostrarundefinede o erro vier logo em seguida, é isso. - A API retorna algo que não é um array. Se ela retornasse um objeto como
{ users: [...] }, o erro seria outro (users.map is not a function), então esse não é o erro que você colou. Ainda pode ser o próximo problema depois que a causa 1 for resolvida. Verificação:console.log(data)dentro do segundo.then. - A requisição falha. Ainda não está envolvida: como a primeira renderização gera o erro, o React nunca roda o efeito, então a requisição nem chega a ser enviada. Verificação: a aba Network não mostra nenhuma requisição para
/api/users, o que também confirma a causa 1.
A resposta faz algo que uma resposta focada na correção pula: ela descarta causas porque o erro que elas produziriam é diferente do que você colou, ou porque o código nunca chega longe o bastante para que elas aconteçam. É por isso também que o texto exato do erro importa. Pedir ao modelo que liste as causas antes de responder é uma forma leve de chain of thought: o raciocínio vem primeiro e a conclusão se apoia nele.
Monte uma reprodução mínima
Uma reprodução mínima é o menor programa que ainda mostra o bug: dados fixos no código em vez de uma chamada ao banco, uma função em vez do módulo inteiro. Montar uma muitas vezes encontra o bug antes de você perguntar a alguém, porque cada parte que você tira ou mantém o bug (ela não estava envolvida) ou o faz sumir (estava). Quando isso não acontece, a reprodução é o prompt ideal: curta o bastante para o modelo ler cada linha e livre de código sem relação que poderia mandá-lo atrás do problema errado.
Se o bug depende dos dados, inclua algumas linhas que o disparam. Um modelo consegue raciocinar sobre [{"id": 1, "name": null}]; não consegue raciocinar sobre "algumas linhas em produção".
Quando as correções param de funcionar
Se a terceira correção do modelo falha do mesmo jeito, é improvável que um quarto pedido de correção se saia melhor. Duas coisas ajudam mais:
- Dê a ele evidências novas. Acrescente um print ou uma linha de log que mostre os valores reais no ponto da falha, rode e cole a saída. Uma evidência que contradiz a teoria do modelo é o caminho mais rápido para uma teoria melhor.
- Comece uma conversa nova. Conversas longas de depuração se enchem de teorias abandonadas e versões antigas do código, e o modelo pode continuar construindo em cima delas. Um chat novo com o código atual, o erro, as evidências e uma linha dizendo "já descartado: X e Y" muitas vezes vai mais longe em uma resposta.
Cuidado com respostas confiantes sobre o comportamento de bibliotecas. Um modelo pode descrever uma opção ou uma função que não existe; veja alucinação de IA para saber como conferir. Quando o código não está quebrado, mas você não entende por que ele faz o que faz, um prompt para explicar código é a ferramenta certa.
Perguntas frequentes
Como peço ao ChatGPT ou ao Claude que corrija o meu código?
Cole a mensagem de erro completa e o código que a gerou e acrescente três linhas curtas: o que você esperava, o que aconteceu e o que você já tentou. Peça a causa mais provável e um jeito de confirmá-la antes de pedir uma correção. Um simples "corrija isto" traz uma correção para a versão mais comum do erro, que pode não ser a sua.
Devo colar o projeto inteiro na IA?
Não. Cole a função onde o erro acontece, o código que a chama e uma amostra dos dados que ela recebe. Melhor ainda, reduza o problema ao menor programa que ainda o mostra. Arquivos sem relação deixam a resposta mais lenta e dão ao modelo mais lugares para procurar um problema que não está ali.
Por que a correção da IA faz o erro sumir, mas o programa continua sem funcionar?
A correção tratou o sintoma. Por exemplo, trocar row["email"] por row.get("email") acaba com o KeyError, mas se a chave falta por causa de um bug anterior, agora todo e-mail vira None em silêncio. Pedir a causa primeiro, e um jeito de confirmá-la, evita correções que só escondem o problema.
E se a IA continuar sugerindo correções que não funcionam?
Pare de pedir correções e dê evidências. Diga o que cada tentativa mudou, acrescente um print ou uma linha de log que mostre os valores reais e cole essa saída. Se a conversa estiver longa, comece outra com um resumo limpo: o código, o erro, as evidências e as correções já descartadas.