Volver a las novedades

¿Cómo verificar que un agente de IA hizo lo que dijo que hizo?

La respuesta: verifica la afirmación en una fuente que el agente no controla y, antes de eso, pregunta si la acción que dice haber hecho deja un registro duradero o solo un último estado. El 15 de agosto de 2026 auditamos las 15 afirmaciones más recientes de nuestro propio agente sobre actuar fuera de su servidor. Diez se sostienen al verificarlas en la fuente. Cinco no pueden verificarlas ni nosotros ni nadie, porque la fuente guarda solo el evento más reciente y sobrescribe el resto. Ninguna de las 15 se mostró falsa, y cinco de ellas nunca podrían serlo, que no es el mismo resultado.

Esa distinción es la que cambió nuestra forma de trabajar. Entramos esperando atrapar una mentira y salimos con algo más útil: toda una clase de afirmación de agente que es inauditable por construcción, y que se parece exactamente a una afirmación que sí podrías verificar.

¿Qué significa verificar el informe de un agente de IA de programación?

Verificar el informe de un agente de IA de programación significa confirmar, en un sistema donde el agente no tiene permiso de escritura, que el efecto que describió ocurrió de verdad. Es una actividad distinta de leer su código. Cuando un agente como Claude Code, Codex o Cursor termina una tarea, su salida suele traer dos tipos de afirmación, y solo uno es un diff. "Refactoricé el parser" apunta a código que puedes leer. "Ejecuté la suite de pruebas", "subí la rama", "reinicié el servidor de desarrollo", "abrí el pull request" y "envié la notificación" apuntan a eventos en el mundo, y el diff no dice nada sobre ellos.

El segundo tipo es donde la confianza se acumula en silencio. Revisar un diff es un hábito que la industria ya tiene, con herramientas y cultura alrededor. Auditar una afirmación sobre una acción ejecutada no tiene ni lo uno ni lo otro, así que la frase del agente suele ser el único artefacto que alguien mira. Un comentarista de Hacker News, escribiendo el 15 de agosto de 2026, resumió la falla así: sin saber escribir el software tú mismo no puedes juzgar el resultado, y entonces el sistema afirma que las metas se cumplieron y que las pruebas pasan mientras el humano que lo conduce solo empuja otro pull request. En el original:

You have to be able to write the software yourself in order to judge the results and get good software out. Otherwise the system claims the goals are met, the tests pass, and the human driving the system puts up a new PR.

Así que la pregunta práctica no es si el agente es sincero. Es cuáles de sus frases están atadas a una fuente que puedes consultar, y de qué es capaz de acordarse esa fuente.

Por qué el registro del propio agente no es evidencia

El registro del propio agente es el relato de lo que creyó haber hecho, producido por el mismo proceso que lo hizo, lo que lo convierte en descripción y no en confirmación. Si la acción falló en silencio, el registro va a seguir diciendo que salió bien, porque se escribe desde la intención y desde una respuesta que el agente pudo haber leído mal.

Lo aprendimos en la dirección menos cómoda. Nuestra tubería de contenido mantiene un diario y, el 15 de agosto de 2026, una ejecución leyó la entrada de una ejecución anterior que afirmaba un cross post a dev.to, fue a verificar si ese post existía, concluyó que no, y registró que la entrada anterior era falsa. La acusación estaba equivocada. El post estaba publicado desde las 11:04:24 UTC de esa mañana. Lo que había fallado era el método de verificación, no el diario, y el costo fue real: actuando sobre la conclusión equivocada, esa ejecución publicó un segundo cross post y reventó la cuota del día.

La lección va más allá de nuestro caso. Cuando el informe del agente y tu verificación no coinciden, hay tres candidatos al error y la mayoría solo considera uno. El agente puede estar equivocado, la fuente puede estar mintiendo por omisión, o tu consulta puede estar haciendo la pregunta equivocada. Asumimos el primero y era el tercero. Antes de tratar la afirmación de un agente como falsa, reproduce la verificación con otra consulta contra la misma fuente, porque un método de verificación no tiene más autoridad que el agente al que audita.

¿Qué afirmaciones de un agente se pueden verificar?

La afirmación de un agente puede verificarse cuando el efecto que describe deja registro duradero, y no puede verificarse cuando el efecto solo actualiza un último estado. Esta distinción decide todo lo que viene después, y conviene ordenar las afirmaciones antes de escribir cualquier herramienta.

Registro duradero significa que la acción crea un objeto que persiste y lleva identificador propio: una página publicada que sigue devolviendo 200, un post con slug permanente, un commit alcanzable por SHA, una ejecución de CI con identificador, un artefacto publicado con checksum. Puedes pedirlo por su nombre dentro de años. Último estado significa que el sistema guarda solo la ocurrencia más reciente: el envío de un sitemap, una invalidación de caché, el reinicio de un servicio, un webhook disparado contra un endpoint que no guarda bandeja de entrada. La acción deja marca, pero la marca la sobrescribe la siguiente, así que responde "cuándo pasó esto por última vez" y nunca responde "¿pasó el martes?".

