---
title: "Código repetitivo verboso"
type: "ai-smell"
slug: "verbose-boilerplate"
url: "http://localhost:3000/es/ai-smells/verbose-boilerplate.md"
category: "Claridad"
description: "Los asistentes de IA rellenan una lógica sencilla con comentarios redundantes, ceremonia defensiva y bloques casi duplicados copiados y pegados en lugar de reutilizar o extraer código existente, inflando el número de líneas sin aportar valor."
---
# Código repetitivo verboso

> Los asistentes de IA rellenan una lógica sencilla con comentarios redundantes, ceremonia defensiva y bloques casi duplicados copiados y pegados en lugar de reutilizar o extraer código existente, inflando el número de líneas sin aportar valor.

## Signs and Symptoms

Quien revisa detecta Código repetitivo verboso cuando un diff es mucho más largo de lo que el problema justifica: cada línea está narrada por un comentario que solo la repite, las expresiones simples se envuelven en escaleras defensivas de `null`/`undefined` y la misma forma de código reaparece dos o tres veces en vez de factorizarse en una función auxiliar. El delator es una alta proporción _comentario-a-lógica_ y _línea-a-comportamiento_, además de bloques que podrían haber sido tres líneas de código idiomático.

```ts
// Función para obtener el nombre completo del usuario
function getFullName(user: User): string {
  // Comprobar si el usuario está definido
  if (user === null || user === undefined) {
    // Devolver una cadena vacía cuando no se proporciona usuario
    return "";
  }
  // Obtener el nombre, con cadena vacía por defecto
  const firstName = user.firstName ? user.firstName : "";
  // Obtener el apellido, con cadena vacía por defecto
  const lastName = user.lastName ? user.lastName : "";
  // Concatenar el nombre y el apellido con un espacio
  const fullName = firstName + " " + lastName;
  // Recortar los espacios en blanco y devolver el resultado
  return fullName.trim();
}

```

Tres líneas de comportamiento enterradas en \~12 líneas de ceremonia. En un PR real sueles ver este _mismo_ patrón copiado y pegado como `getDisplayName`, `getLabel` y `getInitials`, cada uno reimplementando a mano una lógica que una utilidad `formatName()` ya cubre: el clásico olor de **Código duplicado**. Otros delatores: constructores/envoltorios vacíos de paso directo, ceremonia `try { ... } catch (e) { throw e }` y un validador de email/URL hecho a medida junto al módulo de validación que el proyecto ya tiene.

## Reasons for the Problem

**Por qué los modelos lo producen**

* **Sesgo de verbosidad del siguiente token.** Los LLM se entrenan con volúmenes enormes de código de tutoriales, Stack Overflow y código principiante donde los comentarios paso a paso y la ceremonia explícita son la norma. La continuación más _probable_ es la más explicada, no la más concisa.
* **El RLHF recompensa "parecer minucioso".** El ajuste por utilidad/verbosidad empuja a los modelos hacia una salida que aparenta ser completa y autoexplicativa —comentarios en cada línea, comprobaciones defensivas por todas partes— que los evaluadores y los usuarios recompensan aunque no aporte valor.
* **Sin contexto del repositorio no hay reutilización.** Sin la base de código circundante en el contexto, el modelo no puede saber que ya existe una utilidad `formatName()` o `validateEmail()`, así que la rederiva en línea. Esto es exactamente la **Sobreespecificación** de OX Security ("soluciones hiperespecíficas de un solo uso en lugar de componentes generalizables y reutilizables", hallada en el 80-90% del código de IA) y la **Evitación de refactorizaciones** (80-90%).
* **Generación, no consolidación.** Los agentes emiten código nuevo por cada prompt y nunca vuelven para deduplicar. El análisis de GitClear de 2025 sobre 211M de líneas modificadas halló que el código copiado/pegado subió de 8,3% (2020) a 12,3% (2024) y superó por primera vez a las líneas "movidas" (refactorizadas), mientras que las líneas refactorizadas cayeron de \~24% a 9,5% y los bloques duplicados de más de 5 líneas se multiplicaron \~8×.
* **Comentar todo por defecto.** OX Security encontró "Comentarios por todas partes" en el 90-100% del código generado por IA.

**Por qué hace daño**

