La recuperación sigue ganando a una ventana de 1M tokens para tu base de código
Hace unas semanas estaba depurando un bug de autenticación en un proyecto secundario — un backend en TypeScript, unos 140 archivos, cómodamente por debajo de un millón de tokens. Tenía a mano un modelo de 1M tokens, así que hice lo cómodo: metí todo el árbol src/ en un único prompt y le pedí al agente que encontrara dónde se refrescaba el token de sesión y por qué a veces no lo hacía.
Lo leyó todo. Me costó una pequeña fortuna en tokens de entrada para ese único turno. Y señaló con confianza un helper refreshToken que parecía correcto pero no lo era — había dos, en módulos distintos, y el que eligió no estaba en la ruta que se ejecutaba. Le había dado todo el pajar y pescó una aguja plausible del medio.
Luego cerré esa sesión, abrí una nueva con el mismo modelo y lo dejé trabajar a su manera habitual: listar el árbol, hacer grep de refreshToken, leer los tres archivos que coincidieron, seguir las importaciones. Encontró el bug real en aproximadamente un cuarto de los tokens y un tercio del tiempo de reloj. El mismo modelo. El mismo repositorio. La diferencia estaba completamente en cómo le había pasado el código.
La versión corta: para una base de código real, volcar todo en una ventana de contexto enorme suele ser el peor movimiento — no porque la ventana sea demasiado pequeña, sino porque los modelos se vuelven mediblemente menos fiables a medida que la llenas, y el código es el input de peor caso para ese fallo. La recuperación dirigida — grep, indexado de símbolos, lectura consciente de dependencias — gana en coste, latencia y precisión para la mayoría de las tareas de código. El contexto largo gana en unos pocos casos específicos, y te daré la regla al final.
El número de la ventana es real; la parte utilizable no lo es
Primero, la parte que es cierta: los números grandes existen. A junio de 2026, los tres modelos de codificación líderes — Claude Opus 4.8, GPT-5.5 y Gemini 3.1 Pro — todos incluyen una ventana de 1M tokens, y más de trece modelos frontier alojados anuncian 1M o más (comparación de ventanas de contexto de Morph). Anthropic y OpenAI incluso eliminaron el recargo por contexto largo, así que ahora se factura a la misma tasa por token en toda la ventana.
El problema es que anunciado y utilizable son números distintos. Las pruebas de recuperación independientes de 2026 siguen mostrando que la capacidad efectiva se queda bastante por debajo de la etiqueta — un resumen sitúa el contexto efectivo en aproximadamente el 50–65% del nominal, y reporta puntuaciones MRCR multi-aguja que caen en picado en la segunda mitad de la ventana: Gemini 3.1 Pro mantiene un ~84.9% de recuperación en la banda de 128K–256K y colapsa al 26.3% en la banda de 512K–1M (análisis "context window lie" de CodingFleet). Toma los porcentajes exactos como indicativos — son cifras de benchmarks de proveedores, no un estudio controlado — pero la forma es consistente en todas partes: la recuperación decae mucho antes de que la ventana esté llena.
Ese declive tiene nombre e historial de investigación, y importa más para el código que para casi cualquier otra cosa.
Por qué el código es el input de peor caso para una ventana completa
Dos efectos bien replicados trabajan en tu contra cuando metes un repositorio en un único prompt.
Perdido en el medio. El artículo de Liu et al. (publicado en TACL) mostró que la precisión del modelo es una función en forma de U según dónde se encuentra la información relevante: máxima cuando está al principio o al final del contexto, y degradándose más del 30% cuando está enterrada en el medio — y esto se cumplió en seis familias de modelos en QA multi-documento y recuperación de pares clave-valor. Una base de código no es otra cosa que "información relevante en el medio". La función que necesitas rara vez es el primer o último archivo que pegaste.
Podredumbre del contexto. El estudio de 2025 de Chroma probó 18 modelos frontier — Claude Opus 4 / Sonnet 4 / 3.7 / 3.5 / Haiku 3.5, OpenAI o3 y la familia GPT-4.1, Gemini 2.5 Pro/Flash, y tres tamaños de Qwen3 — y encontró que el rendimiento cae a medida que crece la longitud del input incluso en tareas triviales como encontrar una cadena o replicar palabras repetidas (informe "Context Rot" de Chroma). El hallazgo que debería incomodar a cualquier desarrollador de agentes de código: en la tarea LongMemEval, todos los modelos lo hicieron peor con el historial completo de ~113k tokens que con un extracto enfocado de ~300 tokens del mismo contenido relevante. Más tokens del material correcto, presentados en bloque, obtuvieron menor puntuación que una pequeña rebanada curada.
Hay un detalle en ese informe que resulta casi cómico si escribes código: los modelos puntuaron peor cuando el pajar "preservaba un flujo lógico de ideas" que cuando estaba desordenado. Un repositorio tiene la máxima estructura lógica — importaciones, grafos de llamadas, definiciones de tipos, módulos ordenados. Le estás dando al modelo exactamente la forma de input que peor gestiona.
Y el código castiga el fallo más duramente que la prosa. Si un chatbot se pierde una frase de un documento largo, da una respuesta algo más vaga. Si un agente de código se pierde la definición real de refreshToken, escribe código que llama a un método que no existe o parchea la función equivocada — y lo hace con confianza. Como señaló un análisis de recuperación de agentes: "el modo de fallo del RAG en contextos de codificación es silencioso y acumulativo" (MindStudio). Una recuperación incorrecta no da error. Se despliega.
Qué significa "recuperación" para el código (mayormente no son embeddings)
Cuando la gente oye "recuperación" imagina una base de datos vectorial. Para el código, los agentes que realmente se despliegan — Claude Code, Cursor, Devin — mayormente no recurren a ella primero. Navegan como lo haría un desarrollador experimentado: mirar el árbol de archivos, hacer grep de un símbolo, leer los archivos concretos que coinciden, seguir la cadena de importaciones (MindStudio). La herramienta de búsqueda principal de Claude Code es ripgrep — coincidencia de texto exacta, rápida y con números de línea que funciona en cualquier repositorio sin preprocesamiento.
Hay una buena razón por la que los vectores no son el estándar para el código, y no es nostalgia. Un marco útil es de tres capas, escala solo cuando lo necesites (búsqueda de código para agentes de IA):
- Léxica (ripgrep): coincidencia exacta, milisegundos, gitignore-aware. Tu opción por defecto.
- Estructural (ast-grep): coincidencia de patrones AST — "encuentra cada función async," "cada catch-and-rethrow" — cosas que regex no puede expresar limpiamente. Escala aquí cuando la consulta es sobre la forma, no sobre cadenas.
- Semántica (embeddings / repo-map): consultas conceptuales en lenguaje natural. Último recurso.
¿Por qué la semántica es el último recurso y no el primero? Porque las consultas que un agente de código genera son cortas y tienen forma de símbolo — auth flow, user service, refreshToken — y ese es precisamente el formato que rompe la búsqueda por embeddings. El benchmark CoREB encontró que las consultas de palabras clave cortas "colapsan casi todos los modelos semánticos probados a cerca de nDCG@10 cero". Los embeddings capturan similitud de significado; el código es un grafo de dependencias, importaciones y definiciones de tipos, y la similitud no es la relación que estás consultando. Dos funciones pueden ser semánticamente casi idénticas y estructuralmente no relacionadas; la que necesitas es la que está en la ruta de llamada, no la que se lee de manera similar.
Eso no hace que el indexado semántico sea inútil — lo convierte en un especialista. Cuando se gana su puesto, las buenas implementaciones no embeden ventanas de texto arbitrarias. Parsean con tree-sitter en unidades reales — funciones, clases, interfaces con sus docstrings intactos — mantienen esos fragmentos enteros, y emparejan la similitud vectorial con la coincidencia de palabras clave BM25 más herramientas de grafo de llamadas para el rastreo de dependencias y el análisis de radio de impacto (opencode-codebase-index). Ese es el juego completo para la recuperación de código: fragmentación consciente de dependencias con límites de símbolo y respaldo de palabras clave — no "divide el archivo cada 512 tokens y reza".
Las matemáticas de coste y latencia que nadie calcula
Deja la precisión a un lado un momento y simplemente pasa la factura. Supón que un repositorio mediano tiene 600K tokens. Meterlo en un turno significa pagar 600K tokens de entrada en cada turno de la conversación a menos que estés cacheando cuidadosamente — e incluso cacheado, cargas con la latencia del modelo atendiendo a todo eso. Un pase de recuperación en cambio envía el árbol (unos pocos KB), un resultado de grep (unos cientos de tokens) y quizás cuatro archivos que realmente lees (~15K tokens). Esa no es una diferencia de redondeo; es uno a dos órdenes de magnitud por turno, multiplicado por cada turno en una sesión de depuración.
La latencia sigue la misma curva. Un modelo razonando sobre 600K tokens es más lento al primer token y en general que el mismo modelo razonando sobre 18K. En un bucle interactivo donde haces veinte turnos para perseguir un bug, eso se acumula en minutos de espera muerta. La recuperación mantiene cada turno pequeño, así que cada turno es rápido, y el bucle se mantiene ajustado.
Y hay un coste más silencioso: el presupuesto de atención. Cada archivo irrelevante en la ventana es una distracción, y Chroma mostró que las distracciones arrastran la precisión de forma medible — una distracción dañó, cuatro la amplificaron. Un repositorio completo en contexto son miles de distracciones para cualquier pregunta concreta. No solo pagas más para ser más lento; pagas más para ser más lento y más impreciso.
Cuándo el contexto largo realmente gana
Esto no es "siempre recuperación". Hay un rango real donde meter todo es la decisión correcta, y está definido por el tamaño del repositorio y la forma de la tarea, no por el tamaño de la ventana por la que estás pagando.
El contexto largo gana cuando:
- Todo el repositorio cabe de verdad con margen — digamos por debajo de ~150K tokens, bien dentro del frente de alta recuperación de la ventana — y la tarea necesita razonamiento entre archivos que es difícil de recuperar por partes. Un repositorio pequeño donde todo importa es exactamente el caso que la recuperación sobre-complica.
- Necesitas razonamiento de archivo completo o módulo completo de una sola vez — un único archivo grande que quieres refactorizar completamente, una lectura de seguridad de principio a fin de un módulo, una revisión arquitectónica donde el modelo necesita tener las relaciones a la vista a la vez. La recuperación lo fragmenta; el contexto lo preserva.
- Es un pase de solo lectura de una sola vez, no un bucle iterativo. Una única llamada "revisa este PR" o "resume cómo funciona este servicio" amortiza el coste en un turno. La economía que mata el contexto largo — pagar la ventana completa en cada turno — no muerde cuando solo hay un turno.
La recuperación gana en todo lo demás, que en la práctica es la mayor parte del trabajo: cualquier repositorio demasiado grande para caber cómodamente, cualquier cosa iterativa, cualquier cosa donde necesites una definición específica en lugar de una comprensión general, y cualquier cosa donde una recuperación silenciosamente incorrecta desplegaría código roto.
Una regla aproximada que uso realmente: si la parte relevante de la tarea es más pequeña que el repositorio, recupera. Si la tarea es todo el repositorio y el repositorio cabe en el primer ~15% de la ventana, cárgalo. La mayoría de los días, la parte es más pequeña que el repositorio.
La conclusión
La ventana de 1M tokens es una capacidad real, y vale la pena usar sus precios sin recargo para los trabajos en los que es buena — revisiones de una sola pasada de código que cabe, razonamiento de módulo completo, el repositorio pequeño ocasional donde todo es relevante. Pero no es un sustituto de saber dónde vive tu código. Para un agente de código que funciona, el stack aburrido — listar el árbol, hacer grep del símbolo, leer los cuatro archivos que coincidieron, seguir las importaciones, escalar a AST o embeddings solo cuando la búsqueda por palabras clave llegue vacía — es más barato, más rápido y más preciso que el impresionante. El número grande en la hoja de especificaciones es una opción, no una instrucción. La mayor parte del tiempo, no la llenes.