Aplicada a un agente de IA de programación, esta separación clasifica una sesión normal en segundos. "Subí el código" es duradero, porque el remoto tiene el SHA. "Abrí el pull request" es duradero, porque el pull request tiene número. "Ejecuté las pruebas" solo es duradero si la ejecución ocurrió en algún lugar que guarda registro de ejecución, y fuera de eso es puro último estado, y por eso es la frase inverificable más repetida de la categoría. "Reinicié el servicio" es último estado en casi todas partes. Una afirmación de la segunda columna no es mentira. Es una frase que ninguna diligencia posterior puede ascender a evidencia, y la única corrección es hacer que la acción deje registro antes de ejecutarse.

¿Qué devolvió la auditoría de nuestro propio agente?

Nuestra auditoría devolvió 10 verificadas de 15, y las cinco que quedaron fuera fallaron todas por el mismo motivo estructural. El objeto fue el diario de nuestra tubería de contenido: de sus 100 entradas más recientes, 15 afirman un efecto fuera del servidor que las guarda, registradas entre el 14 de agosto de 2026 a las 00:14 UTC y el 15 de agosto de 2026 a las 17:11 UTC. Escribimos lo que esperábamos encontrar antes de consultar nada, que es la única manera de que una auditoría pueda contradecir a quien la ejecuta.

Las seis afirmaciones de publicación verificaron 6 de 6. Cada una nombra un slug, y cada slug existe en tres idiomas, así que la verificación fueron 18 peticiones contra el sitio en vivo, todas devolviendo 200:

curl -s -o /dev/null -w '%{http_code}\n' "https://canvascode.app/es/news/undo-ai-coding-agent-changes"

Las tres afirmaciones de cross post verificaron 3 de 3, cada una presente con la URL canónica correcta apuntando de vuelta a nuestro sitio. Usamos el endpoint de cuenta /api/articles/me/all, que devolvió 401 sin clave de API y 200 con ella, en lugar del listado público, por razones que explica la siguiente sección.

Las seis afirmaciones de aviso de sitemap verificaron 1 de 6. La respuesta de Search Console para nuestro sitemap traía un único envío registrado, lastSubmitted en 2026-08-15T17:08:02.065Z, sin ninguno anterior al lado. Eso confirma el aviso más reciente y deja los otros cinco indistinguibles de avisos que nunca ocurrieron. La misma respuesta traía lastDownloaded en 2026-08-15T17:08:04.364Z, y ese campo es la mitad más interesante: dos segundos después de nuestro envío, Google descargó el archivo. Esa es la diferencia entre evidencia de que hablaste y evidencia de que el otro lado actuó, y es la confirmación más fuerte de esta lista.

¿Por qué una respuesta vacía de la API no prueba que el agente no hizo nada?

Una respuesta vacía de API no prueba ausencia porque un endpoint de listado responde a la pregunta que escribiste, no a la que quisiste hacer, y responde a una pregunta malformada con una nada segura y bien formada. Reprodujimos tres maneras distintas de ser engañados por la misma API de dev.to el 15 de agosto de 2026, y cada una devolvió HTTP 200.

La primera es identidad. Consultar el listado público con un nombre de usuario que no existe devuelve [] y estado 200. El nombre de nuestra marca no es nuestro identificador allí, y pedir por la marca produjo una lista vacía y limpia, que se parece exactamente a un agente que no publicó nada.

La segunda es caché por URL. Con el identificador correcto, el mismo endpoint devolvió totales distintos según un parámetro que solo debería ampliar la ventana:

curl -s "https://dev.to/api/articles?username=hassekf&per_page=30"

Eso devolvió 8 artículos, mientras que per_page=10, per_page=20 y per_page=50 devolvieron 10 cada uno. Ejecutamos los cuatro valores tres veces y el patrón fue idéntico todas las veces, así que no es inestabilidad, es una caché con clave en la URL completa. Un listado que encoge cuando pides más no sirve como censo.

La tercera es la corrección de las dos. Pedir el elemento por su identificador, /api/articles/hassekf/<slug>, devolvió 200 para el post cuya existencia habíamos negado por error ese mismo día. Ese endpoint no necesita clave; simplemente responde sobre una cosa nombrada en vez de enumerar. Cuando quieras saber si una cosa concreta existe, pide esa cosa por su nombre, y enumera solo cuando necesites un conteo.

Un contador que marca cero mientras la misma fuente informa 39 impresiones

La misma respuesta de Search Console que verificó nuestro aviso de sitemap traía también un número que casi publicamos como crisis. Junto a las marcas de tiempo del envío, el bloque de contenido informaba 579 URLs enviadas y 0 indexadas. Leído solo, eso dice que Google no ha indexado nada de lo que hemos escrito.

Lo contradice el mismo producto. Sacar el análisis de búsqueda de los 28 días anteriores de esa misma propiedad devolvió 23 consultas distintas y 39 impresiones, con 0 clics. Una página no puede mostrarse 39 veces en resultados de búsqueda estando ausente del índice, así que los dos números no pueden describir la realidad a la vez, y el que merece desconfianza es el contador, no el informe. Nuestro registro de visitantes coincide con el informe: guarda llegadas referidas desde google.com en la misma ventana.

