QA con IA:
cuando mirar no es lo mismo que probar
Un agente de IA revisó un mini-juego, sacó capturas de cada escenario y llegó a una conclusión segura sobre un bug. La conclusión estaba mal. Esto es lo que reveló sobre la diferencia entre un agente que prueba y uno que solo mira.
"Usá un agente de IA para hacer QA" suena, dicho así, a que le pedís que corra tu app, mire si algo tira error, y te avise. Eso no es QA, es un linter con más pasos. La diferencia entre un agente que efectivamente prueba tu producto y uno que solo simula hacerlo se ve mejor en un caso chico que en una charla teórica. Este es uno real, con el veredicto equivocado incluido.
El punto de partida: un reporte, no una hipótesis
Un jugador de un mini-juego interno reportó algo puntual: el enemigo dispara y el proyectil parece salir de su cuerpo, no del arma. Nada crítico. Pero un agente al que le pedís "arreglá esto" tiene dos caminos frente a un reporte así.
El primero es mover el punto de disparo hasta que "se vea bien" contra la descripción del síntoma. Rápido, y frágil: funciona para esa pose puntual y se rompe apenas hay otra dirección o postura de por medio.
El segundo es reproducir el reporte primero, con el mismo estado que describió el jugador, y recién ahí decidir qué tocar. En este caso, activar al enemigo en cada una de sus posturas (parado, agachado, saltando, mirando a cada lado) confirmó el síntoma en las seis combinaciones a la vez: el disparo nacía siempre en el centro exacto del sprite, sin importar hacia dónde miraba.
Antes de dejar que un agente toque código en respuesta a un reporte, la pregunta no es "¿lo arregló?". Es "¿reprodujo el problema, con el mismo estado real, antes de tocar nada?". Un fix sin reproducción es una apuesta con vocabulario técnico.
Medir, no mirar
Con el síntoma confirmado, la tentación es ajustar el offset a ojo hasta que la captura se vea razonable. Un agente de IA es particularmente bueno para caer en esta trampa: genera un número que parece razonable, lo aplica, saca una captura, y la captura se ve bien. Nada de eso prueba que el número sea correcto.
Lo que sí prueba algo es medir contra la fuente real. En este caso, la punta del arma del sprite: no un valor estimado, sino el borde real de píxeles no transparentes en cada una de las seis imágenes del enemigo, medido una sola vez con un script corto. El resultado fueron seis números concretos, entre 55 y 64 píxeles de offset según la postura y dirección, calculados contra el archivo real, no contra la impresión visual de una captura.
Ese número se verificó de nuevo con un log temporal en el punto exacto donde se genera el disparo, no con otra captura: hkx: 370, muzzleX: 306.36. Comparado a mano contra la fórmula, coincide. Un fix se prueba con un dato, una captura solo lo ilustra.
El punto ciego que casi nadie revisa: ¿el reloj corrió de verdad?
Acá está la parte que vale la pena contar, porque el agente llegó a una conclusión segura, medible, y equivocada.
Con el bug del disparo resuelto, tocaba la pregunta obvia: ¿hay algo más así? Un barrido automatizado recorrió cada tipo de obstáculo y cada postura de enemigo del juego, sacando una captura de cada escenario. Una de esas capturas, la de un efecto de fuego, mostraba apenas una mancha tenue en el piso en lugar de una llamarada completa.
La conclusión inicial, mirando el código del efecto, fue: la opacidad decae en línea recta desde el instante en que se enciende, así que para cuando el jugador todavía tiene margen para reaccionar, el efecto ya casi no se ve. Sonaba a un problema real de percepción, y el código parecía confirmarlo.
Estaba mal. El barrido nunca movía al personaje, y la aplicación tiene una regla explícita: el reloj interno completo (temporizadores, física, cuentas regresivas) queda congelado hasta que hay un primer movimiento real. Lo que se dibuja en pantalla sí se actualiza siempre, así que la escena se veía "viva" en la captura. Pero el efecto de fuego nunca había tenido la chance de avanzar ni un milisegundo: la mancha tenue no era un efecto apagándose, era un efecto que nunca había empezado.
Una prueba automatizada que corre, no tira error y produce una captura de pantalla da la sensación de haber verificado algo. Acá estaba verificando el estado inicial congelado del sistema, no su comportamiento a lo largo del tiempo. Un agente de IA es especialmente propenso a esto: entrega una conclusión con seguridad, con números, con una captura de respaldo, y esa seguridad no dice nada sobre si el reloj de la aplicación estaba realmente corriendo cuando se tomó el dato.
La forma de destrabarlo fue forzar que el reloj corriera de verdad (un toque real de movimiento) y volver a medir, esta vez muestreando el estado cuadro por cuadro en vez de una sola captura estática. Ahí apareció el dato correcto: el efecto sí llegaba a su punto máximo rápido y se mantenía así durante la mayor parte de su vida, con un fundido final mal calibrado en el último tramo, mucho más chico y puntual que la hipótesis inicial. El arreglo real fue mínimo. Lo que valió la pena fue descartar la conclusión seria y bien fundamentada antes de aplicarla.
El prompt real detrás de esto
Nada de este proceso salió de un solo pedido mágico. Salió de una cadena de instrucciones concretas, cada una más específica que la anterior, no de "hacé QA" a secas:
1. "Verificá que el disparo del enemigo siempre salga de su arma, no de su cuerpo" 2. "Hacé de QA ahora, revisá todo para arreglar" 3. "Confirmá el fix con datos, no con una captura"
El primer pedido es acotado: un síntoma puntual, un componente puntual. El agente lo puede reproducir y medir sin ambigüedad. El segundo es deliberadamente amplio, "revisá todo", y ahí es donde un agente sin estructura tiende a mirar por arriba y decir que está todo bien. La diferencia no la puso el modelo, la puso pedirle explícitamente un barrido sistemático (cada obstáculo, cada pose, cada modo) en vez de una revisión genérica, y exigir que cada hallazgo se cerrara con un dato verificable antes de darlo por bueno.
Esa secuencia (reproducir → medir contra la fuente real → verificar con instrumentación → barrer sistemáticamente → confirmar con datos, no con capturas) es exactamente el tipo de proceso que conviene dejar de repetir a mano cada vez. Dos formas concretas de hacerlo, si trabajás con Claude Code:
- Empaquetarlo como Skill. Una Skill es justamente esto: un archivo de instrucciones reutilizable que le dice al agente, sin que se lo repitas, "cuando te pida QA, reproducí primero, medí contra la fuente real, después verificá con un log o assert, y recién ahí barré el resto de los escenarios". Una vez armada, "hacé de QA" ya no depende de que te acuerdes de pedir cada paso por su nombre.
- Correrlo con un
/loop. El barrido sistemático (nueve tipos de obstáculo, cuatro poses de enemigo, cada modo especial) no tiene por qué esperar a que alguien reporte algo. Ese mismo barrido corriendo en un intervalo, antes de cada deploy o cada tanto en producción, convierte el QA reactivo ("un jugador reportó") en QA que corre solo y avisa antes de que alguien más lo note.
Cuatro preguntas antes de confiar en el veredicto de un agente de QA
Ninguno de los dos bugs de este caso era grave. Pero son exactamente el tipo de falla que, en un flujo de pagos o un panel con datos reales, deja de ser cosmética. Antes de aceptar el "todo probado, cero errores" de un agente automatizado, cuatro preguntas concretas:
- ¿Reprodujo el reporte con el estado real, o ajustó contra la descripción del síntoma? Si no hay reproducción, no hay diagnóstico, solo un parche con buena redacción.
- ¿El resultado se verificó con un dato medible, o con una captura que "se ve bien"? Una captura confirma una impresión. Un log, un valor calculado contra la fuente real, confirma un hecho.
- ¿La prueba automatizada ejercitó el sistema en marcha, o solo su estado inicial? Correr sin errores no es lo mismo que haber puesto a prueba el comportamiento real a lo largo del tiempo.
- ¿Alguien intentó romper la conclusión antes de aceptarla? La hipótesis inicial sobre el efecto de fuego sonaba sólida y estaba mal. Se descartó porque alguien volvió a medir con el reloj corriendo, no porque "sonaba razonable".
Un agente de IA puede correr estas cuatro verificaciones perfectamente bien. La parte que no delega es la desconfianza: la costumbre de volver a medir una conclusión que ya vino con números y capturas de respaldo, en vez de aceptarla porque se ve completa.
El enfoque directo y el hábito de cuestionar cada conclusión de este artículo se los debo a Adriana Troche Robles, que escribe sobre ingeniería de QA en calidadsinhumo.com. Si te interesa QA en serio, vale la pena seguirla.