“Spotify redujo 90% los tokens de Claude Code”
No fue una optimización aplicada a toda la ingeniería de Spotify ni una mejora interna de Claude: fue un experimento con Portal by Spotify que delegó las tareas intensivas en entrada y salida a un modelo más económico.
La idea detrás del resultado sí es importante: un agente de programación no necesita utilizar su modelo más capaz para cada archivo que lee ni para cada bloque de código repetitivo que genera.
Qué hizo realmente Spotify
Dimitri Mazmanov, Principal Product Manager de Spotify, describió un flujo personal en el que Claude Code conserva las tareas que requieren razonamiento, mientras que Gemini 2.5 Flash funciona como modelo auxiliar para procesar grandes cantidades de texto y generar código predecible.
En las pruebas publicadas por Spotify Engineering, el sistema se evaluó sobre un monorepo Java mediante cuatro escenarios. Las tres pruebas cuantificadas de lectura consiguieron reducciones del 82%, 94% y 94% en los tokens que entraban al contexto de Claude. La media para esas lecturas masivas fue cercana al 90%.
No significa que cualquier sesión de Claude Code vaya a consumir 90% menos. Tampoco significa que el trabajo desaparezca: los archivos siguen siendo procesados y, por tanto, siguen consumiendo tokens en el modelo auxiliar. El ahorro ocurre en la parte más cara del flujo, porque Claude recibe un resumen pequeño en lugar del contenido completo.
El problema: usar el modelo más caro para mover texto
Un agente de código combina varios tipos de trabajo:

