Boilerplate Verboso.
Assistentes de IA incham lógica simples com comentários que repetem cada linha, narração passo a passo, escadas defensivas de verificações de null e expressões prolixas onde bastaria um idioma da linguagem ou um helper existente — aumentando a contagem de linhas sem acrescentar comportamento.
##Sinais e sintomas
Um revisor identifica Boilerplate Verboso quando um diff é muito mais longo do que o problema exige: cada linha é narrada por um comentário que apenas a reafirma, expressões simples são embrulhadas em escadas defensivas de null/undefined e o mesmo formato de código reaparece duas ou três vezes em vez de ser fatorado em um único helper. O sinal revelador é uma alta razão comentário-para-lógica e linha-para-comportamento, além de blocos que poderiam ter sido três linhas de código idiomático.
// Função para obter o nome completo do usuário
function getFullName(user: User): string {
// Verifica se o usuário está definido
if (user === null || user === undefined) {
// Retorna uma string vazia quando nenhum usuário é fornecido
return "";
}
// Obtém o primeiro nome, usando string vazia como padrão
const firstName = user.firstName ? user.firstName : "";
// Obtém o sobrenome, usando string vazia como padrão
const lastName = user.lastName ? user.lastName : "";
// Concatena o primeiro nome e o sobrenome com um espaço
const fullName = firstName + " " + lastName;
// Remove espaços em branco e retorna o resultado
return fullName.trim();
}
Três linhas de comportamento enterradas em ~12 linhas de cerimônia. Outros sinais: construtores ou wrappers vazios que só repassam a chamada, a cerimônia try { ... } catch (e) { throw e }, x ? x : fallback onde ?? bastaria, e um validador de e-mail/URL feito à mão ao lado do módulo de validação que o projeto já tem. Quando essa mesma forma verbosa também aparece copiada como getDisplayName, getLabel e getInitials, cada uma reescrevendo lógica que um util formatName() já cobre, a verbosidade virou Código Duplicado — veja Duplicação em Vez de Extração.
##Causas do problema
Por que os modelos produzem isso
- Viés de verbosidade do próximo token. LLMs são treinados em enormes volumes de código de tutoriais, Stack Overflow e iniciantes, onde comentários passo a passo e cerimônia explícita são a norma. A continuação mais provável é a mais profusamente explicada, não a mais concisa.
- O RLHF recompensa "parecer minucioso." O ajuste de prestatividade/verbosidade empurra os modelos para uma saída que parece completa e autoexplicativa — comentários em cada linha, verificações defensivas por toda parte — que avaliadores e usuários recompensam mesmo quando não agrega valor.
- Sem contexto do repositório, sem reutilização. Sem a base de código ao redor no contexto, o modelo não tem como saber que um util
formatName()ouvalidateEmail()já existe, então rederiva a lógica inline. Isso corresponde a dois padrões do relatório da OX Security: superespecificação (Over-Specification — "soluções hiperespecíficas, de uso único, que não podem ser adaptadas para outros fins", em 80–90% do código de IA) e evitação de refatorações (Avoidance of Refactors, 80–90%). - Geração, não consolidação. Agentes emitem código novo a cada prompt e raramente voltam para enxugá-lo. A análise de 2025 da GitClear sobre 211 milhões de linhas alteradas mostrou que as linhas associadas a refatoração ("movidas") caíram de 25% das linhas alteradas em 2021 para menos de 10% em 2024, enquanto as copiadas e coladas subiram de 8,3% para 12,3% e, em 2024, superaram as movidas pela primeira vez; blocos com cinco ou mais linhas duplicadas cresceram cerca de oito vezes durante 2024.
- Padrão de comentar tudo. A OX Security encontrou "Comentários por Toda Parte" em 90–100% do código gerado por IA.
Por que isso é prejudicial
- Manutenibilidade: mais superfície para ler e alterar; comentários redundantes perdem a sincronia com o código e passam a enganar ativamente (o smell Comentários de Fowler).
- Correção e segurança: assim que um bloco verboso é copiado, um bug ou uma vulnerabilidade precisa ser corrigido em N lugares — o padrão Bugs Déjà-Vu da OX (70–80%), que faz "bugs idênticos aparecerem repetidamente pela base de código, exigindo a mesma correção várias vezes".
- Carga de revisão: diffs grandes e de baixo sinal escondem mudanças reais e induzem fadiga no revisor, então problemas genuínos passam despercebidos.
- Dívida técnica que se acumula: cada quase-duplicata torna a próxima extração mais difícil, enraizando o problema que o modelo não consegue enxergar entre arquivos.
##Tratamento
Táticas de revisão / prompting
- Force a reutilização antes da geração: "Procure na base de código por helpers existentes (
formatName,validate*) e reutilize-os; não reimplemente." Forneça os utils relevantes no contexto. - Estabeleça um orçamento para a saída: "Mantenha isto em menos de ~15 linhas; sem comentários que reafirmem o código — apenas comentários explicando o porquê."
- Faça o modelo executar as ferramentas: exija
eslint/ruffe uma passada de duplicação comjscpd, e faça-o relatar e corrigir as violações antes de retornar. - Peça o menor diff e uma etapa explícita de deduplicação: "Se algum bloco se repetir, extraia uma função compartilhada e chame-a" (Extrair Método).
- Consolide na revisão: ao ver a terceira quase-cópia, aplique Extrair Método, Subir Método ou Consolidar Fragmentos Condicionais Duplicados; onde um comentário só explica o que uma expressão faz, aplique Extrair Variável ou Renomear Método para que o próprio código carregue a explicação e o comentário possa sair.
Refatoração (antes → depois)
// depois: comentários removidos (o código é autoevidente), cerimônia eliminada,
// e o util formatName() existente reutilizado em vez de reconstruído inline
import { formatName } from "@/utils/format";
export const getFullName = (user?: User): string =>
formatName(user?.firstName, user?.lastName);
E elimine os duplicados de vez — se getDisplayName/getLabel faziam a mesma coisa, aponte quem as chama para uma única função e apague as cópias (Embutir Método); o que ficar sem chamadas é Código Morto e também sai. Substitua o validador feito à mão pelo import do módulo existente em vez de manter uma cópia paralela.
Regra prática para o catálogo: trate qualquer bloco de IA em que os comentários superem as linhas de lógica, ou em que você consiga nomear um helper existente que ele ignorou, como candidato à exclusão-por-reutilização — a correção mais rápida para boilerplate costuma ser menos código, não mais.
##Detectado por
- ESLint (core) no-useless-catch — Cláusulas catch desnecessárias (cerimônia de capturar e relançar: catch (e) { throw e })
- ESLint (core) no-unneeded-ternary — Operadores ternários onde existe uma alternativa mais simples (com defaultAssignment: false, detecta x ? x : fallback)
- typescript-eslint @typescript-eslint/prefer-nullish-coalescing — Preferir ?? a || e a ternários com verificação explícita de null
- ESLint (core) no-useless-constructor — Construtor vazio redundante / boilerplate de passagem
- ESLint (core) max-lines-per-function — Comprimento de função inchado/verboso (proxy parcial)
- jscpd --min-tokens / --threshold — Detecção de copiar/colar, para quando blocos verbosos são copiados e colados (limite --min-tokens / --threshold)
- SonarQube / SonarCloud typescript:S4144 — Funções e métodos não devem ter implementações idênticas
- ESLint (eslint-plugin-sonarjs) sonarjs/no-identical-functions — Funções não devem ter implementações idênticas