⚠️ SUPERSEDED · s55 (11-05-2026) por [[decision—20260511—cleanup-openrouter-monoproveedor-google-genai]].
OpenRouter fue retirado del stack AI tras 8 días de PROD estable con
google_genaidirecto a Google AI Studio Paid Tier (s49 → s55). Los archivoscore/services/ai_providers/openrouter.py+monitoring/services/ai_providers/openrouter.pyreferenciados ensourcesfueron eliminados en s55 (-1266 LOC). En s58 d21 también se cerró el caller restante del workspace (scripts/translate-wiki.mjs+functions/api/wiki/translate.ts). Soloai-eval/run.tsmantiene OpenRouter por diseño (tool de comparación multi-proveedor).ADR conservado como referencia histórica del puente OpenRouter (s44 → s55).
Contexto
El 28 de abril de 2026, durante una sesión sobre el plan registrado en la memoria project_gemma4_openrouter (sesión cierre 28-04 previa), Edu validó subjetivamente en /tools/ai-eval que google/gemma-4-26b-a4b-it:free daba respuestas mejores que gemini-2.5-flash en preguntas largas con prosa libre. Esa observación motivó la propuesta de migrar todos los call sites de IA del proyecto (CreaRack-Pro + workspace) a Gemma 4 vía OpenRouter, hasta entonces no integrado.
La Regla 8 de CLAUDE.md exige que cualquier cambio de modelo requiera un ADR que actualice la tabla canónica. Este es ese ADR.
Decisión
Migrar los 11 call sites de IA del proyecto a google/gemma-4-26b-a4b-it (versión paga vía OpenRouter) a partir del 2026-04-28. La versión :free queda prohibida porque Google AI Studio (provider upstream del free tier) devuelve HTTP 429 sin previo aviso incluso con tráfico bajo.
El cambio unifica todo el stack de IA en un único modelo — anteriormente había 3 modelos Gemini distintos (gemini-3.1-flash-lite-preview para Categoría A, gemini-2.5-flash para Categoría B, y la fallback chain del router). La distinción Categoría A / Categoría B desaparece.
Call sites migrados (11 totales)
CreaRack-Pro (8)
| Archivo | Servicio / Uso |
|---|---|
core/services/ai_providers/openrouter.py | Nuevo — provider unificado (texto, JSON, JSON Schema, visión, sync + async) |
core/services/ai_providers/router.py | DEFAULT_OPENROUTER_MODEL — fallback chain OpenRouter → DeepSeek → Claude |
monitoring/services/ai_providers/openrouter.py | Nuevo — OpenRouterProvider para CNS Insight con backoff |
blueprints/services/autoplan.py | Auto-Plan AI (visión, JSON object) — nuevo _analyze_with_openrouter |
network/services/mib_assistant.py | MIB Assistant (JSON crítico) — _call_gemini → _call_ai |
monitoring/services/tutor_service.py | Network Tutor (síntesis async con conversation history) — nuevo _ask_openrouter |
core/services/ai_operations.py | AIOperations.MODEL = "google/gemma-4-26b-a4b-it" |
core/management/commands/finops_report.py + perf_review.py | Comandos de gestión — sustituido cliente Gemini directo por ai_fallback |
Workspace (3)
| Archivo | Servicio / Uso |
|---|---|
functions/api/mcp/handlers/archivo-core.ts | Síntesis del Archivo Maestro / Help Widget (bib_ask) |
functions/api/wiki/translate.ts | Traducción ES→EN live al editar páginas |
scripts/translate-wiki.mjs | Traducción ES→EN batch pre-build |
Excepción permitida
functions/api/tools/ai-eval/run.ts mantiene la integración Gemini para que la herramienta /tools/ai-eval pueda comparar Gemma vs Gemini en futuras evaluaciones. Esta es la única referencia a Gemini permitida fuera del fallback chain.
Evaluación previa
Subjetiva (Edu en /tools/ai-eval, 27-04-2026)
Probando google/gemma-4-26b-a4b-it:free con preguntas largas y respuestas en prosa: respuestas notablemente más completas y mejor estructuradas que gemini-2.5-flash.
Cuantitativa (scripts/eval_ai_models.py matriz 4×3, 28-04-2026)
| Caso | gemini-3-flash | gemini-3.1-flash-lite | gemma-4-26b A4B | Observación |
|---|---|---|---|---|
| MIB classification (JSON ~1500 chars) | 15.0s, 6 mon / 5 dd | 2.3s, 5/4 | 22.9s, 4/6 | Calidad equivalente, latencia 10× peor |
| Network Tutor (texto ~2-4 KB) | 6.3s, 2.1 KB | 3.5s, 2.7 KB | 8.0s, 3.7 KB | Gemma +36% chars, todos los keywords |
| Perf Review (texto largo) | 8.7s, 15 bullets, 7 kw | 3.0s, 9 bullets, 8 kw | 12.2s, 9 bullets, 6 kw | Flash-Lite gana en keywords técnicos |
| Auto-Plan visión (JSON corto) | 5.0s, 4/4 racks | 1.5s, 4/4 | 2.5s, 4/4 | Equivalente funcionalmente |
Test direcionado de latencia (3 runs por config, prompt MIB largo)
| Provider routing | min | mean | max |
|---|---|---|---|
| default (Ionstream/Parasail) | 11.8s | 22.0s | 32.5s |
sort=latency (Parasail) | 11.8s | 22.5s | 34.1s |
only=deepinfra | 12.5s | 15.2s | 17.9s |
Test direccionado de latencia (prompt corto, 300 chars output)
| Provider routing | min | mean | max |
|---|---|---|---|
sort=latency (Cloudflare) | 1.1s | 1.2s | 1.3s |
sort=throughput (Parasail) | 2.7s | 3.1s | 3.8s |
Lectura clave
Latencia de Gemma 4 escala lineal con tokens de salida (~60-80 tokens/s en Cloudflare/Parasail/DeepInfra). Para prompts cortos es competitivo con Gemini Flash-Lite. Para JSON largos, Gemma 4 es 10× más lento. La elección de migrar acepta este trade-off porque:
- Los sites de output largo son cron / async (no bloquean UI directa).
- CreaRack está en modo dev compartido (Edu + Dani), sin clientes que sufran el delay.
- Beneficio en stack unificado y coste pesa más que latencia en sites no-UX.
Coste
| Métrica | gemini-3.1-flash-lite-preview | google/gemma-4-26b-a4b-it | Δ |
|---|---|---|---|
| Input (por M tokens) | $0.25 | $0.06 | −76% |
| Output (por M tokens) | $1.50 | $0.33 | −78% |
Implementación
Patrón Python (CreaRack-Pro)
Provider único en core/services/ai_providers/openrouter.py con dos entry points:
from core.services.ai_providers.openrouter import call_openrouter, acall_openrouter
# Texto + JSON
text = call_openrouter(prompt, response_json=True, max_tokens=2048)
# JSON Schema estricto (forza provider con structured_outputs)
text = call_openrouter(prompt, response_schema={...}, provider_prefs={"only": ["deepinfra"]})
# Visión
text = call_openrouter(prompt, images=[img_bytes], image_mime="image/jpeg")
# Async con conversation history (Tutor)
text = await acall_openrouter(messages_list, system_instruction=SYSTEM_PROMPT)
Routing por defecto: provider.sort = "latency". OpenRouter elige Cloudflare/Parasail/DeepInfra/etc. según latencia upstream observada.
Patrón TypeScript (workspace)
Fetch directo a https://openrouter.ai/api/v1/chat/completions con Authorization: Bearer ${env.OPENROUTER_API_KEY} y provider: { sort: "latency" } en el body. Sin SDK.
Configuración
- CreaRack-Pro:
OPENROUTER_API_KEYañadida acompose.yml(servicioweb),config/settings/base.pyy.env. DefaultsAUTOPLAN_PROVIDER=openrouteryEDGE_AI_PROVIDER=openrouter. Hetzner PROD necesita la key en su.envDokploy antes del próximo redeploy. - Workspace:
OPENROUTER_API_KEYañadida alEnvtype (functions/types.ts). Cloudflare Pages requiere añadir la key como secret en el panel del dashboard antes del próximo deploy (no automatizable desde CLI sin reauth wrangler — tarea manual de Edu).
Consecuencias
Positivas
- Stack unificado: un único modelo para todo (texto, JSON, visión). Elimina la distinción Categoría A / B.
- −76% / −78% coste por token vs
gemini-3.1-flash-lite-preview. - Independencia de Google AI Studio: routing automático multi-provider (Cloudflare, Parasail, DeepInfra, Google Vertex…). Si un provider falla OpenRouter cambia automáticamente.
- Latencia competitiva en prompts cortos (Tutor, Help Widget breve, Auto-Plan visión).
- Provider OpenRouter reutilizable (
call_openrouter/acall_openrouter) — futuras integraciones IA en CreaRack pasan por aquí.
Negativas / Riesgos
- Latencia 10× peor en sites de JSON largo (MIB classification, CNS Insight con muchos chunks). Aceptado por contexto dev-compartido.
- Variante
:freeno usable (rate-limited upstream sin previo aviso). Se queda fuera de la opción de fallback gratis. - Dependencia adicional de OpenRouter como aggregator. Si OpenRouter cae completo, los 11 call sites pasan al fallback DeepSeek → Claude (en CreaRack-Pro) o devuelven error 503 (en workspace).
Neutrales
- Los call sites Auto-Plan y CNS mantienen su lógica de visión / JSON intacta — solo cambia el cliente subyacente.
- Las claves Gemini (
GEMINI_API_KEY) y los call sites DeepSeek (Auto-Plan fallback explícito) se mantienen sin cambios. La migración es reversible vía toggle.env.
Revisión 2026-05-03 (sesión 48): :free desbloqueado vía BYOK para Auto-Plan
La afirmación original “:free queda prohibida” era válida para el pool compartido OpenRouter — efectivamente devuelve 429 sin previo aviso por saturación cross-tenant. Tras pruebas en s48:
Cambio: :free es viable y preferible para Auto-Plan siempre que el OPENROUTER_API_KEY tenga BYOK conectado a una API key personal de Google AI Studio (https://openrouter.ai/settings/integrations). Con BYOK, las requests :free consumen la cuota personal del usuario (no el pool compartido) y no hay 429 mientras la cuota diaria personal alcance.
Por qué :free es preferible para visión:
:freerutea siempre a Google AI Studio (único provider). Es el runtime oficial de Google donde se entrenó el modelo.- El paid (
google/gemma-4-26b-a4b-it) rutea a 10 providers third-party (DekaLLM, DeepInfra, Ionstream, Cloudflare, Parasail, etc.). En s48 se confirmó conprovider.onlyyseed=42fijo que algunos third-party recortan la imagen antes de servirla al modelo (calidad ~45-95%) o tienen cuantizaciones más agresivas. Solo Google AI Studio (:free) y Google Vertex (google-vertexslug del paid) replican el comportamiento del runtime original.
Estado tras s48:
- Auto-Plan: usa
google/gemma-4-26b-a4b-it:freecon BYOK Edu (commit96bc4efben repo CreaRack-Pro). Validado 100% calidad sobre plano test 68 racks. Reproducible conOPENROUTER_SEED=43. - Resto de call sites de IA (CNS, MIB Assistant, Tutor, Help Widget, traducciones, finops, perf review): siguen en el modelo paid
google/gemma-4-26b-a4b-itoriginal. La migración es Auto-Plan-only.
Doc operativo nuevo: [[crearack-tech—backend—auto-plan-ai-tuning]] cubre el setup actual (Dokploy env vars, prompt, footguns, recetario para iterar prompt con seed fijo).
Riesgo BYOK: la cuota diaria de Google AI Studio personal de Edu (~1500 req/día típico free tier) puede saturar si el uso de Auto-Plan crece mucho. Mitigación: si satura, cambiar OPENROUTER_MODEL=google/gemma-4-26b-a4b-it (paid) — pierde calidad pero recupera funcionalidad. O reactivar self-host EPYC pve-epyc-02 cambiando AUTOPLAN_PROVIDER=ollama.
Reversión
Para revertir a Gemini Flash-Lite:
- CreaRack-Pro: en
.envde PROD cambiarAUTOPLAN_PROVIDER=geminiyEDGE_AI_PROVIDER=gemini. Los call sites mantienen su path Gemini intacto. Paraai_fallbackrevertir un commit. - Workspace: revertir el commit (los CF Workers vuelven a usar
GOOGLE_AI_API_KEYdirecto).
Supersedes
Supersedes: [[decision—20260427—gemini-3-1-flash-lite-migration]]
La Regla 8 de CLAUDE.md ha sido actualizada para reflejar esta decisión como la tabla canónica vigente. Las menciones a Categoría A / Categoría B quedan obsoletas.
Véase también
- [[decision—20260427—gemini-3-1-flash-lite-migration]] — ADR previo sobre Gemini Flash-Lite (ahora superseded)
- [[crearack—blueprints—auto-plan-ai]] — Auto-Plan AI, principal call site de visión
- [[crearack—monitoring—cns-sentinel]] — CNS, call site de JSON crítico
- [[feature—ai—eval-ai-models-framework]] — Script de evaluación A/B usado en este ADR
Referenciado desde
- ADR: Migración síntesis Help Widget a Gemma 4 E2B Q4_0 self-host (pve-epyc-02 + CF Tunnel)
- Auto-Plan AI · Ajustes y Prompt (operativa)
- Servicio llama-help: llama.cpp self-host para síntesis RAG (Gemma 4 E2B Q4_0)
- Sistema de Traducción Wiki ES→EN (translate.ts + translate-wiki.mjs)
- Wiki Translate — Pipeline de traducción ES→EN (CF Pages Function + script batch)