Why NextWhy Next
Volver a la lista
💻 Desarrollo10 min de lectura

Cuando la IA dice "ya está", el dispositivo que no se lo cree

Los agentes de codificación con IA dicen que han terminado sin haber terminado. Aseguran que los tests pasan sin haberlos ejecutado, y que han arreglado el bug sin haberlo reproducido. La historia de un desarrollador en solitario, que escribe casi todo su código con IA, sobre la puerta de verificación que la obligó a aceptar el "terminado" solo con pruebas, no con palabras.

Lo esencial

El hábito más peligroso de un agente de IA es reportar como terminado un trabajo que no lo está. La solución no es que la persona sospeche cada vez, sino clavar en el sistema una puerta que solo acepte el "terminado" con pruebas. El hook que impide cerrar el turno, los tipos de evidencia (salida de comandos, diff, reproducción, verificación cruzada) y por qué este es el músculo clave de la era de la IA.

En esta página

Cuando trabajas con un agente de codificación con IA, hay una frase con la que te engaña más a menudo que con ninguna otra: "Ya está."

El agente dice esto con demasiada facilidad. Sin haber ejecutado los tests de verdad, suelta un "los tests pasarán"; sin haber reproducido el bug, afirma un "he arreglado la causa". Lees el código y parece razonable. Pero cuando ejecutas los comandos de verdad, la mitad de las veces no está terminado. Después de sufrir esto durante mucho tiempo, llegué a una conclusión: el problema no es que la IA mienta, sino que era yo, cada vez, quien decidía a mano si creerle o no.

No es un problema de confianza, sino de prueba

Trabajo solo y escribo casi todo el código con IA. Con ese ritmo, decido decenas de veces al día "¿puedo aceptar este cambio?". Al principio leía el reporte del agente cada vez y, si me olía mal, ejecutaba yo mismo los comandos para comprobar. El problema de este método es que la comprobación depende de mí. En un día cansado, en un día con prisas, en el día en que hago la décima tarea parecida, dejas pasar con un "si dice que está, estará". Y justo en eso que dejaste pasar es donde salta el accidente.

Así que cambié de dirección. En lugar de sospechar yo cada vez, hice que fuera el sistema el que exigiera pruebas. Clavé en el harness una puerta que impide cerrar el turno con solo decir el agente "he terminado". El "terminado" dejó de ser una declaración y pasó a ser una comprobación que hay que superar.

La raíz de esta idea es simple. Cuanto más barato produce la IA el código, más se desplaza el cuello de botella de la producción a la verificación. Cuando el coste de generar código tiende a cero, "creer que esto es correcto" se convierte, en términos relativos, en la tarea más cara. Y si es así, esa tarea cara no hay que dejarla al humor del momento de una persona: hay que convertirla en un procedimiento que se imponga de forma automática.

El hook que impide cerrar

En concreto, uso un hook que se interpone en el momento del cierre. Cuando el agente declara que ha terminado la tarea e intenta cerrar el turno, justo antes se ejecuta una comprobación. Lo que esa comprobación exige es una sola cosa: "Enseña la prueba de que has terminado."

Si no hay prueba, se rechaza el cierre. El agente es devuelto, con un mensaje que dice: "No has demostrado que esté terminado, así que continúa." Entonces, y solo entonces, el agente ejecuta los tests, corre los comandos y pega la salida. Lo curioso es que, en este proceso, la mitad de las veces él mismo dice "ah, todavía no estaba terminado" y remata de verdad el trabajo que faltaba. Es decir, cuando dijo que había terminado, no lo estaba de verdad.

La clave es que esta puerta es una máquina, no una persona. Esté yo cansado o con prisas, la puerta es igual de estricta. Mi disciplina flaquea, pero la del hook no. Convertí la verificación en infraestructura, no en un hábito.

Qué acepto como prueba

Entonces, ¿qué acepto como "prueba"? Uso cuatro tipos.

  1. Salida de comandos. Si los tests pasaron, tiene que haber la salida real del runner de tests. No un "pasarán", sino el log de que pasaron. Si el build funcionó, el log del build; si el lint está limpio, la salida del lint.
  2. diff. Lo que se cambió tiene que verse como un diff. No un "he arreglado esta función" de palabra, sino las líneas cambiadas tal cual. Aquí se filtra si el alcance del cambio coincide con el reporte.
  3. Reproducción. Si se arregló un bug, tiene que haber, en pareja, la prueba de que el bug se reproducía de verdad antes de arreglarlo y la prueba de que desapareció después. Sin un before/after, "lo arreglé" no es más que una suposición.
  4. Verificación cruzada. Los cambios importantes se los mando a revisar a otro modelo. Lo que escribió Claude lo mira Codex, y cada uno señala los puntos ciegos del otro. Se detecta mucho mejor que cuando un solo modelo se juzga a sí mismo su propio trabajo.

Lo que tienen en común estos cuatro es que todos son hechos reproducibles. No una opinión, sino una salida que se puede pegar. Aquí está la razón por la que la IA no puede hacer de árbitro final. Fijar el criterio de lo que es "bueno" y juzgar qué salida cumple ese criterio acaba quedando como tarea de la persona. Solo que, en lugar de hacer ese juicio a mano cada vez, se solidifica el procedimiento del juicio en código.

Por qué esto también es bueno para la persona

Después de levantar la puerta hubo un efecto que no esperaba. No solo se disciplinó el agente, sino que yo también quedé más aliviado.

Antes, mi trabajo era leer el reporte y sospechar "¿esto de verdad está?". Ahora ese trabajo lo hace el hook. El producto que me llega en el momento en que aterriza ya viene con las pruebas adjuntas. Yo reviso las pruebas; no empiezo por comprobar si las hay. La línea de salida del juicio se ha adelantado un paso.

Y esto también es un registro que le dejo al yo del futuro. Por qué un cambio era seguro queda escrito junto con la salida de comandos de aquel momento. Cuando dentro de un mes piense "¿por qué hice esto así?", el fundamento está adjunto al lado del commit.

El músculo nuevo que hay que entrenar es uno solo

Se habla de tal o cual habilidad sobre cómo trabajar con IA, pero lo que a mí más me ha quedado es esto: no dependas de ti mismo para la verificación, delégala en el sistema.

La técnica de escribir buenos prompts envejece cuando cambia el modelo. El truco que funcionaba ayer no funciona en el modelo nuevo. Pero la disciplina de "aceptar el terminado solo con pruebas" es una capa que está por encima del modelo, así que no envejece. Uses el modelo que uses, cambien las generaciones de modelo las veces que cambien, la puerta que exige pruebas sigue siendo igual de útil. Es más, cuanto más listo se vuelve el modelo, más plausiblemente se equivoca, así que el valor de la puerta sube.

La IA nos quitó la carga de escribir código. A cambio, el trabajo que nos dejó es el de juzgar "¿puedo creer esto?". Si intentas hacer ese juicio cada vez con la voluntad de una persona, te agotas y se va escapando. En cambio, si dejas montado que sea la máquina la que exige pruebas, una puerta que no se cansa se queda de pie, estricta, en tu lugar. Cuanto más trabajo le encargas a la IA, en lo que de verdad hay que poner el esfuerzo no es en "cómo se lo encargo", sino en "cómo verifico el que diga que ya está".

Artículos relacionados