Saltar al contenido
Volver a todas las notasruntime · 10 min

Cómo escribir un AGENTS.md que los agentes sigan de verdad

Las comparativas te dicen qué fichero usar. Nadie te dice dónde ponerlo, qué forma tiene, ni por qué la mitad de las líneas que escribiste se ignoran en silencio.

nota de campo10 min

Escribiste un AGENTS.md. El agente lo leyó y luego editó igualmente un fichero generado, o lanzó el comando de tests equivocado, o reformateó un módulo que habías vallado de forma explícita. Así que añadiste una línea. La siguiente ejecución se saltó otra distinta. Ahora el fichero tiene doscientas líneas escritas de buena fe y has dejado de creer que alguna sostenga peso.

No es que el agente sea descuidado. Casi todos los AGENTS.md que he leído, varios míos incluidos, están escritos como si el lector fuese un compañero nuevo que preguntará cuando algo suene ambiguo. Este lector no pregunta nunca. Rellena el hueco con algo plausible y sigue, que es el mismo fallo que aparece en cualquier otro sitio donde le das a un agente un contrato incompleto.

Lo que esta pieza no vuelve a discutir

Hay una discusión real sobre qué decisiones deben vivir en un fichero de reglas, y ya tiene su sitio en dónde deberían vivir tus decisiones. La versión comprimida: los hechos operativos sobre cómo funciona el repo van al fichero de reglas, y las decisiones de producto con sus porqués van a un contrato que viaja. Los procedimientos que solo aplican a veces son otro canal con otro coste, y los invariantes que un agente tiene que ver antes de escribir nada son una categoría aparte.

Damos por hecho que ya has decidido que una línea va en AGENTS.md. Esto va de cómo escribirla para que sobreviva a una ejecución.

Ponlo donde el agente ya está mirando

AGENTS.md es un fichero Markdown normal en la raíz del repositorio, y para un proyecto de un solo paquete ahí acaba la cuestión de dónde ponerlo.

Los monorepos son donde la gente falla, y el error es escribir un único fichero raíz que intente describir todos los paquetes. Crece más allá de la longitud a la que algo se cumple y, peor todavía, casi todo su contenido es irrelevante para cualquier tarea concreta. Un agente que trabaja en el paquete de la API dedica atención a instrucciones de build del cliente móvil sin ningún motivo.

Anidar es la respuesta soportada, y el estándar lo dice de forma explícita: «Large monorepo? Use nested AGENTS.md files for subprojects», con la instrucción de «Place another AGENTS.md inside each package.» Pon uno corto en la raíz para lo que es cierto en todas partes y otro dentro de cada paquete para lo que solo es cierto ahí. Fichero raíz: versiones de lenguaje, herramienta del monorepo, convenciones de commit, directorios que nadie debe tocar. Fichero de paquete: cómo se construye este paquete, cómo se lanzan sus tests, qué no puede importar. Cuando un agente trabaja dentro de packages/api, el fichero que tiene al lado es el que describe el código que está editando.

La regla de conflicto conviene conocerla antes de necesitarla, porque decide cómo repartes el contenido. Según el FAQ del estándar, «The closest AGENTS.md to the edited file wins; explicit user chat prompts override everything.» O sea que un fichero de paquete no necesita repetir el de la raíz para ganarle en su terreno, y nada de lo que escribas en ninguno de los dos sobrevive a una instrucción directa en la sesión. Esa segunda mitad recuerda algo útil: un fichero de reglas fija valores por defecto, no garantías.

La regla que evita que esto se convierta en su propio problema de mantenimiento es que cada hecho viva en un solo fichero. Si el de la raíz y el del paquete explican los dos cómo lanzar los tests, uno de ellos estará equivocado dentro de un mes, y no te enterarás de cuál hasta que un agente lo siga. Es el mismo mecanismo de deriva que hace que los ficheros de reglas empiecen a mentirte, y duplicar es la forma más rápida de dispararlo.

La forma, y por qué el orden no da igual

Con cuatro secciones se cubre casi todo, y el orden importa porque los agentes, igual que las personas, pesan más lo de arriba que lo de abajo.

Los comandos van primero. Cómo instalar, cómo construir, cómo lanzar los tests, cómo lanzar un test suelto. Son las líneas que un agente necesita en casi cualquier tarea y aquellas donde equivocarse sale más caro, porque un comando de tests erróneo produce un éxito declarado con nada detrás.

Los límites van segundos. Qué no se toca, qué no se importa, qué está generado y se sobrescribirá. Los límites valen más que las instrucciones cuando lo que los lee puede generar código plausible a toda velocidad, y son la sección que la gente escribe la última y más corta.

Las convenciones van terceras. Nombres, manejo de errores, los patrones que este repo ha decidido. Es la sección que se hincha y la primera que hay que recortar cuando el fichero se alarga.

La estructura va al final. Dónde vive cada cosa. Es útil de verdad y a la vez la menos urgente, porque un agente puede descubrir casi toda la estructura leyendo, mientras que tu comando de tests no lo descubre leyendo.

Cada línea tiene que poder ser falsa

Es la prueba que más ha cambiado mis propios ficheros de toda esta lista.

