Padrão Obsoleto ou Descontinuado.
Assistentes de IA emitem com confiança APIs, bibliotecas e expressões idiomáticas que eram atuais anos atrás, mas que agora estão descontinuadas, removidas ou substituídas, porque seu conhecimento paramétrico está congelado em um corte de treinamento e o padrão antigo ainda é o estatisticamente mais comum em seu corpus.
##Signs and Symptoms
Um revisor reconhece este smell quando o código gerado roda, mas combina com o estilo de um tutorial de dois ou três anos atrás: ele chama APIs sobre as quais o framework agora emite avisos, fixa versões principais antigas ou recorre a expressões idiomáticas legadas em vez da biblioteca padrão/sintaxe moderna. Sinais reveladores:
- Avisos de descontinuação na instalação/build/execução que o modelo ignorou (
DeprecationWarning,[DEP0005],componentWillMount is deprecated). - Expressões idiomáticas que antecedem a base atual da linguagem:
varem vez deconst/let, cadeias de callbacks/.then()onde a base de código usaasync/await,require()em um projeto ESM,moment.jsem vez deIntl/Temporal/date-fns. - Chamadas de biblioteca removidas na versão que você realmente tem instalada: pandas
df.append(...)/.ix[], ciclos de vida legados do React,datetime.utcnow(), Nodenew Buffer(),url.parse(). - Padrões de segurança legados que dominam dados de treinamento antigos: hashing MD5/SHA1,
crypto.createCipher, SQL bruto concatenado por strings. - Reinventar o que a plataforma agora já fornece (
deepClone,groupBy, UUID feitos à mão) em vez destructuredClone,Object.groupBy,crypto.randomUUID().
// Gerado por IA: compila, mas cada linha é um padrão agora descontinuado
const crypto = require('crypto'); // projeto ESM usa import
const buf = new Buffer(userInput); // Buffer() descontinuado desde o Node 6
const id = crypto.createHash('md5') // MD5 descontinuado para qualquer uso de segurança
.update(token).digest('hex');
const cipher = crypto.createCipher('aes-256-cbc', key); // API de caminho removido, KDF fraca
request(apiUrl, (err, res, body) => { /* ... */ }); // 'request' sem manutenção desde 2020
##Reasons for the Problem
Por que os modelos o produzem
- Defasagem do corte de treinamento. O conhecimento paramétrico de um LLM está congelado em seu corte, mas as bibliotecas continuam evoluindo. Estudos que medem isso encontram uma taxa de uso de APIs descontinuadas de 25–38% em oito bibliotecas Python nas completações de LLMs (Wang et al., ICSE 2025), e mesmo os modelos de ponta atingem apenas 48–51% em geração condicionada à versão (GitChameleon 2.0). Não há consciência de API/versão em tempo real no momento da inferência.
- A frequência do próximo token favorece o jeito antigo. O corpus contém anos de código legado, então a completação estatisticamente mais provável muitas vezes é a obsoleta. A OX Security observa que os modelos recorrem por padrão à concatenação de strings e a MD5/SHA1 justamente porque esses padrões "aparecem com mais frequência nos dados de treinamento", e a Veracode descobriu que os modelos escolhem a opção insegura/legada em ~45% das vezes quando lhes é dada uma escolha (OX Security).
- Sem contexto do repositório. O modelo geralmente não sabe qual versão principal você realmente instalou, o que seu lockfile fixa, ou que
lib/hash.tsjá existe — então ele não consegue mirar na sua superfície de API. O enquadramento do Stack Overflow: um agente é "um ótimo reconhecedor de padrões… código bom entra, código bom sai" — sem um exemplo atual, ele recorre à média de seus dados de treinamento (Reyes Q&A). - Recompensa por "fazer funcionar" + bajulação. Os modelos otimizam para código que plausivelmente compila e satisfaz o prompt, não para "usa o caminho atual e suportado". A chamada descontinuada ainda funciona hoje, então ela parece correta.
Por que isso prejudica
- Manutenibilidade / quebra-bomba-relógio. Descontinuado hoje significa removido na próxima versão principal — o código funciona até que uma atualização o quebre silenciosamente, e esses padrões são copiados e colados em vez de refatorados. A análise de 211M de linhas da GitClear mostra que as linhas copiadas/coladas subiram de 8,3%→12,3% enquanto as linhas refatoradas ("movidas") caíram de 24,1%→9,5% de 2020 a 2024, com blocos duplicados crescendo ~8x — então uma única expressão idiomática obsoleta se propaga em vez de ser corrigida uma única vez (GitClear 2025).
- Correção. APIs substituídas muitas vezes têm semântica sutilmente diferente (
utcnow()retorna um datetime ingênuo; ciclos de vida legados disparam em momentos diferentes), produzindo bugs que passam por um teste rápido de fumaça. - Segurança. Criptografia descontinuada (MD5,
createCipher) e versões de pacotes desatualizadas carregam CVEs conhecidos que o modelo nunca confronta com nenhum banco de dados de advisories — um motivador central da constatação de que a maioria do código gerado por IA é entregue com pelo menos uma vulnerabilidade. - Carga de revisão & dívida técnica. Cada ocorrência é uma correção manual separada e, como o padrão é duplicado em vez de centralizado, o custo se acumula por toda a base de código.
##Treatment
Táticas de revisão & prompting
- Declare as versões no prompt ou no contexto. "Estamos no React 19, pandas 2.2, Node 22 (ESM) — use apenas APIs atuais nessas versões." Traga a documentação atual para o contexto (um docs MCP / Context7) em vez de confiar na memória paramétrica.
- Force uma passagem de ferramentas. Exija que o modelo execute o linter, o verificador de tipos e
npm outdated/pip list --outdated, e então corrija todo aviso de descontinuação antes de declarar concluído. Avisos de descontinuação são o detector mais barato possível — não deixe que sejam ignorados. - Exija reutilização em vez de reinvenção. "Use o helper existente em
lib/hash.ts; não faça hashing à mão." Aponte para o módulo canônico para que o modelo não regenere uma versão legada (Código Duplicado). - Codemods em vez de edições manuais. Para atualizações sistemáticas, execute os codemods/modernizadores oficiais em vez de pedir ao modelo que reescreva à mão:
npx @next/codemod, codemods do React, regraspyupgrade/RuffUP. Eles são determinísticos e completos.
A refatoração — isto é essencialmente Substituir Algoritmo / substituir-API-descontinuada, e consolidar as chamadas obsoletas duplicadas em um único helper aplica Extrair Função contra Código Duplicado:
// Antes — APIs de caminho descontinuado/removido
const buf = new Buffer(userInput);
const id = crypto.createHash('md5').update(token).digest('hex');
const cipher = crypto.createCipher('aes-256-cbc', key);
// Depois — atual, suportado, sensato em segurança
import crypto from 'node:crypto';
const buf = Buffer.from(userInput); // construtor seguro
const id = crypto.createHash('sha256').update(token).digest('hex');
const iv = crypto.randomBytes(16); // IV explícito
const cipher = crypto.createCipheriv('aes-256-cbc', key, iv);
// (para senhas, use argon2/bcrypt — não um hash bruto)
Para dependências, a correção equivalente é elevar o pin e deixar o codemod migrar os pontos de chamada, e então bloquear a deriva futura no CI (regra de lint abaixo + uma política Dependabot/Renovate) para que o modelo não possa reintroduzir silenciosamente o padrão antigo.
##Detected by
- ESLint (eslint-plugin-n) n/no-deprecated-api — Proíbe APIs principais descontinuadas do Node.js (Buffer(), crypto.createCipher, url.parse, etc.)
- typescript-eslint @typescript-eslint/no-deprecated — Sinaliza o uso de qualquer símbolo marcado como @deprecated em sua declaração JSDoc/TS
- ESLint (eslint-plugin-react) react/no-deprecated — Sinaliza APIs e métodos de ciclo de vida descontinuados do React (componentWillMount, etc.)
- SonarQube / SonarSource RSPEC-1874 ("@Deprecated" code should not be used) — Relata o uso de código anotado/marcado como descontinuado
- Ruff pyupgrade (UP) rules — Detecta e reescreve expressões idiomáticas Python obsoletas/substituídas para equivalentes modernos
- Dependabot version-updates — Sinaliza versões de dependências desatualizadas (a faceta de pacote obsoleto deste smell)