* **Mantenibilidad:** más superficie que leer y cambiar; los comentarios redundantes se desincronizan del código y se vuelven activamente engañosos (el olor de los **Comentarios** de Fowler).
* **Corrección y seguridad:** los bloques duplicados implican que un fallo o una vulnerabilidad debe arreglarse en N sitios: el **Déjà-vu de fallos** de OX (70-80%). El código clonado se correlaciona con un 15-50% más de defectos.
* **Carga de revisión:** los diffs grandes y de baja señal ocultan los cambios reales e inducen fatiga en quien revisa, así que los problemas genuinos se cuelan.
* **Deuda técnica acumulativa:** cada casi-duplicado hace más difícil la _siguiente_ extracción, atrincherando el problema que el modelo no puede ver entre archivos.

## Treatment

**Tácticas de revisión y de prompts**

* **Fuerza la reutilización antes de generar:** "Busca en la base de código funciones auxiliares existentes (`formatName`, `validate*`) y reutilízalas; no las reimplementes." Proporciona las utilidades relevantes en el contexto.
* **Pon un presupuesto a la salida:** "Mantén esto por debajo de \~15 líneas; sin comentarios que repitan el código, solo comentarios que expliquen el _porqué_."
* **Haz que el modelo ejecute las herramientas:** exige `eslint`/`ruff` y una pasada de duplicación con `jscpd`, y que informe y arregle las violaciones antes de devolver.
* **Pide el diff más pequeño** y un paso explícito de deduplicación: "Si algún bloque se repite, extrae una sola función compartida (Extraer función) y llámala."
* **Consolida en la revisión:** cuando veas la tercera casi-copia, aplica **Extraer función**, **Subir método** o **Consolidar fragmentos condicionales duplicados**, y **Reemplazar comentario por código** (renombra para que el código se autodocumente).

**Refactorización (antes → después)**

```ts
// después: comentarios eliminados (el código se explica solo), ceremonia colapsada,
// utilidad compartida reutilizada en vez de rederivada
function getFullName(user?: User): string {
  return [user?.firstName, user?.lastName].filter(Boolean).join(" ");
}

```

Y elimina los duplicados de raíz: si `getDisplayName`/`getLabel` hacían lo mismo, bórralos y apunta a quienes los llaman hacia una sola función (**Eliminar código muerto** / **Insertar función en línea**). Sustituye el validador hecho a mano por la importación del módulo existente en lugar de mantener una copia paralela.

Regla práctica para el catálogo: trata cualquier bloque de IA donde los comentarios superen en número a las líneas de lógica, o donde puedas nombrar una función auxiliar existente que ignoró, como candidato a la eliminación-por-reutilización: el arreglo más rápido del código repetitivo suele ser _menos_ código, no más.

## Detected by

- **jscpd** `duplication threshold (--min-tokens / --threshold)` — Detección de copiar/pegar (umbral de tokens mínimos) (https://github.com/kucherenko/jscpd)
- **SonarQube / SonarCloud** `typescript:S4144` — Las funciones y los métodos no deben tener implementaciones idénticas (https://rules.sonarsource.com/typescript/RSPEC-4144/)
- **SonarQube / SonarCloud** `typescript:S1192` — Los literales de cadena no deben duplicarse (https://rules.sonarsource.com/typescript/RSPEC-1192/)
- **SonarQube / SonarCloud** `javascript:S1871` — Dos ramas de una estructura condicional no deben tener exactamente la misma implementación (https://rules.sonarsource.com/javascript/RSPEC-1871/)
- **ESLint (eslint-plugin-sonarjs)** `sonarjs/no-identical-functions` — Las funciones no deben tener implementaciones idénticas (https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-functions.md)
- **ESLint (eslint-plugin-sonarjs)** `sonarjs/no-duplicate-string` — Los literales de cadena no deben duplicarse (https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-duplicate-string.md)
- **ESLint (core)** `no-useless-constructor` — Constructor vacío redundante / código repetitivo de paso directo (https://eslint.org/docs/latest/rules/no-useless-constructor)
- **ESLint (core)** `max-lines-per-function` — Longitud de función inflada/verbosa (indicador parcial) (https://eslint.org/docs/latest/rules/max-lines-per-function)
