====== 7. AGENTS.md ====== Qué es ''AGENTS.md'' en dos líneas está en [[cursos:sdd:02-conceptos-basicos#fichero_agentsmd|Conceptos básicos]], y cómo se genera el primero, en [[cursos:sdd:03-opencode#init|OpenCode]] y [[cursos:sdd:04-claude-code#init|Claude Code]]. Aquí, qué entra en él, dónde va todo lo demás y cómo se escriben las referencias para que funcionen igual en las dos herramientas. ---- ===== 1. Qué es AGENTS.md ===== ''AGENTS.md'' es un markdown en la raíz del repositorio con las instrucciones fijas del proyecto: lo que le contarías a un compañero nuevo el primer día. **Se carga entero en todas las sesiones**, encaje o no con la tarea. Es un [[https://agents.md/|estándar abierto]]: el mismo fichero lo leen Claude Code, OpenCode, Codex, Cursor, Copilot o Gemini CLI. ==== Pequeño: el detalle va en skills ==== Como se paga en cada petición, ''AGENTS.md'' tiene que ser **pequeño**: solo lo imprescindible y un índice. El detalle se reparte en [[cursos:sdd:08-skills-agentes#que_es_una_skill|skills]], una por tema, y el agente carga solo la que necesita para la tarea. AGENTS.md .opencode └── skills ├── producto │ └── SKILL.md ├── tecnologia │ └── SKILL.md ├── arquitectura │ ├── SKILL.md │ ├── cliente.md │ └── servidor.md └── despliegue ├── SKILL.md ├── desarrollo.md └── produccion.md Las que tiene que haber como mínimo: * ''producto'': para qué sirve el producto, qué valor aporta y sus capacidades principales. * ''tecnologia'': el stack, los frameworks, las decisiones técnicas y las restricciones del sistema completo. * ''arquitectura'': organización de directorios, patrones de arquitectura y convenciones de nombres. * ''despliegue'': cómo se despliega la aplicación, lo común a todos los entornos. Si hay varias arquitecturas, el ''SKILL.md'' se queda con lo común y cada una va en un fichero de apoyo dentro de la //skill//: ''cliente.md'', ''servidor.md'', ''movil.md''. Con el despliegue igual: ''desarrollo.md'' y ''produccion.md'' con lo propio de cada entorno. --- name: arquitectura description: Carpetas, patrones y nombres del proyecto. Usar antes de crear cualquier clase o fichero. --- # Arquitectura - Un paquete por funcionalidad (`pedidos`, `clientes`), no por capa. - Los controladores solo validan y delegan: la lógica va en los servicios. Lee además `servidor.md` si tocas `servidor/` y `cliente.md` si tocas `cliente/`. ''AGENTS.md'' dice **cuándo** usar cada una: # Pedidos API REST de pedidos con cliente web. Compilar y probar: `./mvnw verify`. ## Skills del proyecto Antes de empezar, lee la skill que necesite la tarea: - `.claude/skills/producto/SKILL.md`: antes de escribir o revisar una especificación. - `.claude/skills/tecnologia/SKILL.md`: antes de añadir una dependencia. - `.claude/skills/arquitectura/SKILL.md`: antes de crear cualquier clase o fichero. - `.claude/skills/despliegue/SKILL.md`: antes de tocar el despliegue. **La //skill// sola no basta.** El agente la carga solo si decide que encaja con la tarea, y muchas veces no lo decide: en las [[https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals|pruebas de Vercel]] no llegó a usarse en más de la mitad de los casos. El índice de ''AGENTS.md'' está siempre en contexto, así que convierte esa decisión en una instrucción. Y como da la ruta del fichero, funciona también en un agente que no sepa de //skills//. Cómo generar un primer ''AGENTS.md'' con ''/init'' y cómo mantenerlo: [[cursos:sdd:03-opencode#init|/init en OpenCode]]. ==== CLAUDE.md: no usarlo ==== Existe también ''CLAUDE.md'', el fichero propio de Claude Code. **No lo uses**: si en una carpeta hay ''CLAUDE.md'', Claude Code lee solo ese y **deja de leer el ''AGENTS.md''** de esa misma carpeta, sin avisar. El equipo que usa otra herramienta ve unas normas y el que usa Claude Code ve otras. Como basta con que alguien cree un ''CLAUDE.md'' para que el ''AGENTS.md'' deje de valer, se añade una **regla de arquitectura** que lo impida: un test que falla si aparece alguno en el repositorio. class SinClaudeMdTest { @Test void noHayNingunClaudeMd() throws IOException { try (Stream ficheros = Files.walk(Path.of("."))) { List claudeMd = ficheros .filter(f -> !f.startsWith("./target") && !f.startsWith("./.git")) .filter(f -> f.getFileName().toString().equalsIgnoreCase("CLAUDE.md")) .toList(); assertThat(claudeMd) .as("Las instrucciones van en AGENTS.md, no en CLAUDE.md") .isEmpty(); } } } ---- ===== 2. Cómo se organiza AGENTS.md ===== La [[#que_es_agentsmd|sección 1]] dice que ''AGENTS.md'' es un índice pequeño. Aquí va qué entra en él, dónde va todo lo demás y cómo se escriben las referencias para que funcionen igual en Claude Code y en OpenCode. ==== Qué entra ==== El agente **obedece** lo que pone el fichero: en el [[https://arxiv.org/abs/2602.11988|estudio de ETH Zurich]], cuando ''AGENTS.md'' nombra una herramienta, el agente la usa en casi todas las tareas, y si no la nombra, casi nunca. Pero el fichero encarece cada tarea más de un 20 %, y solo mejora el resultado cuando cuenta lo que no es estándar. Así que entra solo lo que vale **para todas las tareas** y **no se deduce del código**: * **Una frase** con qué es el proyecto. * **Órdenes** para compilar, probar y comprobar, si no son las habituales. * **Convenciones que se apartan de lo normal**: las que el agente no adivinaría leyendo el código. * **Límites**: lo que no se hace nunca y lo que se pregunta antes. * **El índice de //skills//**, con cuándo leer cada una. Fuera: la descripción general del proyecto, el árbol de carpetas, la lista de dependencias y las reglas de estilo. Las tres primeras el agente las saca del propio código, y en el estudio no le ayudaron a encontrar antes los ficheros que tenía que tocar. El estilo lo impone el formateador, no un párrafo. **No dejes tal cual el ''AGENTS.md'' que genera ''/init''.** Mete justo lo que sobra: descripción, arquitectura y dependencias. Los ficheros generados por el modelo salen peor que los escritos a mano. Úsalo de borrador y recorta. # Pedidos API REST de pedidos con cliente web. ## Órdenes - Compilar y probar: `./mvnw verify` - Solo los tests del servidor: `./mvnw -pl servidor test` ## Convenciones - Los importes son `BigDecimal` con escala 2; nunca `double`. - Los errores de negocio heredan de `ErrorDeNegocio`; los controladores no lanzan `RuntimeException`. - Cada requisito de `specs/` tiene al menos un test que cita su identificador (`R-12`). ## Límites - No modifiques una migración ya aplicada: crea una nueva. - Pregunta antes de añadir una dependencia o de cambiar un requisito de `specs/`. ## Skills del proyecto Explora primero el código que toca la tarea. Después lee la skill que necesite: - `.claude/skills/producto/SKILL.md`: antes de escribir o revisar una especificación. - `.claude/skills/tecnologia/SKILL.md`: antes de añadir una dependencia. - `.claude/skills/arquitectura/SKILL.md`: antes de crear cualquier clase o fichero. - `.claude/skills/despliegue/SKILL.md`: antes de tocar el despliegue. Cabe en una pantalla, y así tiene que seguir: **menos de 200 líneas**, mejor menos de 60. Cada instrucción de más hace que el modelo cumpla peor todas las demás, no solo la nueva. ==== Dónde va lo demás ==== ^ Qué es ^ Dónde va ^ Ejemplo ^ | Lo que vale en todas las tareas | ''AGENTS.md'' raíz | «Los importes son ''BigDecimal''» | | Lo que vale solo en una carpeta | ''AGENTS.md'' de esa carpeta | ''servidor/src/test/AGENTS.md'': «los tests de integración crean los pedidos con ''PedidoFactory''; no se mockea el repositorio» | | El detalle que solo hace falta en algunas tareas | Una //skill// | ''arquitectura'', ''despliegue'' | | Un procedimiento que se lanza para una tarea concreta | Una //skill// | ''revisar-pr'' | | Lo que tiene que cumplirse siempre | Un test, el linter o un //hook// | ''SinClaudeMdTest'', el formateador | * **''AGENTS.md'' por carpeta**: Claude Code y OpenCode lo cargan cuando el agente trabaja con ficheros de esa carpeta. Solo se crea si sus normas difieren de las de la raíz, y **no puede contradecirla**: cada herramienta los junta en un orden distinto, así que no está claro cuál gana. * **Lo que tiene que cumplirse siempre** no va en ''AGENTS.md'': ahí es una petición, no una garantía. Si de verdad no puede fallar, un test que lo compruebe, como el de la [[#claudemdno_usarlo|regla de ''CLAUDE.md'']]. ==== Cómo se escriben las referencias ==== Cada referencia lleva **la ruta entre comillas invertidas** y **cuándo leerla**. Nunca con ''@'': ^ Referencia ^ Claude Code ^ OpenCode ^ | ''`.claude/skills/arquitectura/SKILL.md`: antes de crear cualquier clase o fichero.'' | La lee cuando la tarea lo pide | La lee cuando la tarea lo pide | | ''@.claude/skills/arquitectura/SKILL.md'' | La carga entera al arrancar, en todas las sesiones | No la entiende: es texto | | ''Ver la skill de arquitectura.'' | No sabe cuándo leerla | No sabe cuándo leerla | **El ''@'' anula el índice.** En Claude Code, ''@ruta'' importa el fichero al arrancar, así que un índice escrito con ''@'' carga todas las //skills// en cada sesión: lo mismo que meterlas en ''AGENTS.md''. El ejemplo de la [[https://opencode.ai/docs/rules/|documentación de OpenCode]] usa ''@'' y en Claude Code hace justo eso. La condición se escribe con **las palabras con las que se pedirá la tarea** («antes de escribir o revisar una especificación»), sin «MUST» ni mayúsculas. En la [[https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals|prueba de Vercel]], «explora primero el proyecto y luego usa la //skill//» acertó más que «debes usar la //skill//»: con la orden tajante, el agente leía la documentación primero, seguía sus ejemplos sin mirar el proyecto y se dejaba cambios. Lo mismo vale para la ''description'' de cada //skill// ([[cursos:sdd:08-skills-agentes#el_frontmatter|el frontmatter]]): las //skills// se activan casi por palabra clave. En la [[https://scottspence.com/posts/measuring-claude-code-skill-activation-with-sandboxed-evals|medición de Scott Spence]], con la palabra en el prompt se activaban casi siempre; con una forma genérica de pedirlo, entre un 20 y un 40 % de las veces. ---- ===== Fuentes ===== * [[https://agents.md/|AGENTS.md]]: el estándar, con ejemplos y la lista de herramientas que lo leen. * [[https://vercel.com/blog/agents-md-outperforms-skills-in-our-agent-evals|AGENTS.md outperforms skills in our agent evals]]: la prueba de Vercel. Índice en ''AGENTS.md'': 100 %; //skill// sola: 53 %; //skill// con instrucción explícita: 79 %. La //skill// no llegó a usarse en el 56 % de los casos. * [[https://dreaming.press/posts/agents-md-vs-agent-skills-evals.html|AGENTS.md vs Agent Skills evals]]: lectura crítica de la prueba de Vercel. Lo que decide es dónde está el aviso de cargar la documentación (siempre en contexto o a decisión del modelo), no el formato. * [[https://scottspence.com/posts/measuring-claude-code-skill-activation-with-sandboxed-evals|Measuring Claude Code skill activation]]: otra medición. Sin ayuda, las //skills// se activan solas la mitad de las veces; cuando se activan, siempre es la correcta. * [[https://aihero.dev/a-complete-guide-to-agents-md|A complete guide to AGENTS.md]]: ''AGENTS.md'' mínimo y el detalle en ficheros enlazados por tema; qué no meter en él. * [[https://skills.cat/skills/heykvnzhao/dotfiles/agents-md-best-practices|agents-md-best-practices]]: //skill// que parte un ''AGENTS.md'' grande en un índice y un fichero por tema. * [[https://github.com/opsmill/infrahub-sdk-python/pull/609|infrahub-sdk-python PR #609]]: caso real. Un ''CLAUDE.md'' de 317 líneas pasa a un ''AGENTS.md'' de 77 más un ''AGENTS.md'' por carpeta; después el repositorio añadió //skills// para sus procedimientos. * [[https://www.humanlayer.dev/blog/writing-a-good-claude-md|Writing a good CLAUDE.md]]: por qué cada instrucción de más empeora el cumplimiento del resto, y la carpeta de documentos enlazada desde el índice. * [[https://arxiv.org/abs/2602.11988|Evaluating AGENTS.md]]: estudio de ETH Zurich. Los ficheros de contexto encarecen más de un 20 % cada tarea y en general no mejoran el resultado; sí ayudan cuando cuentan prácticas no estándar del proyecto. * [[https://code.claude.com/docs/en/memory|Claude Code: memory]]: menos de 200 líneas; los procedimientos y lo que vale solo para una parte del código, a //skills//; ''@ruta'' no ahorra contexto porque carga el fichero al arrancar. * [[https://claude.com/blog/steering-claude-code-skills-hooks-rules-subagents-and-more|Steering Claude Code]]: el fichero de instrucciones como índice que apunta a otros ficheros. * [[https://opencode.ai/docs/rules/|OpenCode: rules]]: OpenCode no sigue solo las rutas que aparecen en ''AGENTS.md''; hay que decirle cuándo leer cada fichero.