DEV Community

Cover image for Cómo saber si el agente hizo lo que dice que hizo
Guillermo Leyendeker
Guillermo Leyendeker

Posted on • Originally published at leyendeker.com

Cómo saber si el agente hizo lo que dice que hizo

La segunda semana de abril el pipeline ya producía. Un agente elegía la tarea, otro la implementaba, y el sistema la marcaba como terminada. Todo funcionaba, en el sentido de que ningún paso devolvía error.

Ese era exactamente el criterio: si el paso anterior corrió sin error, la tarea está hecha. Escrito así suena razonable. En la práctica significaba que el sistema le estaba tomando declaración al sospechoso.

Un agente puede terminar su corrida sin ningún error y no haber tocado una sola línea de código. Puede haber explorado el repositorio, razonado sobre el problema, redactado un resumen convincente de lo que haría, y cerrar. El proceso termina con código de salida cero. El sistema, mirando solamente eso, lo da por implementado.

El 12 de abril agregué la primera prueba de implementación

La idea era sencilla y cambió el sistema entero: para marcar algo como hecho hay que encontrar evidencia en el repositorio. No leer una afirmación en la salida del agente. Buscar commits.

Parece un detalle menor. No lo es, porque invierte la carga de la prueba. Antes el sistema asumía que el trabajo estaba hecho salvo que algo fallara. A partir de ese día, asumía que no lo estaba hasta que apareciera un cambio real en el código.

Tres días después endurecí un poco más el criterio: el control de calidad, que hasta entonces era un paso que se podía saltear, pasó a ser obligatorio entre la implementación y el cierre. Ya no era una verificación opcional que corría cuando yo me acordaba. Sin control aprobado, la tarea no se cerraba.

Los agujeros que aparecieron después

Lo interesante de este problema es que no se resolvió con esos dos cambios. Se resolvió —parcialmente— a lo largo de cuatro meses, y cada agujero que tapé me enseñó algo sobre la diferencia entre verificar y aparentar que verificás.

A principios de mayo agregué un control que compara los archivos que la especificación declaraba que había que tocar contra los que efectivamente cambiaron en los commits. Porque encontrar "un commit" no alcanza: el agente puede haber commiteado algo, en algún lado, que no tiene nada que ver con lo que se le pidió.

Ese mismo día apareció un caso que no había anticipado: un control de calidad viejo certificando trabajo nuevo. La tarea había pasado el control en un intento anterior, después se modificó, y el veredicto guardado seguía diciendo que todo estaba bien. La regla que agregué fue exigir un control reciente antes de marcar nada como hecho.

Y hubo un problema de alcance, más aburrido pero igual de importante: la búsqueda de commits solo miraba el repositorio principal. Como los cambios se reparten entre el backend y los distintos frontends, había implementaciones perfectamente reales que el sistema no encontraba, y tareas que quedaban trabadas sin motivo. Hubo que extender la búsqueda a todos los repositorios del espacio de trabajo.

Cuatro meses después, el problema sigue apareciendo

Esta es la parte que menos esperaba cuando empecé.

El 3 de agosto —casi cuatro meses después del primer control— encontré un caso nuevo: el control estaba certificando tareas que en realidad nunca había mirado. No es que fallara la verificación; es que en cierto camino del código la verificación no llegaba a ejecutarse y el resultado quedaba, por omisión, como aprobado.

Ese es el tipo de error que más me preocupa, porque no se ve. Un control que falla hace ruido. Un control que no corre y devuelve verde es indistinguible de uno que corrió bien, salvo que vayas a buscarlo específicamente.

Nueve días más tarde di el último paso hasta ahora: la etapa de implementación de cada tarea dejó de declararse por lo que el sistema cree y pasó a derivarse de la evidencia de cambios ya verificada. Es decir, el estado ya no es algo que se escribe cuando un paso termina; es algo que se calcula a partir de lo que se puede comprobar.

Si miro la historia completa del proyecto, esta es la única línea de trabajo que atraviesa los cuatro meses de punta a punta. Todo lo demás tuvo un principio y un final. Esto no.

Por qué es el problema más difícil del rubro

Creo que hay una razón de fondo, y es que confiar es el comportamiento por defecto de casi cualquier sistema que orqueste agentes.

Cuando conectás un modelo a un pipeline, lo que tenés naturalmente disponible es el resultado del proceso: terminó, no terminó, tiró error. Construir la verificación real —ir al repositorio, buscar commits, cruzar archivos contra la especificación, confirmar que el control corrió sobre esta versión y no sobre otra— es trabajo extra que nadie te pide y que no se nota cuando funciona.

Se nota cuando no está. Y se nota tarde, que es lo peor: una tarea mal cerrada no genera un error, genera una base falsa sobre la que se apoyan las siguientes. El costo aparece semanas después, cuando algo que dependía de eso no funciona y nadie entiende por qué.

Por eso lo que aprendí de estos cuatro meses no es una técnica sino un criterio: la confianza en un agente no se configura, se construye con evidencia externa a él. Y la evidencia útil no es que el proceso haya terminado sin error. Es que existan commits, con archivos concretos, que se correspondan con lo que se pidió, verificados después de la última modificación.

Todo lo demás es tomarle declaración al sospechoso.

Lo que esto habilitó

Con el sistema capaz de detectar que un trabajo estaba mal, quedó expuesta la pregunta siguiente, que era bastante más incómoda: ¿y ahora qué hago con eso?

Por entonces, un veredicto negativo simplemente frenaba la cadena y me esperaba a mí. El agente había fallado, el control lo había detectado, y el sistema se quedaba quieto hasta que yo apareciera a mirar qué había pasado.

Un pipeline que necesita que vos estés mirando no sirve de mucho. De eso trata la próxima entrega: qué hace el sistema cuando el agente falla, y cómo decidir entre insistir, cambiar de enfoque o abandonar.

Top comments (0)