Logotipo do ConstructiCat
CodeBust.
Explorar a seção ▾

API Alucinada.

Código gerado por IA que chama funções, métodos, parâmetros, chaves de configuração ou pacotes que parecem plausíveis, mas que não existem na versão real da biblioteca da qual você depende.

##Sinais e sintomas

Um revisor identifica uma API Alucinada quando o código lê de forma fluente e "parece" um uso idiomático de uma biblioteca, mas a chamada, opção ou importação específica não pode ser encontrada na API real dessa biblioteca. Sinais reveladores:

  • Um método ou opção cujo nome é conveniente demais — faz exatamente o que o prompt pediu, com um nome que mescla duas APIs reais (por exemplo, findLastWhere, includesAll, parseDateSafe).
  • Parâmetros inventados em uma função real (a variante perigosa — muitas vezes compila e só falha em tempo de execução, ou ignora silenciosamente a opção).
  • Um import de um pacote que não está no package.json / requirements.txt, ou uma importação nomeada que o módulo nunca exporta.
  • Formatos de API que misturam versões: uma assinatura da v2 chamada em um cliente v5, ou um método removido/renomeado várias releases atrás.
  • Comentários inline confiantes afirmando que a chamada está correta ("// retorna a cobrança reembolsada").
// Gerado por IA — fluente, plausível e errado
import { formatRelative } from 'date-fns';

// `roundingMethod` é inventado aqui — formatRelative não aceita essa opção (ela pertence a formatDistanceStrict), então ela é silenciosamente ignorada
const label = formatRelative(date, new Date(), { roundingMethod: 'floor' });

// `findLastWhere` não existe em Array — TypeError em tempo de execução
const lastActive = items.findLastWhere(i => i.active);

// Método de SDK inventado: o stripe-node não tem refunds.createForCharge — a chamada real é stripe.refunds.create({ charge, amount })
await stripe.refunds.createForCharge(chargeId, { amount: 500 });

Uma heurística rápida: se você não consegue apontar a entrada na documentação ou a definição de tipo de uma chamada de terceiros em menos de um minuto, trate-a como alucinada até prova em contrário.

##Causas do problema

Por que os modelos a produzem

  • Plausibilidade do próximo token, não consulta. Um LLM prevê a continuação estatisticamente mais provável, que é efetivamente a média de cada API similar que ele já viu. Essa média muitas vezes é um método que deveria existir — o modelo emite "o nome conveniente" em vez do real. Em um estudo sobre recomendação de APIs para Java 8 (JRE), 58,1%–84,1% das APIs recomendadas por três modelos não existiam na biblioteca especificada, e a maioria dos erros eram nomes de métodos inexistentes (arXiv 2409.15228).
  • Mistura de versões. Os corpora de treinamento misturam muitas versões de uma biblioteca, então o modelo funde assinaturas da v2 e da v5 em uma que não corresponde a nenhuma. Conflitos de conhecimento de API, como chamar um parâmetro inexistente, são uma categoria documentada de alucinação em nível de repositório (Zhang et al., ISSTA 2025), e os autores observam que algumas alucinações podem passar pelas verificações estáticas e por todos os casos de teste.
  • Defasagem do corte de treinamento. O modelo usa com confiança APIs renomeadas, descontinuadas ou removidas desde seu corte, e recorre ao que mais apareceu em seu corpus de treinamento — que pode ser uma versão da biblioteca mais antiga do que a que você tem instalada.
  • Sem contexto de repositório/dependência. Sem o seu package.json ou o código-fonte real do módulo, o modelo inventa helpers que "parecem" pertencer à sua stack.
  • Bajulação / ânsia por responder. O assistente quase nunca diz "não tenho certeza de que esse método existe" — ele produz código confiante e com aparência executável, o que reduz a suspeita do revisor.
  • O determinismo o torna explorável. A alucinação de pacotes não é ruído aleatório: em 16 modelos e 576.000 amostras de código (2,23M de referências a pacotes), 19,7% das referências a pacotes eram alucinadas (205.474 nomes únicos inexistentes), e 58% dos pacotes alucinados se repetiram mais de uma vez em 10 execuções do mesmo prompt (Spracklen et al., USENIX Security 2025; resumo da SecurityWeek).

