ConstructiCat Logo
CodeBust.
Browse section ▾

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.

##Signs and Symptoms

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 superfície 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 — date-fns não expõe tal opçã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);

// Chamada de SDK mesclada: o formato real do Stripe é stripe.refunds.create({ charge })
await stripe.charges.refund(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.

##Reasons for the Problem

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. Estudos de recomendação de API constatam que 58,1%–84,1% das APIs recomendadas não existem no pacote nomeado, e o erro dominante são nomes de métodos inexistentes (arXiv 2404.00971, ACM TOSEM 2025).
  • 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. Essas "Alucinações por Conflito de Conhecimento" (por exemplo, parâmetros inexistentes) são especificamente o tipo que passa despercebido pelos linters e falha em tempo de execução.
  • 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 no corpus — o que, como a OX Security observa, significa que versões de pacotes mais antigas, às vezes vulneráveis, acabam sendo recomendadas (relatório OX, out/2025).
  • 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 2,23M de gerações, 19,7% dos pacotes recomendados eram fictícios (205.474 nomes únicos), e 58% das alucinações se repetiram em até 10 novos prompts (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: clones em alta ~8×, linhas movidas por refatoração caindo de 25% para <10%). Esse padrão já está catalogado entre os code smells específicos de IA (arXiv 2509.20491).

##Treatment

Táticas de processo & prompting

  • Fundamente o modelo em superfícies reais. 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 de Extrair Função, em vez de espalhar a chamada falsa.

// Antes — parâmetro alucinado + formato de SDK mesclado
async function refundLast(chargeId: string) {
  // `stripe.charges.refund` e este formato de opção não existem
  return stripe.charges.refund(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.

##Detected by