- Explorar archivos para localizar una función.
- Leer implementaciones completas para responder una pregunta concreta.
- Comparar patrones repetidos entre pruebas.
- Generar configuración, stubs o boilerplate.
- Depurar condiciones de carrera.
- Tomar decisiones de arquitectura.
Las primeras cuatro actividades pueden consumir mucho contexto sin requerir el mismo nivel de razonamiento que las últimas dos. Leer 7,000 líneas para identificar qué métodos acceden a la base de datos es principalmente una operación de búsqueda, extracción y compresión. Detectar un error sutil de concurrencia exige otro nivel de análisis.
Si ambas tareas se ejecutan con el mismo modelo, se paga capacidad de razonamiento avanzada incluso cuando el cuello de botella real es la cantidad de texto.
La solución de Spotify separa estas responsabilidades en tres rutas: las lecturas masivas van a un modelo rápido que devuelve un resumen compacto; el boilerplate va a un modelo rápido que escribe el resultado en disco; y el debugging o la arquitectura permanecen en Claude.
Claude continúa coordinando el trabajo, pero deja de absorber todo el material intermedio.
Dos workers especializados
La implementación utiliza AiKA Modes, agentes declarativos ejecutados mediante Portal by Spotify. Cada modo define sus instrucciones, modelo, temperatura y herramientas disponibles. La documentación de AiKA Modes confirma que un modo puede seleccionar un modelo diferente, incorporar herramientas MCP y publicarse para reutilizarse dentro de una organización.
El experimento configura dos modos.
bulk-reader: leer mucho y devolver poco
bulk-reader recibe uno o varios archivos junto con una pregunta concreta. Utiliza Gemini 2.5 Flash para leer el corpus y devuelve únicamente una respuesta estructurada y breve.
Por ejemplo, en lugar de introducir dos servicios completos en el contexto de Claude para preguntar qué métodos consultan una base de datos, el worker procesa los archivos y responde con los nombres y ubicaciones relevantes. Claude recibe el resultado útil, no miles de líneas de entrada.
Cada invocación es efímera. Si hay una segunda pregunta, los archivos vuelven a enviarse al worker. Parece repetitivo, pero esa repetición ocurre fuera del contexto costoso que se intenta proteger.
code-writer: escribir sin devolver el archivo a Claude
code-writer se ocupa de pruebas repetitivas, archivos de configuración, stubs y otros resultados que pueden derivarse de un patrón existente. Recibe una especificación y un archivo de referencia, genera el contenido y puede escribirlo directamente en disco.
Este detalle evita dos consumos:
- Claude no necesita leer todos los ejemplos utilizados como referencia.
- El código generado no tiene que regresar completo al contexto de Claude.
El archivo de referencia es obligatorio porque limita la generación al estilo real del proyecto. Sin esa referencia, el modelo económico produciría código genérico que podría no respetar nombres, estructura o convenciones locales.
El router no es solo un prompt
La primera versión consistía en reglas escritas en CLAUDE.md. Claude debía interpretar esas instrucciones y decidir por sí mismo cuándo delegar. El problema era que las reglas eran recomendaciones: el modelo podía ignorarlas y cada repositorio necesitaba mantener su propia copia.
La versión actual utiliza un plugin llamado shunt. Su arquitectura tiene tres capas.
1. Hooks que hacen cumplir la decisión
Antes de cada llamada a una herramienta, el plugin inspecciona la operación mediante hooks PreToolUse. La documentación oficial de Claude Code explica que estos hooks se ejecutan antes de una herramienta y pueden permitir, modificar o bloquear el flujo según su configuración.
shunt registra dos controles:
check-file-sizeintercepta lecturas completas. Si un archivo supera 350 líneas de forma predeterminada, bloquea la operación y dirige a Claude haciabulk-reader.check-bash-readdetecta intentos equivalentes mediantecat,head,tail,lessomore.
Las lecturas específicas con desplazamiento o límite sí pasan. Si Claude ya sabe qué fragmento necesita editar, no tiene sentido enviar esa sección a otro modelo.
El umbral puede cambiarse mediante SHUNT_MIN_LINES. Su función no es encontrar un número universal, sino evitar que la latencia de delegar cueste más que el ahorro obtenido con archivos pequeños.
2. Scripts que aíslan la integración
Dos scripts construyen las solicitudes, invocan Portal, gestionan errores y limpian la salida. Claude llama una interfaz estable con argumentos definidos en lugar de improvisar comandos complejos durante cada sesión.
bulk-read delimita los archivos con etiquetas XML para conservar sus fronteras. code-write elimina bloques Markdown de la respuesta y, cuando recibe un destino, guarda el código directamente.
3. Skills que enseñan cuándo delegar
Las skills describen a Claude qué tareas pertenecen a cada worker y cómo llamar los scripts. No son el mecanismo de cumplimiento: facilitan la decisión, mientras que los hooks impiden que una lectura masiva continúe por la ruta cara.
Esta combinación es más fiable que confiar únicamente en instrucciones. La skill orienta; el hook aplica una política determinista.
Qué muestran realmente los benchmarks
El repositorio de shunt publicado en GitHub contiene los escenarios y resultados resumidos:
| Escenario | Sin shunt | Con shunt | Ahorro en Claude |
|---|---|---|---|
| Archivo Java de 4,014 líneas | 33,684 tokens | 5,737 tokens | 82% |
| Código y prueba, 7,408 líneas | 75,990 tokens | 4,148 tokens | 94% |
| Varios archivos, 1,281 líneas | 16,221 tokens | 821 tokens | 94% |
| Generación de pruebas desde una referencia | 40,614 tokens más la salida | 833 líneas escritas en disco | No comparable directamente |
La media del 90% corresponde a los tres casos de bulk-reader. El escenario de generación no tiene un porcentaje equivalente porque el flujo optimizado escribe el resultado directamente en disco y Claude nunca recibe esas 833 líneas.
También es importante observar qué mide la tabla: tokens consumidos por Claude, no el total agregado de todos los modelos. Para calcular ahorro económico real habría que sumar el consumo de Gemini, las tarifas de cada proveedor y cualquier costo de Portal. El artículo original demuestra una reducción de contexto en el modelo principal, no publica una auditoría completa de costos.
Lo que el router no debe delegar
El propio experimento identifica límites claros.
Ediciones que requieren contexto exacto
Los resúmenes del worker no conservaron ubicaciones suficientemente fiables para editar código. Claude todavía necesita leer directamente el fragmento específico antes de modificarlo. Por eso el hook permite lecturas con offset y limit.
Debugging y decisiones de arquitectura
Durante las pruebas, el modelo auxiliar encontró patrones superficiales, pero no detectó un problema sutil de seguridad entre hilos. Claude lo reconoció cuando recibió el contexto adecuado.
La configuración excluye deliberadamente debugging, decisiones arquitectónicas y código crítico para la seguridad. El router busca eficiencia, no reemplazar razonamiento especializado con el modelo más barato disponible.
Operaciones pequeñas
Cada delegación añade un viaje de red. Spotify reporta respuestas de aproximadamente 10 a 30 segundos y un límite de 30 segundos por invocación en Portal. Para archivos pequeños, esa latencia puede superar cualquier ventaja.
Generaciones demasiado grandes
La integración transporta la entrada mediante argumentos de línea de comandos y está limitada por el tamaño máximo admitido por el sistema operativo. El README de shunt advierte además que las generaciones extensas deben dividirse para no exceder el tiempo máximo de Portal.
Cómo aplicar la misma idea sin Portal
Portal y AiKA resuelven la configuración, ejecución y distribución de los workers, pero el patrón puede implementarse con otras herramientas. Los componentes esenciales son los siguientes.
1. Clasificar las tareas por capacidad necesaria
Antes de elegir modelos, define categorías explícitas:
| Ruta económica | Ruta avanzada |
|---|---|
| Resumir archivos grandes | Depurar fallos no evidentes |
| Extraer símbolos o dependencias | Diseñar arquitectura |
| Generar boilerplate desde una referencia | Revisar código sensible |
| Actualizar documentación repetitiva | Resolver requisitos ambiguos |
| Clasificar resultados de herramientas | Aprobar cambios destructivos |
El ahorro nace de una clasificación restrictiva. Si la ruta económica acepta “cualquier tarea sencilla”, terminará recibiendo problemas que parecían triviales pero requerían contexto o criterio.
2. Interceptar antes de consumir contexto
El router debe actuar antes de que el agente principal lea el archivo. Decidir después no recupera los tokens ya enviados.
En Claude Code esto puede implementarse con PreToolUse. En otro agente puede ser un middleware alrededor de sus herramientas, una regla en el servidor MCP o una capa propia que evalúe tamaño, tipo de operación y riesgo.
Una política mínima podría ser:
si lectura_completa y lineas > umbral: usar worker de lecturasi generación_predecible y existe referencia: usar worker de escriturasi debugging, arquitectura o seguridad: conservar modelo avanzado3. Diseñar contratos de salida compactos
Enviar una tarea a un modelo barato no ayuda si este devuelve una explicación extensa. El worker debe responder con un contrato limitado: símbolos, rutas, rangos aproximados, evidencias y una conclusión corta.
Para generación, conviene solicitar únicamente código y escribirlo fuera del contexto del orquestador. Después, el agente principal puede revisar un diff o ejecutar pruebas en lugar de leer toda la salida de nuevo.
4. Escalar cuando exista incertidumbre
El worker necesita una forma explícita de rechazar una tarea. Si faltan datos, detecta ambigüedad o encuentra código crítico, debe devolver un estado de escalamiento y no inventar una respuesta para cumplir el formato.
La ruta avanzada debería recibir la pregunta original, el resumen del worker y solo los fragmentos relevantes. Así se conserva el ahorro sin ocultar la incertidumbre.
5. Medir el costo total
No basta con contar tokens de Claude. Un benchmark útil debe registrar:
- Tokens de entrada y salida de cada modelo.
- Precio efectivo por modelo y proveedor.
- Latencia agregada por delegación.
- Porcentaje de tareas que requieren repetición o escalamiento.
- Errores introducidos por resúmenes incompletos.
- Tiempo de revisión humana.
Una reducción de tokens puede dejar de ser ahorro si duplica la latencia, provoca reintentos o exige que el modelo principal vuelva a leer los archivos completos.
La lección para equipos que usan agentes de código
La optimización no consiste simplemente en reemplazar Claude por Gemini Flash. Consiste en impedir que el modelo de mayor capacidad reciba información que no necesita.
El router de shunt consigue esto con cuatro decisiones acertadas:
- Detecta las operaciones costosas antes de ejecutarlas.
- Delega únicamente trabajo intensivo en entrada o salida.
- Mantiene el razonamiento y las decisiones sensibles en Claude.
- Devuelve resúmenes compactos o escribe los resultados directamente en disco.
La documentación de costos de Claude Code propone una optimización relacionada: preprocesar salidas grandes mediante hooks para que el modelo reciba solo los datos relevantes. Spotify lleva ese principio un paso más allá al convertir el preprocesamiento en una capa de routing entre modelos.

