Context Drift en Claude Code: los controles que ya no son manuales
Context drift es la pérdida progresiva de precisión de un agente de código a medida que su ventana de contexto se llena de historial redundante o irrelevante, un efecto que el informe Context Rot de Chroma mide de forma directa: el rendimiento en tareas de coincidencia semántica y en conversaciones largas cae de forma medible mucho antes de agotar el límite nominal de tokens, incluso en modelos que superan sin fallos el benchmark clásico Needle in a Haystack, pensado solo para recuperación literal. La versión anterior de este artículo, hace unos meses, recomendaba compactar a ojo cuando la barra de contexto rondaba el 60%; era una heurística razonable en ese momento, no una regla documentada por Anthropic. Desde entonces Claude Code ha convertido buena parte de esa intuición en controles explícitos: un umbral de auto-compactación que se fija con un comando, checkpoints que se deshacen sin recompactar nada, y una vía para hacer una pregunta sin que entre en el historial. La disciplina útil ya no es memorizar un porcentaje: es saber qué control corresponde a cada momento de la sesión.
Sacar del contexto lo que no necesita entrar
La forma más barata de evitar el context drift es no dejar que algo lo cause. Tres mecanismos mantienen contenido fuera de tu ventana principal desde el origen, sin llegar a necesitar compactación.
Los subagentes ejecutan una tarea en su propia ventana de contexto y devuelven solo un resumen. La documentación de subagentes es clara sobre cuándo conviene cada opción: conversación principal si hay ida y vuelta frecuente, fases que comparten contexto o la latencia importa (un subagente arranca en frío); subagente si la tarea produce salida verbosa que no necesitas en el hilo principal, exige restringir qué herramientas puede usar, o es autocontenida y puede volver como un resumen.
Para preguntas puntuales sobre algo que ya está en la conversación, /btw evita incluso la delegación. Ve todo tu contexto actual pero no tiene acceso a herramientas, y la respuesta aparece en una superposición descartable que nunca entra en el historial: /btw cómo se llamaba ese archivo de configuración. Es la opción correcta cuando la pregunta es sobre algo que Claude ya leyó, no cuando necesitas que investigue algo nuevo.
El tercer mecanismo es silencioso: las definiciones de herramientas MCP se cargan de forma diferida por defecto, así que solo los nombres entran en contexto hasta que Claude usa una en concreto. Si tienes servidores activos que rara vez usas, siguen pesando en ese listado; /mcp te deja verlos y desactivar los que no necesitas en el proyecto, como detallamos en el artículo sobre uso real de servidores MCP.
Decidir cuánto contexto se llena antes de resumir
El umbral al que Claude Code compacta automáticamente ya no es un número fijo que memorizas: se configura. El comando /autocompact acepta una cantidad de tokens, por ejemplo /autocompact 500k, y fija a partir de ahí cuánto se llena la ventana antes de que salte el paso automático, según documenta la guía de la ventana de contexto de Claude Code. Bajarlo tiene sentido en sesiones donde prefieres resúmenes más frecuentes y baratos sobre un único contexto enorme; subirlo tiene sentido cuando trabajas con un modelo de ventana grande y quieres aprovecharla entera antes de perder detalle.
Ese "entera" depende del modelo y de dónde lo ejecutas. Según la documentación de ventanas de contexto, Claude Sonnet 5 corre con 1M de tokens por defecto sin cabecera beta, y Opus 5, Opus 4.8, Opus 4.7, Opus 4.6, Sonnet 4.6 y Fable 5 también admiten 1M. Pero Sonnet 4.6 y Opus 4.6 sin contexto extendido, y Opus 4.8 u Opus 5 corriendo a 200K (habitual en Amazon Bedrock, la plataforma de agentes de Google Cloud o Microsoft Foundry), compactan en ese límite de 200K aunque la ficha del modelo anuncie 1M. La variable CLAUDE_CODE_DISABLE_1M_CONTEXT=1 fuerza ese mismo límite incluso en un modelo con ventana nativa de 1M, útil si prefieres compactaciones más frecuentes y baratas.
Compactar con intención en vez de con suerte
Cuando el resumen automático ocurre a ciegas, decide por su cuenta qué es relevante y a veces se equivoca. /compact acepta instrucciones: /compact enfócate en el bug de autenticación y los archivos que tocamos conserva lo que tu elijas en vez de lo que el paso automático adivina. En una sesión recién abierta sin historial, /compact simplemente responde que no hay suficientes mensajes para compactar.
Esa misma preferencia se puede fijar de forma permanente en CLAUDE.md, para no tener que repetirla cada vez:
# Compact instructions
Al compactar, prioriza:
- Decisiones de arquitectura tomadas en la sesión (con el porqué)
- Lista de archivos modificados y su estado (probado / pendiente)
- Tests que fallan y la hipótesis actual sobre la causa
- Comandos exactos usados para reproducir el problema
Descarta sin preguntar: salidas completas de grep o find ya resueltas,
diffs de commits ya aplicados, y exploraciones de rutas que se descartaron.
Este bloque vive en tu CLAUDE.md junto al resto de instrucciones del proyecto y se aplica automáticamente en cada compactación, manual o automática, según confirma la guía de gestión de costes de Claude Code.
Deshacer sin recompactar: checkpoints y /rewind
Compactar no es la única herramienta para recuperar el control de una sesión que se desvía. Claude Code crea un checkpoint automático antes de cada prompt tuyo y guarda los cien más recientes de la sesión, según la documentación de checkpointing. Descartar un checkpoint antiguo borra los ficheros que ningún checkpoint restante referencia ya, excepto la primera instantánea de cada archivo, que la extensión de VS Code usa como base para sus diffs de sesión.
/rewind, o pulsar Escape dos veces con el campo de entrada vacío, abre el menú de rewind para volver a un punto anterior de código y conversación sin tocar el resumen que ya tengas compactado. Los checkpoints se guardan junto con la conversación, así que /rewind sigue funcionando después de retomar una sesión con claude --resume. Por defecto se eliminan a los 30 días junto con la sesión; el ajuste cleanupPeriodDays en settings.json cambia ese periodo si necesitas retención más larga.
La diferencia práctica con /compact: rewind deshace, compact resume. Si Claude tomó un camino equivocado hace diez minutos, rewind es más barato y más preciso que dejar que un resumen intente reconstruir por qué se descartó ese camino.
Qué le corresponde a la memoria automática, y qué no
La memoria automática de Claude Code (el archivo MEMORY.md que Claude escribe solo entre sesiones) tiene su propio artículo con el detalle de configuración, comandos y casos de uso en Claude Code Auto-Memory: el contexto que persiste solo. Aquí importan dos límites que afectan directamente a la gestión de contexto de una sesión larga.
Primero, el límite de carga automática no son "200 líneas" sin más: es un límite doble (200 líneas o 25 KB, lo que se alcance antes), con el detalle completo ya cubierto en el artículo de auto memory enlazado arriba. Segundo, la memoria automática de la conversación principal no se carga en los subagentes que lances: un subagente que explora 15 archivos no hereda tus notas de sesiones anteriores, parte con la ventana más limpia posible, otro motivo por el que delegar exploración es defensa contra el drift y no solo ahorro de tokens.
CLAUDE.md flaco: la base que sigue funcionando
Con todos estos controles nuevos, la disciplina original sobre CLAUDE.md no ha perdido vigencia, solo ha dejado de ser la única defensa. La misma documentación de memoria lo respalda de forma directa: los archivos CLAUDE.md se cargan completos sin importar su longitud, pero los archivos más cortos producen mejor adherencia a las instrucciones. Un archivo de 400 líneas no falla por límite técnico, falla porque las instrucciones del final compiten por atención con las del principio, el mismo mecanismo que documenta Chroma a escala de conversación completa.
El criterio práctico sigue siendo el de progressive disclosure: instrucciones y decisiones que un linter no puede derivar van en CLAUDE.md; documentación de API, listados de endpoints o el histórico de decisiones van en un archivo aparte que Claude lee bajo demanda cuando lo necesita, no en la carga inicial de cada sesión.
| Va en CLAUDE.md | Va en un archivo de referencia aparte |
|---|---|
| Comandos de build y test exactos | Documentación completa de la API |
| Decisiones de arquitectura no derivables del código | Listado de endpoints, modelos o schemas |
| Convenciones que el linter no cubre | Histórico de decisiones (eso va en commits o ADRs) |
| Instrucciones de compactación del proyecto | Reglas que ya aplica un formatter automático |
Los límites que no dependen de ti: plan, proveedor y modelo
Vale la pena cerrar con los casos donde ninguno de estos controles compensa una limitación de plataforma. Si tu equipo accede a Claude Code a través de Amazon Bedrock, la plataforma de agentes de Google Cloud o Microsoft Foundry, es posible que estés corriendo con ventana de 200K incluso en un modelo cuya ficha anuncia 1M; el límite real lo fija la superficie, no el nombre del modelo, así que si una sesión compacta "antes de tiempo" comparada con lo que esperabas, este suele ser el motivo antes que un bug.
Para el problema inverso (un CLAUDE.md que ya no describe el proyecto real, con rutas que ya no existen o comandos que cambiaron), hay una herramienta de terceros pensada para eso: context-drift, un CLI que revisa de forma determinista cuánto tiempo lleva sin tocarse cada archivo de contexto, si las dependencias que menciona siguen en package.json, pyproject.toml, go.mod o Cargo.toml, si las rutas y comandos que cita existen todavía en el repositorio, y si hay conflictos cruzados, como un CLAUDE.md que dice npm test mientras un AGENTS.md del mismo repo dice yarn test. Es un chequeo mecánico, no sustituye la revisión humana, pero detecta la desincronización que un archivo de contexto acumula sin que nadie lo note hasta que Claude sigue una instrucción que ya no aplica.