El contexto no es gratis
Escribir las reglas del proyecto una sola vez con AGENTS.md o CLAUDE.md, delegar el trabajo sucio en subagentes, y entender qué parte de la factura de tokens paga cada decisión. Con templates listos para copiar.
Hay un momento incómodo que se repite: abrís una sesión nueva con el agente, le pedís algo, y te devuelve exactamente el mismo error que le corregiste ayer.
No es que se haya olvidado. Es que nunca lo supo. Cada sesión de Claude Code arranca con una ventana de contexto vacía: lo que le explicaste la semana pasada no viajó a ninguna parte.
Y ahí hay dos trabajos distintos que la mayoría mezcla en uno solo. El primero es escribir las reglas una vez para que no haya que repetirlas. El segundo es repartir el trabajo para que una tarea ruidosa no te consuma la sesión entera.
Los dos se pagan en tokens. Eso es la tercera parte de este post, y es la que casi nadie mira hasta que le llega el aviso de límite.
#Primera parte: el archivo que se lee siempre
Hay dos mecanismos que cruzan sesiones. Uno lo escribís vos, el otro lo escribe el agente. Acá me interesa el primero.
Un CLAUDE.md es un archivo markdown con instrucciones persistentes que se carga al inicio de cada sesión. Las ubicaciones posibles, en orden de carga de lo más amplio a lo más específico:
| Alcance | Dónde va | Para qué |
|---|---|---|
| Política gestionada | /etc/claude-code/CLAUDE.md en Linux y WSL, con su equivalente en macOS y Windows |
Reglas que pone la organización |
| Usuario | ~/.claude/CLAUDE.md |
Tus preferencias, en todos tus proyectos |
| Proyecto | ./CLAUDE.md o ./.claude/CLAUDE.md |
Lo que comparte el equipo por control de versiones |
| Local | ./CLAUDE.local.md |
Lo tuyo en este proyecto, va al .gitignore |
Un detalle que cambia cómo conviene organizarlo: los archivos no se sobrescriben entre sí, se concatenan. Se ordenan desde la raíz del filesystem hacia tu directorio de trabajo, así que las instrucciones más cercanas a donde levantaste la sesión se leen al final. Y dentro de cada directorio, el CLAUDE.local.md se agrega después del CLAUDE.md.
Los CLAUDE.md que están en subdirectorios por debajo de tu directorio de trabajo no se cargan al arranque: entran cuando el agente lee un archivo de ahí. En un monorepo eso importa bastante.
Si arrancás de cero, /init genera un primero analizando el repo. Si ya existe uno, en vez de sobreescribirlo sugiere mejoras.
#AGENTS.md: el mismo archivo para todos los agentes
Si ya venías manteniendo un AGENTS.md para otras herramientas, hasta hace poco tenías que duplicarlo o importarlo. Eso cambió en la versión 2.1.277, y el changelog lo dice en una línea:
Added AGENTS.md support: in a project with no CLAUDE.md, Claude Code reads AGENTS.md instead; change it under 'Project instructions' in
/config
La condición está en esa frase y conviene leerla con cuidado, porque es la causa número uno de "tengo el archivo y no lo lee":
| Lo que hay en el repo | Lo que lee Claude |
|---|---|
Un AGENTS.md, y ningún CLAUDE.md ni CLAUDE.local.md en tu directorio de trabajo ni arriba |
Tu AGENTS.md |
Un AGENTS.md y además un CLAUDE.md o CLAUDE.local.md en tu directorio o arriba |
Solo tus CLAUDE.md |
Un CLAUDE.md que ya importa el AGENTS.md |
Tu CLAUDE.md, con el AGENTS.md incluido por el import |
Tu ~/.claude/CLAUDE.md, el CLAUDE.md gestionado de la organización y los archivos de .claude/rules/ no cuentan para ese chequeo: siguen cargando al lado del AGENTS.md.
Dos consecuencias prácticas de la tabla:
- Si agregás un
CLAUDE.local.mdcon tus notas personales a un proyecto que se apoya enAGENTS.md, dejás de leer elAGENTS.md. Para conservar los dos, hay que poner Project instructions enclaude-md-and-agents-mddesde/config. - El
AGENTS.mdleído directamente no aparece en/memoryni en la lista de Memory files de/context. Para confirmar que cargó, se busca en la conversación una línea del estilono CLAUDE.md found; AGENTS.md loaded: /home/you/repo/AGENTS.md.
Y si tu sesión es una de las que no puede leerlo directo — por ejemplo sobre Amazon Bedrock, o con la telemetría deshabilitada — la salida sigue siendo un CLAUDE.md al lado con una sola línea:
@AGENTS.md
Ese import nunca hace que el archivo se lea dos veces, así que dejarlo puesto no cuesta nada. Debajo del import podés agregar lo que sea específico de Claude.
Tres archivos que no se leen, para que no los uses esperando que funcionen: AGENTS.local.md, AGENTS.override.md, y cualquier cosa dentro de un directorio .agents/.
#Cómo se escribe uno que realmente se cumpla
Acá hay algo que conviene decir sin vueltas: esto es contexto, no configuración. No es un archivo de reglas que el runtime aplique a la fuerza. Si querés bloquear una acción pase lo que pase, eso es un hook, no una línea en el markdown.
Lo cual significa que cómo lo escribís cambia cuánto se cumple. Lo que está documentado:
Tamaño: apuntá a menos de 200 líneas por archivo. Más largo consume más contexto y baja la adherencia. Y no te engañes partiéndolo en imports "para que sea más liviano": los archivos importados se expanden y entran al contexto igual, en el arranque. Sirven para organizar, no para ahorrar.
Especificidad: instrucciones concretas, verificables.
| ❌ | ✅ |
|---|---|
| "Formateá bien el código" | "Usá indentación de 2 espacios" |
| "Probá tus cambios" | "Corré npm test antes de commitear" |
| "Mantené los archivos ordenados" | "Los handlers de la API van en src/api/handlers/" |
Consistencia: si dos reglas se contradicen, el agente puede elegir cualquiera de las dos. Eso incluye las que están en CLAUDE.md anidados y en .claude/rules/. Conviene revisarlas de tanto en tanto y sacar lo que quedó viejo.
Y lo que no va ahí: si una entrada es un procedimiento de varios pasos, o solo importa para una parte del código, no es contenido para este archivo. Los procedimientos van a un skill, que se carga cuando se invoca. Lo que aplica a ciertos archivos va a una regla con paths: en el frontmatter, que carga solo cuando el agente toca algo que matchea. La diferencia no es estética: lo que está acá se paga en todas las sesiones, incluso en las que no tienen nada que ver.
El criterio para decidir qué agregar es bastante simple, y es el mismo que usarías con una persona nueva en el equipo: escribilo cuando el agente comete el mismo error por segunda vez, cuando un code review encuentra algo que debería haber sabido del proyecto, o cuando te escuchás tipeando la misma corrección que tipeaste la sesión pasada.
Un detalle lindo para el final: los comentarios HTML de bloque (<!-- así -->) se eliminan antes de inyectar el contenido. Podés dejar notas para los humanos que mantienen el archivo sin gastar tokens en ellas.
#Template: AGENTS.md
Esto es un punto de partida, no un molde sagrado. Está pensado para un backend .NET, pero la estructura aplica a cualquier stack: comandos, layout, convenciones, y lo que está prohibido.
# AGENTS.md
Instrucciones para agentes de IA que trabajan en este repositorio.
Humanos: ver también `README.md`.
## Stack
- .NET 8, ASP.NET Core Web API
- EF Core 8 sobre SQL Server
- xUnit + FluentAssertions para tests
## Comandos
- Build: `dotnet build`
- Tests: `dotnet test`
- Un solo test: `dotnet test --filter FullyQualifiedName~NombreDelTest`
- Migraciones: `dotnet ef migrations add <Nombre> -p src/Infra -s src/Api`
Corré `dotnet test` antes de dar por terminado cualquier cambio.
## Estructura
- `src/Api/` — controllers y composición (DI, middleware)
- `src/Application/` — casos de uso, un handler por operación
- `src/Domain/` — entidades y reglas, sin dependencias a infraestructura
- `src/Infra/` — EF Core, clientes HTTP, integraciones
- `tests/` — espeja la estructura de `src/`
## Convenciones
- Nullable reference types habilitado; no agregues `!` para silenciar el compilador
- Async hasta el final: todo método que hace IO devuelve `Task` y recibe `CancellationToken`
- Un archivo por tipo público
- Los DTOs de entrada y salida son `record`, y nunca se exponen entidades de dominio en la API
- Los mensajes de error que ve el usuario van en español; los logs en inglés
## Qué no hacer
- No agregues una dependencia nueva sin dejarlo dicho en el resumen del cambio
- No toques nada dentro de `src/Infra/Migrations/`, se genera
- No escribas lógica de negocio en los controllers
- No hagas `git push --force` sobre ramas compartidas
## Git
- Ramas: `feature/<descripcion-corta>`
- Commits en imperativo, una línea, sin prefijos de emoji
<!-- Nota para el equipo: los procedimientos largos viven en .claude/skills/, no acá -->
Si tu proyecto también tiene un CLAUDE.md, o si trabajás en sesiones que no pueden leer el AGENTS.md directo, el archivo de al lado es de una línea:
@AGENTS.md
## Notas específicas de Claude
- Antes de tocar `src/Application/`, leé el handler más parecido y seguí su forma
#Segunda parte: subagentes
Un subagente es un asistente especializado que corre en su propia ventana de contexto, con su propio prompt de sistema, sus propias herramientas y sus propios permisos. Trabaja sobre una tarea delegada y devuelve un resumen a la conversación principal.
Eso es el punto entero. La tarea que iba a llenar tu sesión de resultados de grep, logs y contenido de archivos que no vas a volver a mirar, la hace en su contexto, y a vos te vuelve el resumen.
Lo que sí ve un subagente cuando arranca: su propio prompt de sistema, el mensaje de delegación que le escribe el agente principal, y los CLAUDE.md de toda la jerarquía. Lo que no ve: el historial de la conversación, los archivos que el principal ya leyó, ni los skills que ya se habían invocado. Arranca limpio.
Los archivos van en un directorio y el más específico gana:
| Ubicación | Alcance |
|---|---|
.claude/agents/ |
Este proyecto — va al control de versiones |
~/.claude/agents/ |
Todos tus proyectos |
Los directorios se escanean recursivamente, así que podés organizarlos en subcarpetas.
#El frontmatter
Dos campos obligatorios y una lista larga de opcionales. Los cuatro que importan al principio:
| Campo | Obligatorio | Qué hace |
|---|---|---|
name |
Sí | Identificador único, en minúsculas y con guiones. No puede contener : |
description |
Sí | Cuándo debería delegarle el agente principal |
tools |
No | Las herramientas que puede usar. Si lo omitís, hereda todas las disponibles para subagentes |
model |
No | sonnet, opus, haiku, fable, un ID completo como claude-opus-5, o inherit |
Sobre description: la delegación automática se decide con tu pedido, este campo, y el contexto del momento. Poner "usá esto proactivamente" (o el equivalente en inglés) empuja a que se delegue sin que lo pidas. Y conviene que sea breve: cuando la suma de todas las descripciones pasa los 15.000 tokens, salta una advertencia.
Sobre tools: los nombres son los canónicos de las herramientas — Read, Grep, Glob, Bash, Edit, Write, WebFetch, WebSearch, TodoWrite, Agent, Skill. Ojo con este, que es un clásico: la herramienta para lanzar subagentes se llama Agent, no Task. Y si la lista queda vacía o no resuelve a nada, normalmente el subagente no arranca y te devuelve un error con los nombres que no pudo resolver.
Un punto que conviene tener claro antes de escribir el cuerpo del archivo: el prompt de sistema del subagente reemplaza por completo al de Claude Code. No es un agregado. Todo lo que el subagente necesite saber sobre cómo comportarse tiene que estar ahí.
#Cómo se invoca
Tres niveles, de menos a más determinista:
# 1. Lenguaje natural — el agente decide si delega
"Usá el subagente test-runner para arreglar los tests que fallan"
# 2. Mención — garantiza que corra para esa tarea
@agent-revisor-csharp revisá los cambios de auth
# 3. Default de sesión
claude --agent revisor-csharp
#Los tres que uso
No hacen falta veinte. Con estos tres se cubre casi todo, y cada uno resuelve un problema distinto: revisar, buscar, y ejecutar algo ruidoso.
#1. El revisor
Read-only a propósito. Si no puede escribir, no te "arregla" nada por su cuenta mientras revisa.
Va en .claude/agents/revisor-csharp.md:
---
name: revisor-csharp
description: Revisa cambios en C# contra las convenciones del proyecto y busca bugs, problemas de performance y riesgos de seguridad. Usalo proactivamente después de escribir o modificar código.
tools: Read, Grep, Glob
model: sonnet
---
Sos un revisor de código C#. Trabajás sobre los cambios que te indiquen,
sin modificar archivos.
Para cada hallazgo, devolvé tres cosas en este orden:
1. Qué está mal y por qué importa (una o dos oraciones)
2. El código actual, con su ruta y número de línea
3. La versión corregida
Revisá, en este orden de prioridad:
- Correctitud: nulls que no se manejan, off-by-one, condiciones invertidas
- Async: métodos async sin `CancellationToken`, `.Result` o `.Wait()`
bloqueando, `async void`
- EF Core: consultas dentro de loops, `Include` que traen de más,
entidades de dominio expuestas en respuestas de la API
- Seguridad: concatenación de SQL, secretos hardcodeados, datos de usuario
en los logs
- Convenciones del proyecto, según las instrucciones que ya tenés cargadas
Ordená los hallazgos de más grave a menos grave. Si no encontrás nada,
decilo en una línea y no rellenes con observaciones de estilo.
#2. El rastreador
Este existe por una razón muy concreta: buscar en un repo grande genera muchísimo output que no vas a volver a leer. Con haiku alcanza y sobra, y es la opción más barata.
Va en .claude/agents/rastreador-deuda.md:
---
name: rastreador-deuda
description: Busca marcas de deuda técnica en el repositorio y devuelve un inventario agrupado. Usalo cuando haya que hacer un relevamiento antes de planificar.
tools: Read, Grep, Glob
model: haiku
---
Sos un relevador de deuda técnica. Tu trabajo es encontrar e inventariar,
no opinar ni arreglar.
Buscá:
- Comentarios `TODO`, `FIXME`, `HACK`, `XXX` y `WORKAROUND`
- `try/catch` que se tragan la excepción sin loguear
- Tests marcados como ignorados o salteados
- Valores hardcodeados que deberían estar en configuración: URLs,
connection strings, timeouts, rutas absolutas
- Métodos de más de 80 líneas
- Dependencias con versión fijada a una versión vieja
Devolvé una tabla agrupada por categoría, con ruta y línea, ordenada por
cantidad de hallazgos. Al final, agregá las tres cosas que más se repiten.
No pegues bloques largos de código: una línea de contexto por hallazgo
es suficiente. No propongas arreglos salvo que te los pidan.
#3. El corredor de pruebas
Este es el caso de manual del ahorro de contexto. Correr la suite completa escupe cientos de líneas; lo que vos necesitás son las que fallaron.
Va en .claude/agents/corredor-pruebas.md:
---
name: corredor-pruebas
description: Corre la suite de tests y reporta únicamente lo que falló, con el mensaje de error y el archivo. Usalo proactivamente después de cambios que puedan romper tests.
tools: Bash, Read, Grep, Glob
model: sonnet
---
Sos el que corre los tests y reporta el resultado. No arreglás nada salvo
que te lo pidan explícitamente.
Corré la suite con el comando del proyecto. Si no sabés cuál es, buscalo
en las instrucciones del repositorio antes de improvisar uno.
Devolvé, en este formato y nada más:
1. Una línea de resumen: cuántos pasaron, cuántos fallaron, cuánto tardó
2. Por cada test que falló: el nombre, el mensaje de error, y la línea del
stack trace que apunta a código del proyecto (no a código del framework)
3. Si varios fallan por la misma causa, agrupalos y decilo
No pegues la salida completa del runner. No incluyas los tests que pasaron.
Si la compilación falla antes de correr los tests, reportá solo los errores
de compilación.
#Tercera parte: la factura
Todo lo de arriba se paga en tokens, y conviene saber en qué parte.
El mecanismo base es este: Claude Code manda tu conversación completa en cada request, y cada vez que usa herramientas manda otro request con esa tanda de resultados. Con prompt caching, ese historial se vuelve a leer a la tarifa de tokens cacheados, pero se vuelve a leer. Una pregunta de una línea en una sesión que lleva abierta todo el día arrastra la conversación entera.
De ahí salen las dos cuentas que importan:
El costo fijo de arranque. Tu CLAUDE.md o AGENTS.md entra al contexto en cada sesión, tenga o no que ver con lo que vas a hacer. Un archivo de 600 líneas con el procedimiento completo de las migraciones se paga también el día que solo vas a cambiar un color en el CSS. Por eso el límite de 200 líneas no es una sugerencia estética, y por eso mover los procedimientos a skills — que cargan cuando se invocan — baja el piso de todas tus sesiones.
El costo variable de delegar. Cada subagente tiene su propia ventana de contexto. Delegar no es gratis: es cambiar output verboso en tu contexto por una conversación aparte con su propio arranque. Conviene cuando lo que se delega genera mucho ruido y devuelve poco — tests, logs, búsquedas, documentación — y no conviene cuando la tarea necesita todo el hilo de la conversación, porque el subagente justamente no lo tiene y hay que reconstruírselo.
#Cómo mirar la factura
/contextmuestra el uso actual del contexto como una grilla, con sugerencias de qué está ocupando lugar./usagemuestra tokens y costo estimado de la sesión./costes un alias de/usage, no otro comando.- En planes Pro, Max, Team y Enterprise,
/usageademás desglosa el consumo reciente atribuido a skills, subagentes, plugins y servidores MCP, cada uno como porcentaje del total. Ahí es donde se ve si el subagente que creaste para ahorrar contexto en realidad se está comiendo la sesión.
Una cifra documentada, y vale la pena ser preciso con ella porque es fácil citarla mal: los agent teams — que no son subagentes, son varias instancias de Claude Code coordinadas, con su propia ventana de contexto cada una — usan aproximadamente 7 veces más tokens que una sesión normal cuando los compañeros corren en plan mode. Están deshabilitados por defecto. No es el número de los subagentes; es el techo de a dónde puede ir esto si escalás la cantidad de agentes en paralelo.
#Las palancas que mueven la aguja
En orden de cuánto rinden por el esfuerzo que cuestan:
/clearentre tareas que no tienen nada que ver. El contexto viejo se paga en cada mensaje siguiente. Con/renameantes, después lo encontrás con/resume.- El modelo correcto para cada cosa. Sonnet resuelve bien la mayoría del trabajo y cuesta menos que Opus. Para subagentes de tareas simples,
model: haiku. - Delegar lo verboso. Tests, documentación, procesamiento de logs. La salida larga queda en el contexto del subagente.
- Sacar del
CLAUDE.mdlo que no se usa siempre. A skills si es un procedimiento, a.claude/rules/conpaths:si aplica solo a ciertos archivos. - Pedidos específicos. "Agregá validación al login en
auth.ts" en vez de "mejorá este código", que dispara un escaneo completo. - Plan mode antes de lo complejo. Cuesta una pasada de exploración y te ahorra el retrabajo entero de haber arrancado para el lado equivocado.
Y un detalle que explica saltos raros en el consumo: el primer mensaje después de un corte más largo que la vida del caché vuelve a procesar todo tu contexto. En suscripción esa vida es de una hora; con usage credits baja a cinco minutos, igual que el default con API key o proveedor cloud.
#Lo que queda
Las tres partes son la misma idea vista desde tres lados.
El AGENTS.md es lo que no querés volver a explicar. El subagente es lo que no querés tener en tu contexto. Y los tokens son la unidad en la que se mide si esas dos decisiones estuvieron bien tomadas.
Lo que no cambia es que sigue siendo tu criterio el que se escribe en esos archivos. El agente no lo va a deducir, y si no está escrito, no está.
#ai #claude-code #tooling #team-practices