Estamos diciendo lo que medimos y no por qué el contador se comporta así, porque no tenemos una fuente de Google que lo explique, e inventar una sería exactamente la falla de la que trata este artículo. La regla operativa que sacamos de aquí es más estrecha y no necesita la explicación: un campo aislado no es una medición mientras un segundo campo de la misma fuente no coincida con él. Un contador que contradice el informe de su propio producto es motivo para buscar el segundo campo, no para dar la alarma. Nosotros la habríamos dado.

La verificación que ejecutamos sobre nosotros mismos, y perdimos

Auditando a nuestro agente atrapamos una creencia nuestra que nunca había sido verificada, y vale contarlo porque es la misma falla en miniatura. Nuestras notas internas dicen que pedir páginas de canvascode.app con un script pelado es rechazado por la defensa contra sondeo que protege el sitio, así que toda verificación de esta auditoría se escribió con un User-Agent completo de navegador, por hábito y no por medición.

Durante esta auditoría por fin probamos el hábito, pidiendo la misma página de tres maneras: sin ninguna cabecera de User-Agent, con curl/8.7.1, y con una cadena de navegador. Las tres devolvieron 200. La precaución era innecesaria para este tipo de petición, y la nota que la justificaba no sobrevivió al contacto con un comando, y por eso ahora verificamos canvascode.app con curl puro, sin opción de User-Agent, y no con la cadena de navegador que usábamos por hábito.

La creencia no fue inventada. Vino de una observación real anterior, y la lectura que hacemos es que generalizamos un caso específico en regla y dejamos de probarla. Es exactamente lo que hace un agente cuando escribe "listo" en su registro: convierte una observación en hecho permanente. La diferencia entre nosotros y el agente, aquel día concreto, fueron tres segundos de curl.

¿Cómo hacer que el informe de un agente sea verificable antes de ejecutarse?

Haces verificable el informe de un agente exigiéndole que registre el identificador que le devolvió la fuente, en lugar del hecho de haber actuado. Es un cambio en las instrucciones que le das al agente, y cuesta cero en el momento de escribirlas, que es el único momento en que todavía es posible.

Tres exigencias cubren la mayor parte. Primera, el informe debe llevar un identificador que se pueda consultar de forma independiente: un SHA de commit, un número de pull request, un identificador de ejecución de CI, una URL publicada, un identificador de mensaje. "Subí la corrección" es inverificable; "subí 4f2a91c a origin/main" lo puede verificar cualquiera con el repositorio. Segunda, debe llevar la marca de tiempo de la fuente, no la del agente, porque el reloj del agente solo prueba cuándo creyó haber actuado. Tercera, debe incluir el comando o la llamada exacta que hizo, para que quien revise pueda repetir la verificación en vez de inventarse una, que fue justamente como ocurrió nuestra mala verificación.

Para acciones de último estado, la única opción honesta es crear el registro tú mismo. Si el agente reinicia un servicio, haz que capture enseguida la hora de arranque del nuevo proceso y la ponga en el informe. Si ejecuta pruebas localmente, haz que escriba el resumen en un archivo con marca de tiempo, o que las ejecute en algún lugar que guarde registro de ejecución. CanvasCode, nuestra aplicación de macOS para ejecutar varios agentes de IA de programación en un mismo lienzo, ayuda en la parte de esto que consiste en ver muchos agentes a la vez, y no resuelve este problema: un agente cuyo informe no lleva identificador dentro es inverificable por buena que sea tu vista de él. La corrección vive en lo que exiges que el agente anote, no en la herramienta con la que lo observas.

Lo que esta auditoría no prueba

Esta auditoría no prueba que los agentes de IA de programación informen con precisión de sus acciones, y la muestra es lo bastante pequeña como para que no defendamos ninguna tasa a partir de ella. Quince afirmaciones de un agente a lo largo de 41 horas es un estudio de caso. Tampoco prueba nada sobre las cinco afirmaciones no verificadas: no se mostró que fueran falsas, se mostró que son infalsables, que es un resultado distinto y, en cierto modo, peor.

La mayor limitación es lo que el agente auditado es. Nuestra tubería escribe y publica contenido; no es un agente de programación y no toca un repositorio. Lo que se traslada es la clasificación de las afirmaciones, no los números: publicar una página y subir un commit son acciones de registro duradero, y avisar un sitemap y reiniciar un servicio son acciones de último estado, pero nuestro 10 de 15 no dice nada sobre cuál sería la proporción de un agente de programación en tu repositorio. Nos gustaría ver a alguien ejecutar la misma auditoría contra el log de sesión de un agente de programación, porque el método es barato y el resultado es verificable.

Un punto más sobre el conteo. Contamos una afirmación como verificada cuando una fuente independiente confirmó el efecto, pero para las seis páginas publicadas la fuente independiente es nuestro propio sitio, en el que escribió nuestra propia tubería. Una auditoría más estricta las confirmaría en algún lugar que no sea nuestro, como un archivo de terceros. Todas las mediciones de este artículo se tomaron el 15 de agosto de 2026 con los comandos mostrados.