Por que isso prejudica

  • Correção. Parâmetros inventados e opções silenciosamente ignoradas produzem comportamento errado em caminhos de código que os testes raramente cobrem; a falha aparece em produção, não em tempo de compilação.
  • Segurança / cadeia de suprimentos. Um nome de pacote alucinado é um alvo de registro: atacantes publicam malware sob o nome previsto, então o próximo desenvolvedor que aceitar a sugestão o instala — o ataque de slopsquatting (termo cunhado por Seth Larson, da PSF). A variante de obsolescência reintroduz silenciosamente APIs descontinuadas ou portadoras de CVEs.
  • Carga de revisão. Código plausível transfere o ônus para os revisores, que precisam verificar cada chamada desconhecida contra a documentação; a prosa fluente torna essa verificação menos provável de acontecer.
  • Acúmulo de dívida técnica. Os desenvolvedores muitas vezes colam o stub alucinado "quase funcional" e remendam ao redor dele em vez de corrigir a chamada-raiz — alimentando a tendência mais ampla da era da IA de aumento de copy/paste e queda de refatoração (GitClear 2025: linhas movidas/refatoradas 25% (2021) → menos de 10% (2024); copy/paste 8,3% → 12,3%; blocos duplicados de 5+ linhas ~8× em 2024).

##Tratamento

Táticas de processo & prompting

  • Baseie o modelo na API real. Cole no contexto os stubs de tipo reais, a página de documentação relevante ou o código-fonte da versão instalada, ou use uma ferramenta de recuperação de documentação (estilo Context7 / RAG). Informe a ele as versões exatas das dependências a partir do seu lockfile.
  • Exija citações. Peça ao modelo que nomeie a entrada oficial da documentação ou a assinatura de tipo de cada chamada de terceiros que ele usar. Regra prática dos praticantes: toda chamada de método contra uma biblioteca de terceiros deve ser rastreada até sua entrada na documentação antes de o PR ser aprovado.
  • Faça rodar, no loop. Exija que tsc / mypy / pylint / o build e a suíte de testes passem, e faça o agente de fato executar npm install / pip install para que um pacote alucinado falhe cedo em vez de chegar à revisão.
  • Peça que ele reutilize, não invente. Forneça um grep do módulo existente e instrua-o a chamar helpers existentes (reutilize os helpers em utils/http.ts) em vez de conjurar novos — isso também combate o smell relacionado de duplicação por helper reinventado.
  • Controle as dependências. Use um lockfile + uma allowlist de instalação e um scanner de cadeia de suprimentos (Socket/Snyk) antes que qualquer novo pacote seja adicionado, para que nomes vítimas de slopsquatting não consigam se infiltrar.

A refatoração do código

Substitua a chamada inventada pela real e verificada. Se você realmente quer a conveniência que o modelo imaginou, implemente-a uma vez contra a API real por trás de um wrapper criado com Extrair Método, em vez de espalhar a chamada falsa.

// Antes — método de SDK inventado + valor de opção inválido
async function refundLast(chargeId: string) {
  // `stripe.refunds.createForCharge` não existe, e 'requested' não é um motivo de reembolso válido
  return stripe.refunds.createForCharge(chargeId, { amount: 500, reason: 'requested' });
}

// Depois — verificado contra os tipos/documentação do SDK do Stripe instalado,
// e a "conveniência" encapsulada uma vez para que a API real não seja repetida
async function refundCharge(chargeId: string, amountCents: number) {
  return stripe.refunds.create({
    charge: chargeId,
    amount: amountCents,
    reason: 'requested_by_customer',
  });
}

Para a variante de obsolescência, trate uma chamada descontinuada sinalizada como uma tarefa real de atualização: migre para a API atual e fixe a versão, em vez de silenciar o aviso.

Limites. Verificadores de tipo e resolvedores capturam o subconjunto resolvível (objetos tipados, importações não resolvidas). O restante dinâmico/não tipado — opções inventadas em any, chaves de configuração em string, campos de payload REST — não tem detector automatizado confiável e precisa ser verificado por um humano contra a documentação real.

##Detectado por