Por qué los agentes de código ignoran tus instrucciones
Si tu archivo dice que el agente debe detenerse y aun así continúa, descubre si la regla no se cargó, es ambigua, fue contradicha o quedó fuera de foco.
Por qué los agentes de programación ignoran sus instrucciones
Los agentes de programación ignoran sus instrucciones por cuatro motivos, y ninguno es que usted haya sido demasiado amable. La regla nunca estuvo en la ventana de contexto. La regla era demasiado imprecisa para comprobar una acción con respecto a ella. Otro elemento del contexto la contradecía, normalmente el código que el agente acababa de leer. O la regla sigue cargada, pero está muy atrás en el turno actual, y el agente trabaja con lo que tiene más cerca.
Cada causa tiene su propia solución, por lo que el primer trabajo consiste en distinguirlas. Escribir en mayúsculas y usar la palabra IMPORTANT no permite diagnosticar el problema. Los mecanismos siguientes usan Claude Code como ejemplo práctico, porque su comportamiento de carga y compactación está documentado con detalle a fecha de August 2026. Otras herramientas difieren en los detalles, pero en términos generales se comportan de la misma forma.
Primero, dos términos. La ventana de contexto es el bloque de texto que el modelo ve en un turno determinado: el prompt del sistema, los archivos de instrucciones, la conversación y todos los archivos que el agente ha leído. El harness es el programa que rodea al modelo, es decir, el componente que lee archivos del disco y ensambla ese bloque. Casi todas las quejas de este artículo se refieren en realidad al harness, no al modelo.
Tu archivo de instrucciones es un mensaje, no una configuración
Un archivo de instrucciones no es una configuración. Nada del entorno de ejecución lee CLAUDE.md y lo aplica. El entorno de ejecución lee el archivo del disco y pega el texto en la conversación. En Claude Code, ese contenido se entrega como un mensaje de usuario situado después del prompt del sistema. Por tanto, el modelo ve las reglas igual que cualquier otro texto que usted haya escrito.
Esto tiene una consecuencia incómoda. Sus reglas compiten con todos los demás textos de la ventana en igualdad de condiciones. Una regla es una afirmación. El archivo que el agente acaba de abrir es una evidencia. Cuando ambos discrepan, la evidencia suele imponerse. No se genera ningún error porque, desde el punto de vista del modelo, no ha ocurrido nada incorrecto.
La documentación oficial lo indica claramente: los archivos de instrucciones se tratan como contexto, no como configuración aplicada. Para bloquear una acción independientemente de lo que decida el modelo, necesita un hook, no una frase. Conserve esa idea. La mayoría de las correcciones del final de esta publicación aplican esa idea a un caso concreto.
Qué archivos de instrucciones se cargan y cuándo
Claude Code recorre el árbol de directorios desde el directorio en el que lo inició. Todos los archivos CLAUDE.md y CLAUDE.local.md, desde la raíz del sistema de archivos hasta el directorio de trabajo, se cargan por completo al iniciar. Se concatenan en ese orden, por lo que el archivo más cercano al directorio desde el que lo inició se lee en último lugar. Dentro de un mismo directorio, el archivo .local se añade después del archivo principal.
Los archivos de los subdirectorios situados por debajo del directorio de trabajo se comportan de otra forma. No se cargan al iniciar. Se cargan cuando el agente lee un archivo de ese directorio. Lo mismo ocurre con las reglas asociadas a rutas en .claude/rules/ que contienen un campo de frontmatter paths:: entran en el contexto cuando se lee un archivo coincidente, no en cada turno.
Esta diferencia explica muchos de los fallos notificados. Añade una regla a packages/api/CLAUDE.md, hace una pregunta sobre la API y el agente responde sin abrir ningún archivo de packages/api/. La regla no se ignoró. Nunca estuvo presente. Si el repositorio distribuye las instrucciones mediante archivos de instrucciones por paquete en un monorepo, esto es lo primero que debe comprobar en cada ocasión.
Hay otra trampa relacionada con la carga, y es la causa más habitual de que parezca que «el agente ignoró mis instrucciones»: Claude Code lee CLAUDE.md, no AGENTS.md. Un repositorio que haya estandarizado AGENTS.md y no tenga CLAUDE.md no proporciona nada que Claude Code pueda cargar. El mecanismo compatible es un archivo CLAUDE.md cuya primera línea sea @AGENTS.md. Esto importa el archivo al iniciar, junto con cualquier nota específica para Claude que se añada debajo. También puede usar un enlace simbólico si no necesita añadir nada más. Decidir qué debe incluir ese archivo es una cuestión independiente, que se trata en separar las instrucciones del agente de la documentación para las personas.
Confirme que el archivo se cargó antes de reescribirlo
No modifique el texto hasta comprobar que el agente puede ver el archivo. Hay dos comprobaciones, y la más sencilla se hace primero.
Ejecute /context dentro de la sesión. Muestra la ventana actual desglosada por categoría, y la lista Memory files incluye el nombre de cada archivo de instrucciones que se cargó realmente. Si un archivo no aparece en esa lista, no forma parte de la conversación y nada de lo que escriba en él tendrá efecto. /memory muestra las ubicaciones de los archivos y los abre para editarlos, incluidos los que todavía no existen.
Para obtener una respuesta más concluyente, registre las cargas. El evento de hook InstructionsLoaded se activa cada vez que un CLAUDE.md o un archivo de reglas entra en el contexto, y su comparador indica por qué se produjo la carga: session_start, nested_traversal, path_glob_match, include o compact. Coloque esto en .claude/settings.json:
{
"hooks": {
"InstructionsLoaded": [
{
"matcher": "nested_traversal",
"hooks": [
{
"type": "command",
"command": "cat >> /tmp/instructions-loaded.log"
}
]
}
]
}
}El hook recibe los datos como JSON por la entrada estándar, por lo que cat añade el registro completo. Supervíselo con tail -f /tmp/instructions-loaded.log mientras trabaja. El estado de salida de este evento se ignora, por lo que el hook sólo puede observar, no bloquear. Si el archivo anidado nunca aparece en ese registro durante una sesión en la que esperaba que se cargara, deje de reescribirlo. El problema está en su ubicación.
Qué le hace una sesión larga a las reglas
Aquí se aplican dos efectos distintos y requieren respuestas diferentes.
Distancia. Una regla indicada en el turno 1 sigue dentro de la ventana en el turno 90, pero ahora compite con 90 turnos de texto más recientes y más específicos de la tarea que está realizando. No puede eliminar este efecto mediante configuración, pero sí puede medirlo. Ejecute la misma tarea en una sesión nueva. Si la regla se cumple allí y deja de cumplirse en una sesión larga, la distancia es la causa.
Compactación. Cuando la ventana se llena, el entorno resume la conversación hasta ese momento y continúa a partir de ese resumen. Lo que sobrevive es lo que el resumidor consideró importante, que no coincide necesariamente con lo que usted considera importante. Claude Code documenta el resultado de cada mecanismo, y las diferencias son grandes. Las reglas del directorio raíz del proyecto CLAUDE.md y las reglas sin ámbito se vuelven a inyectar desde el disco después de una compactación. La memoria automática se vuelve a inyectar desde el disco. Las reglas con frontmatter paths: se pierden hasta que se vuelve a leer un archivo coincidente. Los archivos CLAUDE.md anidados en subdirectorios se pierden hasta que se vuelve a leer un archivo de ese subdirectorio.
Ordene sus instrucciones según esa tabla y el orden de fragilidad se deduce por sí solo. Una regla que sólo escribió en el chat es el elemento más frágil de la sesión: sólo persiste si el resumen la conserva. Una regla en packages/api/CLAUDE.md ocupa el siguiente lugar, porque se cargó una vez, se eliminó del resumen y sólo vuelve a cargarse en la siguiente lectura de ese directorio. Una regla del archivo del directorio raíz del proyecto es la más duradera, porque se vuelve a leer del disco cada vez.
Por tanto, si una instrucción debe mantenerse durante toda una sesión, debe estar en el archivo del directorio raíz del proyecto, sin frontmatter paths:. Todo lo demás implica una decisión de compromiso que debe tomar de forma deliberada. Gestionar lo que permanece en la ventana de contexto trata /compact con un argumento de enfoque y /clear entre tareas no relacionadas; ambos factores cambian la frecuencia con la que el resumidor puede decidir qué reglas tenía usted.
Por qué el código circundante prevalece sobre la regla
Este es el fallo que más se describe y menos se diagnostica. El archivo indica que el acceso a la base de datos pasa por la capa de repositorio. El agente escribe un controlador que llama directamente al ORM (mapeador objeto-relacional). No ignoró la regla por motivos de estilo. La evidencia pesó más.
Una regla describe una preferencia. El código demuestra una preferencia. Cuando el agente abre tres archivos del módulo que está a punto de modificar y los tres llaman directamente al ORM, el contexto contiene una frase abstracta en un lado y tres ejemplos concretos, recientes y ajustados a la tarea en el otro. Copiar el patrón local suele ser el comportamiento correcto. Aquí es incorrecto sólo porque usted sabe algo que el contexto desconoce: esos archivos son código heredado.
Por tanto, escríbalo en la regla. Las reglas que identifican sus propias contradicciones visibles resisten el contacto con un repositorio real. Las reglas que expresan una preferencia aislada no.
El acceso nuevo a la base de datos pasa porapp/repositories/. Los archivos bajoapp/legacy/todavía llaman directamente al ORM. Es código antiguo, no el patrón que debe seguirse. No lo copie.
La segunda frase es la que cumple la función. Indica al agente qué está a punto de encontrar y cómo debe interpretarlo, antes de que lo encuentre. La misma corrección se aplica a cualquier regla que el repositorio contradiga de forma visible: un estilo de commits que el historial no sigue, una estructura de pruebas que la mitad de la suite ignora o una convención de imports que sólo se aplica al código nuevo. Siempre que el código contradiga al archivo, indique esa contradicción en el propio archivo.
Una regla vaga no se puede comprobar y, por tanto, no se puede seguir
"Escriba código limpio." "No diseñe en exceso." "Manténgalo simple." "Tenga cuidado con las migraciones." Ninguna de estas reglas se puede probar contra una acción concreta, ni el agente ni usted. Si un agente recibe una regla que no puede comprobar en su propia salida, está adivinando, y usted evalúa esa suposición según su impresión.
Aplique esta prueba a cada línea del archivo. Escriba el comando de shell que devuelva un código distinto de cero cuando se incumpla la regla. Si no puede escribir ese comando, la regla no se puede comprobar. Compare estos pares:
- No comprobable: "Mantenga las funciones pequeñas." Comprobable: "Una función de más de 60 líneas necesita un comentario encima que explique el motivo."
- No comprobable: "Pruebe los cambios." Comprobable: "Ejecute
npm testy pegue el número de fallos antes de marcar una tarea como terminada." - No comprobable: "Mantenga los archivos organizados." Comprobable: "Los controladores HTTP están en
src/api/handlers/. No coloque nada más en ese directorio." - No comprobable: "Formatee correctamente el código." Comprobable: "Use una indentación de 2 espacios en los archivos
.ts."
"No diseñe en exceso" es la primera regla que la gente abandona, porque la solución no consiste en acortar la frase, sino en alargarla: explicar con precisión qué significa el cambio mínimo que funciona proporciona al agente criterios con los que puede comparar su propio diff.
El tamaño plantea el mismo problema con otra forma. Las directrices de Claude Code recomiendan menos de 200 líneas por archivo de instrucciones y señalan directamente que los archivos más largos reducen el cumplimiento. Un archivo de 700 líneas no contiene instrucciones más firmes. Contiene 700 líneas de afirmaciones, con más posibilidades de contradecirse, y se carga en la ventana en cada turno, lo que se refleja directamente en el uso de tokens. Estructurar el archivo para que cada regla aparezca bajo un encabezado que el lector pueda examinar rápidamente se explica en cómo escribir un archivo de instrucciones que el agente pueda aplicar. Mejor aún, elimine las partes descriptivas que no contienen instrucciones: un recorrido por los directorios que indique dónde están los controladores y los modelos es información estructural que el agente puede consultar cuando la necesite en un mapa analizado del repositorio, en lugar de cargarla en la ventana en cada turno.
Cómo diagnosticarlo en diez minutos
Ejecute estos pasos en orden. Saltar directamente al último paso suele producir un archivo largo de reglas enfáticas que sigue sin funcionar.
- Confirme que se cargó. Ejecute
/contexty lea la lista de archivos de Memory. Si el archivo no aparece, corrija la ubicación y deténgase. Nada más de esta lista se aplica todavía. - Reproduzca el problema en una sesión nueva. Inicie una sesión nueva y proporcione la tarea más pequeña que debería activar la regla. Si funciona al principio pero falla en una sesión larga, el problema apunta a la distancia o a la compactación. Si también falla aquí, el problema está en la propia regla.
- Elimine la competencia. Solicite el mismo cambio en un directorio cuyo código existente ya siga la regla. Si el cumplimiento vuelve a funcionar, el código circundante estaba imponiéndose a su frase.
- Busque un conflicto. Dos archivos que proporcionan instrucciones distintas para el mismo comportamiento constituyen un fallo documentado: el modelo puede elegir uno de forma arbitraria y no le indicará que lo hizo.
- Haga que se pueda comprobar y vuelva a probar. Reescriba la regla con una ruta concreta y una condición. Un aumento importante del cumplimiento indica que la redacción era la causa.
El paso 4 requiere un comando. Busque el tema en todas las fuentes de instrucciones, no sólo en el archivo que estaba editando:
grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/nullUna coincidencia en dos archivos que indican cosas distintas es el error. Elimine una de ellas. No intente establecer prioridades con una redacción más contundente, porque no existe ningún motor de prioridades al que pueda recurrir.
Las correcciones, en orden de eficacia
Cada paso siguiente ofrece más eficacia que el anterior y requiere más trabajo de configuración. Empiece por arriba cuando sea barato reformular una regla. Baje al paso siguiente en cuanto la regla sea lo bastante importante como para que no sean aceptables los incumplimientos ocasionales.
- Haga concreta la regla. Indique una ruta, un comando o una condición. Añada las pruebas en contra que el agente encontrará en el repositorio, como se mostró antes. No tiene coste y resuelve una proporción sorprendentemente alta de los casos.
- Acérquela a aquello que regula. Puede ser un
CLAUDE.mdanidado, una regla cuyo ámbito sea una ruta en.claude/rules/o un comentario al principio del propio archivo. De este modo, la regla se carga junto con el código al que se aplica. Acepte esta contrapartida: todo lo que se cargue de ese modo desaparece en la siguiente compactación y vuelve a cargarse en la siguiente lectura coincidente. - Traslade la aplicación de la regla a un hook. La prosa solicita. Un hook decide. Los hooks se ejecutan como código en eventos fijos del ciclo de vida y se aplican independientemente de la conclusión del modelo.
- Asigne la regla a una herramienta determinista y elimine la prosa. Formato, orden de imports, longitud de línea, imports prohibidos o estructura de los mensajes de commit.
ruff format,prettier --write,eslinto un hookpre-commit. El formatter acierta siempre y no consume tokens. La frase acierta la mayoría de las veces y consume tokens en cada turno.
Paso 3 completo. Suponga que el agente nunca debe editar los archivos de migración. Añada esto a .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
}
]
}
]
}
}Y esto a .claude/hooks/guard-migrations.sh:
#!/usr/bin/env bash
set -euo pipefail
path=$(jq -r '.tool_input.file_path // empty')
case "$path" in
*/migrations/*)
echo "Files under migrations/ are written by hand. Stop and ask first." >&2
exit 2
;;
esac
exit 0Ejecute chmod +x .claude/hooks/guard-migrations.sh, inicie después una sesión nueva y pida al agente que edite un archivo en migrations/. La edición se rechaza y el mensaje vuelve con el motivo. Un estado de salida 2 en PreToolUse bloquea la llamada a la herramienta antes de que se ejecute, y el texto de stderr se entrega al modelo como mensaje de bloqueo. ${CLAUDE_PROJECT_DIR} se resuelve en la raíz del proyecto, por lo que el hook funciona independientemente del directorio en el que se encuentre el agente. El agente no tiene que aceptar la regla, recordarla ni conservarla en el contexto. La edición no se realiza.
Para una prohibición directa sin lógica, permissions.deny en la configuración hace el mismo trabajo sin necesidad de mantener un script, y los modos de permisos determinan qué se ejecuta sin pedirle confirmación. Si una instrucción debe estar realmente en el nivel del system prompt y no en un mensaje de usuario, --append-system-prompt la coloca allí, aunque debe pasarse en cada invocación, por lo que resulta más adecuada para scripts que para el trabajo interactivo.
Lo que no puede imponer una instrucción
Aclare qué parte depende de usted. La ubicación, la redacción, los conflictos entre archivos y el tamaño del archivo son problemas del autor, y el autor debe corregirlos. El resto corresponde al comportamiento del modelo, y una redacción mejor no lo eliminará.
Aceptar no es cumplir. Un agente confirmará una regla, se la repetirá correctamente y la incumplirá dos llamadas de herramienta después. La confirmación no cuesta nada y no predice nada. No la considere una corrección ni la cuente como una prueba.
Algunos hábitos persisten. Añadir comentarios, incorporar gestión defensiva de errores, escribir un resumen final y ejecutar el siguiente comando obvio. Estos comportamientos reaparecen cuando una regla los prohíbe, aunque con una frecuencia menor, no nula. Puede medir su propia frecuencia: ejecute la misma tarea diez veces en sesiones nuevas y cuente las infracciones. Cuando esa cifra deba ser cero, la regla debe salir del prompt. Dar por terminado un trabajo cuando aún queda una parte sin hacer tiene la misma estructura de hábito, y la corrección es estructural, no verbal: la habilidad unlazy sustituye la frase por un árbol de profundidad y archivos de control que el agente debe superar antes de poder afirmar que ha terminado.
Su propia sesión se convierte en un ejemplo. Si el agente incumplió la regla en el turno 12 y usted lo dejó pasar, esa infracción queda en el contexto como una demostración y es mucho más reciente que la regla. Corrija una infracción en cuanto la detecte. Una infracción no corregida enseña al resto de la sesión.
Un archivo de instrucciones no es un límite de seguridad. Modifica el comportamiento, pero no lo impone. Todo aquello cuyo incumplimiento sea costoso, como las credenciales o los comandos destructivos, debe gestionarse mediante permisos o un hook. Mantener los secretos fuera del alcance de un agente aplica el mismo principio a los datos: no pida a un agente que no lea un archivo; haga que el archivo no sea legible.
La versión breve: demuestre que el archivo se ha cargado, haga que la regla se pueda comprobar, colóquela junto al elemento que regula y, cuando la tasa de incumplimiento siga siendo importante, sáquela de la prosa. Una regla que un agente no puede ignorar es una regla que nunca se le pidió al agente.
FAQ
¿Por qué Claude Code ignora mi CLAUDE.md?
Compruebe que lo haya cargado antes de asumir que lo ignoró. Ejecute /context y revise la lista Memory files; si un archivo no aparece allí, no forma parte de la conversación. Los archivos de instrucciones se entregan como un mensaje de usuario después del prompt del sistema y se tratan como contexto, no como configuración obligatoria, por lo que no existe una garantía estricta de cumplimiento. En la mayoría de los casos, se trata de una de estas cuatro situaciones: el archivo está en un subdirectorio que el agente nunca leyó, dos archivos se contradicen y el modelo eligió uno arbitrariamente, la regla es demasiado imprecisa para comprobarla frente a una acción o el código circundante muestra lo contrario de lo que indica la regla.
¿Editar el archivo de instrucciones durante la sesión cambia algo?
No para la copia que ya está en la conversación. Los archivos situados por encima del directorio de trabajo se cargan completos al iniciar, por lo que el texto que conserva el modelo es el de ese momento. Para incorporar una edición, inicie una sesión nueva o pida al agente que lea el archivo con sus herramientas de archivos habituales; así, la versión actual se incorpora a la conversación como un mensaje nuevo. Después de una compactación, el archivo de la raíz del proyecto se vuelve a leer del disco, por lo que la nueva versión también se incorpora en ese momento.
¿Qué archivo prevalece cuando un CLAUDE.md raíz y otro anidado se contradicen?
Ninguno de forma fiable. Los archivos descubiertos se concatenan en el contexto en lugar de sobrescribirse. Se ordenan desde la raíz del sistema de archivos hasta el directorio de trabajo, de modo que el archivo más cercano simplemente se lee al final. No existe un motor de precedencia que resuelva las contradicciones, y la documentación de Claude Code indica que las reglas contradictorias pueden resolverse arbitrariamente. Escriba los archivos anidados como adiciones que indiquen la ruta que gobiernan y elimine la contradicción en lugar de intentar imponer una prioridad.
¿Mis instrucciones sobreviven a /compact?
Depende de cómo se hayan cargado. El archivo CLAUDE.md de la raíz del proyecto, las reglas sin ámbito y la memoria automática se vuelven a inyectar desde el disco después de una compactación. Las reglas con frontmatter paths: y los archivos CLAUDE.md anidados en subdirectorios se pierden hasta que se vuelva a leer un archivo correspondiente. Todo lo que haya escrito únicamente en el chat sobrevive sólo si el resumidor decidió conservarlo. Si una regla debe mantenerse durante toda una sesión, colóquela en el archivo de la raíz del proyecto sin frontmatter paths:.
¿Cuándo debe convertirse una regla en un hook en lugar de permanecer como texto?
Cuando la comprobación sea determinista y el coste de omitirla sea mayor que el de escribir un script pequeño. Las restricciones de rutas de archivos, los comandos obligatorios antes de un commit y las llamadas de herramientas prohibidas cumplen este criterio. Un hook PreToolUse que termina con el estado 2 bloquea directamente la llamada de la herramienta y devuelve al modelo el texto de stderr como motivo, por lo que la regla se aplica aunque ya no esté en el contexto. Todo lo que pueda decidir un formateador o un linter debe quedar bajo el control de esa herramienta y eliminarse por completo del archivo de instrucciones.