Coge cada línea y pregúntate si algo del repositorio podría demostrar que es falsa. «Lanza pnpm test antes de decir que está hecho» puede ser falsa, porque pnpm test existe o no existe. «Las migraciones viven en db/migrate» puede ser falsa, porque esa ruta resuelve o no resuelve. Las dos son comprobables, y un agente puede actuar sobre ellas sin interpretar nada.

Ahora las del otro tipo. «Escribe código limpio y mantenible.» «Sigue las buenas prácticas.» «Ten cuidado con el módulo de auth.» Nada del repositorio podría contradecir jamás estas frases, así que el agente no puede distinguirlas de una preferencia y las tratará como tal. Son justo las líneas que estabas seguro de haber dejado escritas, y son la razón de que te sientas ignorado.

«Ten cuidado con el módulo de auth» empieza a servir en cuanto dices qué significa cuidado: no cambies la caducidad de sesión, no añadas dependencias a ese paquete, lanza la suite de integración de auth antes de decir que está hecho. Son tres líneas comprobables sustituyendo a una aspiración, y ocupan más, lo que nos lleva al techo.

El techo de longitud, y cómo respetarlo

Un fichero de reglas se carga en cada llamada, así que cada línea es presupuesto que gastas en turnos que no la necesitaban. Ese es el coste mecánico. El de forma humana es peor: pasada cierta longitud el fichero deja de leerse con cuidado y empieza a leerse en diagonal, por parte de los agentes tanto como de las personas.

Apunto a algo que una persona leería sin bajar más de una o dos pantallas, y trato el cruzar esa raya como una señal, no como un fracaso. Cuando un fichero raíz se alarga, el contenido casi siempre quiere mudarse antes que encogerse. Los hechos de un paquete quieren su propio fichero. Un procedimiento que aplica a un tipo de tarea quiere ser una skill. Una decisión con su razonamiento quiere estar en la spec, donde puede llevarse el porqué que un fichero de reglas comprime hasta hacerlo desaparecer.

Podar no es ordenar. Cada regla que borras es una cosa menos que un agente puede aplicar mal, y las reglas caducadas hacen más daño que las que faltan, porque una regla que falta produce una pregunta y una caducada produce trabajo equivocado hecho con seguridad.

Escribe el primer borrador leyendo el repo, no de memoria

Si casi todos los ficheros de reglas acaban llenos de aspiraciones es porque se escribieron de memoria, de una sentada, por alguien describiendo el repo que pensaba construir.

Funciona mejor al revés: que un agente lea el repositorio y redacte el fichero a partir de lo que hay. El gestor de paquetes que se usa de verdad. El comando de tests que está en la configuración de CI. Los directorios que están generados. Y después recortar sin piedad, porque ese borrador saldrá largo y descriptivo, y traerá hechos ciertos que ningún agente necesitaba que le contaran.

Lo que escribes a mano después son los límites, porque son lo único que no se deduce del código. Nada en el repositorio dice «no toques la integración de pagos sin hablarlo conmigo». Ese conocimiento vive en tu cabeza hasta que lo escribes, y es el contenido de más valor del fichero.

Luego compruébalo como lo haría un agente. Lanza cada comando. Resuelve cada ruta. Un fichero de reglas que nunca se ha ejecutado es una hipótesis.

Dónde encaja PaellaDoc

Estos ficheros derivan porque se escriben una vez y no se mantienen nunca, mientras el repositorio que describen cambia cada semana. PaellaDoc guarda el contrato operativo junto al código y a la evidencia de las ejecuciones en un modelo local, de forma que los comandos y los límites que lee un agente se pueden contrastar con lo que el repositorio hace ahora y no con lo que hacía el día que alguien los escribió. El fichero se mantiene corto porque el razonamiento de cada regla vive en el contrato en vez de comprimirse en una línea que sobrevivirá a su motivo.

Preguntas frecuentes

¿Dónde pongo el AGENTS.md en un monorepo? Uno corto en la raíz para lo que es cierto en todos los paquetes y uno por paquete para lo que solo es cierto ahí. Mantén cada hecho en un único fichero, porque duplicar las instrucciones de build o de tests en dos sitios garantiza que uno de los dos caduque sin avisar.

¿Cuánto debe ocupar un AGENTS.md? Lo bastante poco como para leerse entero en vez de en diagonal, ya que se carga en cada llamada. Cuando pasa de una o dos pantallas, el arreglo suele ser sacar contenido antes que comprimirlo: los hechos de paquete a un fichero anidado, los procedimientos ocasionales a una skill, y las decisiones con sus porqués a la spec.

¿Por qué mi agente ignora partes de mi AGENTS.md? Normalmente porque esas partes no se pueden comprobar contra nada. Líneas como «escribe código limpio» o «ten cuidado aquí» no tienen significado observable en el repositorio, así que se tratan como preferencia y no como restricción. Sustituye cada una por los comandos, rutas o prohibiciones concretas que estaba representando.

¿Mantengo AGENTS.md y CLAUDE.md a la vez? Solo si llevan contenido distinto. El fallo es copiar los mismos hechos operativos en los dos, que duplica el mantenimiento y garantiza la divergencia. Qué contenido va en cada uno es el tema de la pieza comparativa.