▮ CLAUDE-CORE · ACADEMYCLAUDE CODE v2.1.143CCROUTER · MODEL LAYER ▮
ENRUTA LACAPA DE MODELO
Usa la UX de Claude Code con cualquier modelo — sin perder el loop. Cuatro módulos de teoría, ocho configs de enrutamiento copia-pega. ~25 minutos.
Por qué existe esta class
Claude Code habla con un solo modelo por defecto — el de Anthropic. Pero el turn más caro de tu sesión (un file walk, un resumen de output de grep, una limpieza de comentarios) no necesita razonamiento nivel Opus. CCRouter se sienta entre el cliente de CC y cualquier provider, enruta cada request al modelo que encaja con el trabajo, y se mantiene invisible al agent loop. La asimetría de costo por sí sola paga el setup. La diversidad de modelos desbloquea workflows que el camino single-vendor no alcanza.
Lo que vas a aprender
Lo que CCRouter realmente intercepta y por qué es seguro.
Las seis rutas (default, background, think, longContext, webSearch, image) y cuándo dispara cada una.
El config.json mínimo que te saca de la factura de Anthropic para trabajo rutinario.
Ocho patrones de enrutamiento listos para producción: tope de costo, failover, override por proyecto, transformer custom.
Validado contra
Claude Code v2.1.143 · @musistudio/claude-code-routerv1.0.x. CCRouter es un proyecto open-source de terceros (26.4k stars a mayo de 2026) y se mueve rápido — los shapes de config aquí están validados contra los docs canónicos pero verifica los nombres de campo contra tu versión instalada antes de copiar y pegar.
§1
¿Por qué enrutar?
fundamentos
TL;DR — tres presiones te sacan del default single-vendor: asimetría de costo (Opus pricing en trabajo rutinario), diversidad de modelo (contexto largo de Gemini, razonamiento-por-dólar de DeepSeek, Ollama local para privacidad) y vendor lock-off (mantén la UX de CC, elige el modelo). CCRouter es la forma más barata de atacar las tres a la vez.
▸ Asimetría de costo — la cuenta que nadie hace
Una sesión típica de Claude Code mezcla unos pocos turns pesados de razonamiento con muchos turns baratos — lecturas de archivo, walks de directorio, resúmenes de output de tools. Tratar cada turn como clase Opus es pagar precio Opus por trabajo clase Haiku. La medición de comunidad para heavy users de CC cae rutinariamente en el rango de 50–99% de ahorro cuando el tráfico rutinario se desvía — el número exacto depende de tu ratio read/write.
▸ Diversidad de modelo — capacidades que Anthropic no entrega
Gemini 2.5 Pro — contexto de 2M tokens. Útil cuando necesitas razonar sobre un monorepo entero, un log largo, o un transcript gigante.
DeepSeek V3 / R1 — alta calidad de razonamiento por una fracción del precio Opus. Buen fit para rutas "think".
Ollama (local) — corre offline, nunca manda bytes fuera de tu máquina. La jugada de privacidad / industria regulada.
Groq / SiliconFlow / Together — latencia muy baja para el camino "default" cuando la responsividad importa más que la calidad de tope.
▸ Vendor lock-off — misma UX, cualquier modelo
El valor de CC es el loop, el permission model, el sistema de hooks, los slash commands — no el modelo. CCRouter te deja mantener todo eso mientras eliges la capa de inferencia por tarea. La posición oficial es "Usa Claude Code como base para infraestructura de coding, permitiéndote decidir cómo interactúas con el modelo mientras disfrutas los updates de Anthropic" — misma UX, tus decisiones de modelo.
▸ Cuándo NO instalar CCRouter
Si tu sesión es chica, tu gasto es <$20/mes, o nunca lo pensaste — no te molestes. CCRouter es superficie operacional; el momento correcto para adoptarlo es cuando tu factura de CC es lo suficientemente grande para que costo de setup < ahorro de un mes. Para la mayoría de hobby users, la respuesta es "no". Para quien corre sesiones /goal headless en CI todas las noches, la respuesta es "probablemente sí".
TL;DR — CCRouter es un proxy local en 127.0.0.1:3456. Habla el shape de la API de Anthropic del lado client y el shape de la API de cualquier provider del lado server. CC cree que está hablando con Anthropic; el provider cree que está hablando con su client nativo. Los transformers hacen la traducción.
▸ El camino del request
Claude Code (con ANTHROPIC_BASE_URL=http://127.0.0.1:3456)
│
▼
CCRouter (proxy local, tu máquina)
│
│ 1. parse del request en shape Anthropic
│ 2. clasifica ruta: default | background | think | longContext | webSearch | image
│ 3. consulta Router[route] → provider + modelo
│ 4. aplica transformers (lado request)
│
▼
Provider (OpenRouter · DeepSeek · Ollama · Gemini · Groq · …)
│
▼ response
CCRouter (transformers — lado response)
│
▼
Claude Code (ve response en shape Anthropic, nunca supo)
▸ Lo que CCRouter ve
Cada POST /v1/messages que CC hace — el prompt completo, system message, definiciones de tool.
Conteos de tokens (para la decisión del longContextThreshold).
Tool calls y sus argumentos — para los transformers que necesitan reescribir shapes de tool por provider.
▸ Lo que CCRouter NO ve
Tu filesystem. CC lee archivos; CCRouter solo ve lo que CC ya serializó en el request.
Hooks. Corren dentro del proceso de CC, antes/después de la frontera de request que CCRouter intercepta.
Tu API key de Anthropic — cuando enruta a un provider no-Anthropic, la key de Anthropic nunca se manda.
▸ Transformers — el pegamento entre los shapes de API
Cada provider tiene sus quirks: DeepSeek retorna un campo reasoning_content, Gemini quiere safetySettings, OpenRouter espera un header HTTP-Referer. Los transformers built-in (deepseek, gemini, openrouter, groq, maxtoken, tooluse, reasoning, sampling, enhancetool, cleancache, vertex-gemini) manejan los casos conocidos. Los transformers custom manejan el resto — ver receta R8.
▸ Por qué esto es seguro
El proxy hace bind en 127.0.0.1, no 0.0.0.0 — ningún tráfico externo llega. El campo top-level opcional APIKEY exige que clients (incluyendo CC) manden un header Authorization que coincida, defendiendo contra otros procesos locales que peguen al endpoint. La env var NO_PROXY=127.0.0.1 que ccr activate setea evita que tu proxy HTTP corporativo husmee tráfico de localhost.
TL;DR — npm install -g @musistudio/claude-code-router, escribe un ~/.claude-code-router/config.json mínimo, levanta con ccr code en vez de claude. Cinco minutos de cero al primer turn enrutado.
ccr code — arranca el router Y lanza Claude Code de una. El camino más simple.
ccr start y después claude — corre el proxy como proceso separado, usa el binario claude normal. Útil cuando varias instancias de CC comparten un router.
eval "$(ccr activate)" — exporta ANTHROPIC_BASE_URL, ANTHROPIC_AUTH_TOKEN, NO_PROXY en tu shell. Después de esto, cualquier invocación de claude en ese shell usa el router hasta que salgas.
▸ Verificá que funciona
# en otra terminal, con CCR corriendo
curl -s http://127.0.0.1:3456/health
# → {"ok":true}
# en tu sesión de CC
/cost
# → mirá el campo "model"; si dice "deepseek-chat" en vez de
# un nombre de modelo Anthropic, estás enrutado.
▸ Otros comandos CLI útiles
ccr ui — editor web de config en http://127.0.0.1:3456/ui. Más fácil que editar JSON a mano.
ccr model — picker interactivo de modelo para la sesión actual (overridea el Router.default).
TL;DR — CCRouter clasifica cada request entrante en una de seis rutas y mapea la ruta a un par provider+modelo. default es el fallback; las otras cinco disparan en features observables del request.
▸ Las seis rutas — cuándo dispara cada una
default todo request que no coincide con una ruta más específica
background dispatches de sub-agent; reads/writes en masa; trabajo no-interactivo
think requests donde el system prompt o tools implican profundidad de razonamiento
longContext conteo de tokens prompt+historia > longContextThreshold (default 60000)
webSearch request usa la tool WebSearch
image request contiene imagen (beta)
Las rutas se evalúan en orden de especificidad. longContext le gana a default;
webSearch le gana a default. Lo específico le gana a lo genérico — exactamente
una ruta dispara por request.
Lee como cascada: cualquier cosa pesada/razonamiento se queda en modelos premium; rutina y trabajo en masa va al camino barato; long-context va al modelo con la ventana más grande.
▸ El campo longContextThreshold
Un campo numérico en el objeto Router — el conteo de tokens sobre el cual la ruta longContext dispara. Default 60000. Bajalo (40000) si querés sesgar hacia el modelo long-context antes, subilo si las llamadas a Gemini se están comiendo tu budget en requests de tamaño de frontera.
El campo name es lo que referenciás en el bloque Router (ej: "longContext": "gemini,gemini-2.5-pro" — la coma separa el nombre del provider del nombre del modelo).
▸ Once transformers built-in
deepseek, gemini, openrouter, groq, maxtoken (limita tokens de output), tooluse (reescribe tool calls), reasoning (maneja reasoning_content), sampling (altera temperature/top_p), enhancetool, cleancache, vertex-gemini. Aplicá a nivel provider vía transformer.use, o escopá a modelos específicos vía transformer.<model-name>.use.
Cada receta: Cuándo · Config · Configuración · Trampa. Todas las configs son fragmentos — encajalas en el slot correcto de tu config.json.
R1
Manda tareas background a un modelo barato
costo
Cuándo — dispatches de sub-agent, passes de indexing, reads de archivo en masa — trabajo necesario pero que no necesita razonamiento nivel Opus. Mantené el agent parent en premium, mandá todo lo marcado como background a DeepSeek (u otro modelo barato-y-bueno).
Pegalo en ~/.claude-code-router/config.json. Levantá con ccr code. Los dispatches normales de sub-agent de CC ahora corren en DeepSeek — sin cambios en tus llamadas a la tool Agent.
Trampa — el comportamiento de tool-use de DeepSeek difiere del de Anthropic; el transformer deepseek maneja los casos comunes pero si un sub-agent espera output JSON muy estricto podés necesitar el transformer tooluse también: "transformer": { "use": ["deepseek", "tooluse"] }.
R2
Enruta long-context a Gemini 2.5 Pro
capacidad
Cuándo — estás razonando sobre un monorepo entero, un log de miles de líneas, o un transcript gigante. La ventana de Anthropic es ancha pero Gemini 2.5 Pro con 2M tokens es más ancha. Enrutá solo los requests que lo necesitan.
El threshold es un conteo de tokens entrantes (prompt + historia). Una vez que lo cruzás, cada turn por el resto de la sesión probablemente queda arriba — así que Gemini queda en juego. Bajá el threshold a 40000 si querés handoff más temprano; subilo a 120000 si solo querés tareas repo-wide reales saliendo enrutadas.
Trampa — los safety filters de Gemini pueden rechazar contenido que Anthropic acepta (ej: investigación de seguridad, ciertos samples de código). El transformer gemini desactiva los defaults más agresivos, pero código de producción tocando cualquier cosa adversarial — tests de auth, fuzzing — puede rebotar. Mantené una cadena de fallback (receta R5).
R3
Local-first vía Ollama (offline / privado)
privacidad
Cuándo — trabajo air-gapped, industria regulada (salud, defensa, finanzas con datos de cliente), viaje offline, o solo preferencia: ningún token sale de tu máquina. Ollama corre un server OpenAI-compatible local; CCRouter enruta a él como a cualquier otro provider.
▸ Prerrequisitos
# instalá ollama + tirá de un modelo de coding
brew install ollama
ollama serve &
ollama pull qwen2.5-coder:32b # o deepseek-coder-v2, llama3.3:70b, etc.
Ollama tiene que estar corriendo antes de ccr start (o ccr code). En macOS, la formula de brew instala un servicio launchd; en Linux querés un unit systemd. Confirmá que está al aire con curl localhost:11434/api/tags.
Trampa — los modelos locales quedan sustancialmente detrás de los modelos de frontera en tool-use y razonamiento. Esperá más loops de "voy a tener que pensar esto", tool calls malformados ocasionales, y throughput más lento. Un modelo 32B en un Mac M-series entrega 20–40 tokens/seg; modelos más chicos son más rápidos pero peores. La ganancia de privacidad/costo es real, el gap de calidad también es real.
R4
Sub-agents a Haiku, parent a Opus
costo
Cuándo — tu agent parent dispara muchos sub-agents (investigación, file walks, validación) y cada sub-agent solo necesita seguir un handoff bien apretado. Corré el parent en Opus para orquestación; corré sub-agents en Haiku. Mismo vendor, split dramático de costo.
Los dispatches de sub-agent se clasifican como background automáticamente por el shape del request de CC (cargan un system prompt diferente y tienen parent_tool_use_id). Ninguna config necesaria del lado de CC — el parent se queda en Opus, los dispatches downgradan transparentemente.
Trampa — si forzaste un handoff de delegación de 5 campos (ver cookbook R6), Haiku está bien. Si tus handoffs son flojos, Haiku va a llenar los huecos con suposiciones que Opus no habría hecho. La disciplina en la frontera del dispatch es lo que hace esto seguro.
R5
Cadena de failover: Anthropic → OpenRouter
confiabilidad
Cuándo — cargas headless de producción donde la caída de un solo provider no debería matar tu sesión /goal. CCRouter no tiene un operador de chain built-in, pero OpenRouter es él mismo un meta-provider con semántica de fallback — encadená a nivel OpenRouter, apuntá la ruta secundaria de CC allí.
Cuando Anthropic directo está al aire, tu camino default pega directo (más barato, menor latencia). Si falla (raro), podés cambiar "default" a la ruta de OpenRouter con una edición de config + ccr stop && ccr start (o usá ccr ui para edición en vivo). Failover automático real requiere un script de router custom — fuera del alcance de esta receta.
Trampa — OpenRouter agrega su propio margen (~5%) sobre el pricing del provider, y agrega un network hop. No lo hagas tu camino primario a menos que valores específicamente la semántica de chain. Es una capa de seguro, no un daily driver.
R6
Tope diario con API_TIMEOUT_MS
costo
Cuándo — estás corriendo sesiones /goal desatendidas y un loop fuera de control podría quemar el budget de una semana en una noche. CCRouter no tiene un enforcer de budget en $ built-in, pero combinar API_TIMEOUT_MS con claude -p --max-budget-usd a nivel CC te da dos topes.
▸ Fragmento de config
{
"API_TIMEOUT_MS": 120000, // tope de 2 min por request
"LOG": true,
"LOG_LEVEL": "info",
"Providers": [ /* ... */ ],
"Router": { /* ... */ }
}
▸ Configuración — pareando con tope de budget de CC
# /goal headless con budget Y timeout por request
ccr start &
claude -p \
--permission-mode bypassPermissions \
--max-turns 40 \
--max-budget-usd 2.00 \
--output-format json \
"/goal cada issue marcado 'needs-triage' es procesado. Frená tras 40 turns."
Trampa — API_TIMEOUT_MS en CCRouter solo limita un único request. Un loop fuera de control de 100 turns todavía puede acumular gasto si cada turn es rápido. La flag --max-budget-usd en claude -p es el tope hard real; tratá API_TIMEOUT_MS como guardia de "no quedar colgado en un provider flaky", no como primitiva de budget.
R7
Override de enrutamiento por proyecto
alcance
Cuándo — la mayoría de proyectos quiere la cadena cheap-default, pero un proyecto específico (datos regulados, refactor de alto riesgo) necesita quedarse en Anthropic para todo. Apagá CCR solo para ese workspace sin desinstalar.
▸ Enfoque 1 — env escopada por workspace
# en el .envrc (direnv) del proyecto o el rc del shell
unset ANTHROPIC_BASE_URL
unset ANTHROPIC_AUTH_TOKEN
# en este workspace, claude habla directo con Anthropic
▸ Enfoque 2 — configs distintas por path
# levantá CCR con una config específica del proyecto
CCR_CONFIG_PATH=~/.claude-code-router/configs/regulated.json ccr code
# (o symlinkeá ~/.claude-code-router/config.json antes de cada sesión)
▸ Configuración — ejemplo direnv
# .envrc en el proyecto de alto riesgo
export ANTHROPIC_API_KEY="sk-ant-..." # directo
unset ANTHROPIC_BASE_URL # para que claude no pegue a CCR
unset ANTHROPIC_AUTH_TOKEN
# todos los otros proyectos mantienen ccr activate activo
Trampa — no hay "config por proyecto" de primera-clase en CCRouter hoy; el enfoque de env escopada por workspace es la respuesta pragmática. Si cambiás seguido, mantené dos configs nombradas (config-cheap.json, config-direct.json) y symlinkeá — más fácil que acordarte de unset/reset env cada vez.
R8
Transformer custom — descarta reasoning tokens
compat
Cuándo — estás enrutando a un modelo de reasoning (DeepSeek R1, estilo o3) y el output de reasoning_content se está filtrando a la vista de transcript de CC, comiendo contexto. Un transformer custom puede descartarlo del lado server antes de que CC vea el response.
// ~/.claude-code-router/plugins/strip-reasoning.js
module.exports = {
name: "strip-reasoning",
transformResponse(response, _request, _options) {
if (response?.choices) {
for (const c of response.choices) {
if (c.message && c.message.reasoning_content) {
delete c.message.reasoning_content;
}
}
}
return response;
}
};
▸ Configuración
Reiniciá CCR tras la edición (ccr stop && ccr start). Testeá emitiendo un request que pegue a la ruta think e inspeccionando el transcript de CC — la chain de razonamiento debería haber desaparecido, solo queda la respuesta.
Trampa — descartar reasoning ayuda al budget de contexto pero perdés visibilidad del por qué el modelo tomó una decisión. Para trabajo de alto riesgo, logueá el reasoning_content a un archivo en el transformer (no solo borres) para que los post-mortems sean posibles. El transformer built-in reasoning maneja los casos oficiales; este es para control fino.