[ LJP ]
← todos los artículos

5 señales de AI slop en code review

Cómo identificar en 30 segundos si el dev leyó lo que mergeó o si le dio approve a ciegas al agente. Patterns que vemos en code reviews reales.

Existe un fenómeno nuevo en code review: PRs que compilan, pasan tests, no levantan linter, y aún así están claramente mal. Son output AI sin revisión humana. AI slop: lodo producido por agente, mergeado por developer apurado.

El reviewer entrenado en código humano no detecta slop fácilmente. Los olores son distintos. Aquí las cinco señales que aprendimos a buscar.

1. El “solo por si acaso”

try:
    result = expensive_call()
    if result is not None:
        if isinstance(result, dict):
            return result.get('key', default)
except Exception:
    pass

Tres niveles de defensa contra un input que el agente no validó. El humano hubiera revisado el tipo de expensive_call() y escrito “esto siempre devuelve dict”. El agente, sin contexto, se cubre en todas las posibilidades. Slop pattern: defensive coding sin información.

2. La función helper que ya existe

El PR introduce parseDateRange(start, end) que hace exactamente lo que ya hace dateRangeParser(start, end) en otro archivo del repo. El agente no lo encontró. El humano, en review, debería — pero no leyó suficiente código para detectarlo.

Slop pattern: duplicación que el agente no podía evitar y el reviewer no detectó. Fix: linter o convention de buscar helpers existentes antes de generar.

3. Comentarios que repiten el código

// Increment the counter by 1
counter += 1;

// Return the result
return result;

El humano escribe comentarios para explicar por qué, no qué. El agente, sin contexto del intent, llena con qué porque es lo único que puede inferir del código mismo. Si el comentario solo parafrasea, es slop.

4. Naming genérico-plus

Variables como data, result, temp, value, item. El humano nombra desde el dominio: prescriptionRow, cartTotal, patientPhone. El agente sin contexto nombra desde la mecánica: responseData, processedItems, mappedValues.

Si ves un PR con muchos nombres genéricos, el agente no tenía contexto suficiente — y el humano no lo agregó.

5. Tests que validan la implementación, no el comportamiento

it('returns 1 when input is 1', () => {
  expect(addOne(1)).toBe(1);  // bug: debería ser 2
});

El agente generó la implementación Y los tests al mismo tiempo. Si la implementación tiene un bug, los tests lo “confirman”. El humano debería haber escrito tests primero (TDD), o al menos pensado en qué deberían validar independientemente del código generado.

Slop pattern: tests que pasan no porque el código está bien sino porque test y código están de acuerdo. Catch: revisar tests con los ojos críticos de “¿esto pasaría si la implementación estuviera mal?”.

El sexto que es más sutil

Hay un sexto que no es señal de un PR sino de un equipo: resignación al slop. “Es que con IA todos los PRs salen así ahora”. No. Los PRs salen así cuando el equipo NO está haciendo review crítica. Es respuesta cultural, no inevitabilidad técnica.

Lo que sí funciona

Tres prácticas que vemos en equipos con poco slop:

Pregunta al reviewer: “¿podrías defender cada decisión de este PR en una whiteboard ahora mismo?”. Si no, no apruebes — pide clarificación al autor.

Pull request descriptions con intent: el autor declara qué decidió y por qué, antes de mostrar cómo. “Decidí cachear esto en memoria en lugar de Redis porque…”. Si la descripción es “implementé feature X”, eso ya es señal.

Linter custom para los patterns de arriba: detecta nesting defensivo excesivo, naming genérico, comentarios redundantes. Block PRs que tengan demasiado.

La pregunta para tu última review

¿Cuándo fue la última vez que rechazaste un PR pidiendo al autor “explícame por qué tomaste esta decisión”?

Si la respuesta es “no me acuerdo”, tu equipo ya tiene slop mergeado. Y mañana tendrá más. La review crítica es el único filtro real.


Si tu equipo está adoptando AI coding y quieren establecer practices de review que filtren slop, conversemos — el chat está abierto.