No mês passado meu agente confidentemente chamou uma ferramenta chamada search_invoices. Essa ferramenta não existia. Nunca existiu. O modelo inventou o nome, inventou os argumentos, e emitiu um bloco JSON perfeitamente formado para ela. Meu harness, confiante e ingênuo, tentou despachá-la e travou.
Se você constrói agentes, já viu isso. O modelo chama uma ferramenta que não está no seu schema, ou chama uma ferramenta real com argumentos que não correspondem ao schema de input, ou narra uma chamada de ferramenta em texto simples em vez de emitir o bloco tool_use real. As pessoas chamam tudo isso de "alucinando chamadas de ferramentas". Quero explicar por que acontece no nível de mecanismo, porque uma vez que você vê, as correções param de parecer superstição.
O modelo está prevendo tokens, não executando seu código
Aqui está o que ninguém te diz quando você começa. Uma chamada de ferramenta não é uma invocação de função do lado do modelo. É texto. Texto estruturado, claro, mas texto. O modelo emite um bloco tool_use da mesma forma que emite um parágrafo: prevendo os próximos tokens mais prováveis dado tudo que veio antes. Seu schema faz parte desse contexto, mas não é uma restrição rígida a menos que você a faça uma.
Então quando dá errado? Quando a distribuição dos próximos tokens plausíveis aponta para algum lugar que seu schema não cobre. Se seu histórico de conversa está cheio de referências a faturas, e o modelo decide que precisa de dados de faturas, search_invoices é uma sequência de tokens incrivelmente plausível — mesmo que a ferramenta que você deu se chame na verdade query_billing. O modelo está fazendo correspondência de padrões contra tudo que já viu, e "search_" + substantivo é uma das formas de nomes de ferramentas mais comuns em seus dados de treinamento.
É por isso que chamadas de ferramentas alucinadas disparam em duas situações: quando seus nomes de ferramentas são incomuns, e quando seu contexto é longo e ruidoso.
Correção um: torne a chamada certa a mais provável
Nomeie suas ferramentas da forma que o modelo espera que ferramentas sejam nomeadas. get_weather, send_email, search_database. Chato é bom. Chato é previsível, e previsível significa que o palpite do próximo token do modelo cai na sua ferramenta real em vez de em uma prima inventada.
Depois escreva descrições que digam quando chamar, não apenas o que a ferramenta faz. Isso importa mais em modelos Claude recentes — Opus 4.7 e 4.8 são mais conservadores em recorrer a ferramentas do que 4.6, então uma descrição como "Chame isso quando o usuário perguntar sobre preços atuais ou eventos recentes" aumenta mensuravelmente a taxa de chamada quando deveria. A condição gatilho faz parte do que o modelo condiciona. Coloque-a na descrição, não enterrada no system prompt.
Correção dois: não deixe chamadas ruins passarem
Quando o modelo emite uma chamada malformada, seu harness deve rejeitá-la com barulho, não travar. Retorne um tool_result com is_error: true e uma mensagem que o modelo pode ler:
{
"type": "tool_result",
"tool_use_id": "toolu_abc",
"content": "Nenhuma ferramenta chamada 'search_invoices'. Disponíveis: query_billing, get_customer.",
"is_error": true
}
O modelo lê esse erro no próximo turno e corrige. Vi o Opus 4.8 se recuperar de um nome de ferramenta alucinado em um único turno dessa forma — vê o erro, olha a lista disponível, e re-emite a chamada certa. Não descarte a chamada falhada silenciosamente. Não tente novamente com o mesmo prompt na esperança. Alimente o erro de volta.
Correção três: schemas rígidos para o problema de argumentos
A alucinação de nome e a alucinação de argumento são bugs diferentes. Para argumentos — tipos errados, campos obrigatórios faltando, campos extras — use o uso rígido de ferramentas. Defina strict: true na própria definição da ferramenta (não em tool_choice, isso não faz nada), com additionalProperties: false e uma lista required. Agora a API garante que o input valida exatamente contra seu schema. O modelo literalmente não pode emitir uma forma de argumento que não caiba.
Uma ressalva: o modo rígido não é compatível com tudo. Não funcionará com chamadas de ferramentas programáticas, tool_choice forçado, ou ferramentas MCP. Para esses você está de volta validando você mesmo.
Correção quatro: encurte o contexto do qual a chamada depende
Lembra do gatilho longo-e-ruidoso? Em um longo loop agêntico, resultados antigos de ferramentas se acumulam. No turno 40 o modelo está condicionando em 39 turnos de output majoritariamente irrelevante, e o sinal para "qual ferramenta, quais args" fica afogado. É aqui que a edição de contexto ganha seu lugar — limpando resultados tool_use obsoletos para que a próxima previsão do modelo seja baseada no que é realmente relevante. É um recurso beta (clear_tool_uses_20250919), e não é o mesmo que compactação, que resume em vez de limpar. Para precisão de chamada de ferramenta especificamente, limpar vence resumir, porque um resumo do output antigo de ferramentas ainda empurra a distribuição.
O que surpreende as pessoas
Quando o modelo narra uma chamada de ferramenta em vez de emiti-la — "Vou agora pesquisar isso no banco de dados" sem nenhum bloco tool_use real — isso não é realmente uma alucinação. O modelo está encerrando seu turno cedo. Em execuções longas do Claude, ocasionalmente escreve uma declaração de intenção sem a chamada. A correção é um nudge no system prompt: diga-lhe que antes de encerrar um turno, se seu último parágrafo é uma promessa sobre trabalho que não fez, ele deve fazer esse trabalho agora com uma chamada de ferramenta. Um simples "continue" o recupera interativamente. Para pipelines autônomos, incorpore a instrução.
O que quero que você leve é isto: nenhuma dessas correções é mágica. Todas fazem a mesma coisa — dobrar a distribuição de probabilidade em direção à chamada que você quer, ou capturar a chamada que não quer. O modelo não está com defeito quando inventa search_invoices. Está fazendo exatamente o que foi construído para fazer, com um contexto que apontava na direção errada. Aponte-o melhor.
