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

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() ou validateEmail() 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/ruff e uma passada de duplicação com jscpd, 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