Módulo 7: Comparación técnica de proveedores
Migration paths
Tu matriz de la cápsula 05 te dijo "el proveedor X gana hoy". Pero hoy no dura para siempre:
- OpenAI baja el precio de un modelo a la mitad → conviene migrar
- Tu cliente nuevo requiere data residency en EU → debes salir de USA
- Sale un modelo open-source con calidad comparable a GPT-4 → cambia el cálculo
- Tu volumen sube 10× y self-hosted empieza a ganar
La pregunta sigue siendo la misma: ¿cuánto trabajo cuesta cambiar? Si la respuesta es "1 día", migras cuando convenga. Si es "3 sprints de refactor", quedas atado al proveedor aunque deje de ser óptimo. Esa fricción se llama vendor lock-in, y reducirla es valor real.
Al terminar vas a poder:
- Estimar el costo de migración entre cualquier par de proveedores del path
- Identificar las APIs y abstracciones que minimizan lock-in
- Diseñar tu código desde el inicio para que migrar sea barato
- Ejecutar una migración real con un checklist concreto
Por qué importa
Hay dos formas de prepararse para la incertidumbre:
- Adivinar el futuro y elegir el "ganador definitivo" → casi siempre falla
- Reducir el costo de cambiar → siempre funciona
El método 2 es la única estrategia robusta para un mercado que cambia cada trimestre. Esta cápsula es sobre el método 2.
Modelo mental: la jerarquía de APIs
Buena noticia: el ecosistema convergió. La mayoría de proveedores adoptaron (formalmente o de facto) el formato de OpenAI como interfaz estándar. Eso significa que muchas migraciones son cambio de URL + cambio de API key, no rewrite.
┌─→ OpenAI (nativo)
Formato OpenAI Chat ├─→ OpenRouter (proxy oficial OpenAI-compatible)
/v1/chat/completions ──→ ├─→ Ollama (OpenAI-compatible mode)
├─→ LM Studio (server OpenAI-compatible)
├─→ Modal (tu API custom, pero puedes copiar el formato)
└─→ Together, Anyscale, Groq, vLLM, etc.
Anthropic Claude y Google Gemini tienen formatos propios pero también ofrecen endpoints OpenAI-compatible (a través de proxies oficiales o capa de adaptación).
Migración 1 — OpenAI → OpenRouter
Esfuerzo: ~5 minutos. Cambio de 2 líneas.
# ANTES
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
)
# DESPUÉS — OpenRouter
from openai import OpenAI
client = OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=os.environ["OPENROUTER_API_KEY"],
)
response = client.chat.completions.create(
model="mistralai/mistral-7b-instruct", # ← elige cualquier modelo del catálogo
messages=[{"role": "user", "content": prompt}],
)
Lo que cambia: base_url, api_key, model.
Lo que NO cambia: messages, temperature, max_tokens, response_format, manejo de streaming, error handling.
Verificación post-migración:
- Tests existentes pasan
- Latencia, calidad y costo se comportan como tu benchmark predijo
Migración 2 — OpenAI → Ollama (local)
Esfuerzo: ~10 minutos si Ollama ya está corriendo. Cambio de 3 líneas.
# DESPUÉS — Ollama local
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:11434/v1",
api_key="ollama", # cualquier string; Ollama lo ignora
)
response = client.chat.completions.create(
model="mistral", # tu modelo de Ollama
messages=[{"role": "user", "content": prompt}],
)
Lo que cambia: base_url, api_key (placeholder), model.
Catch: algunos parámetros de OpenAI no están soportados por Ollama (response_format con JSON Schema avanzado, function calling completo con multi-turn, etc). Verifica los que usas.
Migración 3 — OpenAI → LM Studio
Esfuerzo: idéntico a Ollama. LM Studio expone un endpoint OpenAI-compatible en http://localhost:1234/v1.
client = OpenAI(
base_url="http://localhost:1234/v1",
api_key="lm-studio",
)
Mismo patrón. La diferencia es operacional (modelo cargado en LM Studio GUI vs Ollama CLI).
Migración 4 — Cloud (OpenAI/OpenRouter) → Modal
Esfuerzo: ~1-2 horas. No es cambio de URL — es deployment nuevo.
Pasos:
- Definir la función Modal (decoradores, imagen, GPU) — copiar del Módulo 6
- Deployar (
modal deploy) - Tu endpoint expone
/chatcon tu contrato custom (no OpenAI nativo) - Adaptar el caller para usar tu endpoint
# El caller que antes usaba OpenAI directo
import httpx
def chat_via_modal(prompt: str) -> str:
r = httpx.post(
os.environ["MODAL_BASE_URL"] + "/chat",
headers={"Authorization": f"Bearer {os.environ['MODAL_TOKEN']}"},
json={"prompt": prompt, "max_tokens": 256},
timeout=60,
)
r.raise_for_status()
return r.json()["respuesta"]
Si quieres mantener compatibilidad OpenAI: diseña tu endpoint Modal para emitir el formato chat.completions.create() response y exponlo en /v1/chat/completions. Entonces tu Modal se vuelve drop-in replacement de OpenAI (lo que harás conceptualmente en el Módulo 8).
Migración 5 — Modal → Self-hosted (Ollama en AWS)
Esfuerzo: ~1 semana. Es el cambio más grande del módulo.
Requiere:
- Provisionar la VM con GPU (AWS g5.xlarge, Lambda Cloud, etc.)
- Instalar drivers CUDA + Ollama (Docker simplifica)
- Descargar el modelo (
ollama pull mistral) - Configurar reverse proxy con HTTPS (Caddy, Nginx + Let's Encrypt)
- Setup observability (logs, métricas, alertas)
- Adaptar tu cliente a la nueva URL
Razón de hacerlo: economía a volumen alto, compliance, control total. Razón de no hacerlo: el equipo no quiere mantener infraestructura.
Migración 6 — OpenAI → Anthropic Claude
Esfuerzo: ~30 minutos. Formato distinto.
Anthropic tiene su propia API (messages.create() en vez de chat.completions.create()). Diferencias clave:
systemva como parámetro top-level, no como mensaje- Streaming y tool use tienen formatos distintos
- Pricing por separado de input/output cache
Si tu código solo hace chat.completions.create() simple, hay un wrapper trivial:
import anthropic
client = anthropic.Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])
def chat(prompt: str, system: str = "") -> str:
response = client.messages.create(
model="claude-3-5-sonnet-20241022",
max_tokens=400,
system=system or "Eres un asistente útil.",
messages=[{"role": "user", "content": prompt}],
)
return response.content[0].text
Alternativa: usar Anthropic vía OpenRouter o vía OpenAI-compatible proxy → vuelves al patrón base_url + model.
El patrón que minimiza migrar: una capa de abstracción
Lo que el Módulo 8 (Unified Client) va a construir es exactamente esto:
class UnifiedClient:
def __init__(self, provider: str, **kwargs):
self.provider = provider
self._client = self._build_client(provider, **kwargs)
def chat(self, prompt: str, **opts) -> str:
"""Interfaz única; el adapter por proveedor traduce."""
return self._client.chat(prompt, **opts)
Tu código de aplicación nunca toca OpenAI directo, Modal directo, etc. Solo toca UnifiedClient. Migrar es cambio de un parámetro:
# Antes
client = UnifiedClient(provider="openai")
# Después
client = UnifiedClient(provider="modal")
Esa abstracción tiene costo: te restringes a la intersección de features de los providers. Si necesitas function calling sofisticado que solo OpenAI soporta bien, la abstracción se vuelve incómoda. Es un trade-off — pero para muchos productos donde las features avanzadas no aplican, vale la pena.
Checklist de migración (cualquier dirección)
Cuando ejecutas una migración real:
- Benchmark de baseline. Antes de migrar, mide latencia/costo/calidad del proveedor actual con tu set real. Sin esto, no sabrás si la migración mejoró algo.
- Tests de regresión. Tu set de evaluación de la cápsula 04. Corre antes y después. Diferencias significativas merecen explicación.
- Comparación side-by-side en producción. Manda 10% del tráfico al nuevo proveedor, compara latencia y errores. Modal/OpenRouter/Anthropic todos toleran este patrón con feature flags.
- Rollback plan. ¿Qué pasa si el nuevo proveedor falla? Plan claro de volver a OpenAI / al anterior. Mantén el código del antiguo durante 1-2 sprints.
- Update de costo proyectado. Tu finance dashboard / cofounder debe ver el cambio en costos.
- Update de docs. README, runbooks, alertas. El paso que todos olvidan.
- Actualizar contratos con clientes (si aplica). Cambio de provider puede activar cláusulas de notificación (especialmente data processing addendums).
Costos de migración por escenario
| Migración | Esfuerzo eng | Riesgo | Cuándo vale la pena |
|---|---|---|---|
| OpenAI ↔ OpenRouter | 30 min | Bajo | Casi siempre, sobre todo para A/B test |
| OpenAI ↔ Ollama local | 1 hora | Bajo (entornos dev) | Dev / privacidad / costos |
| OpenAI ↔ Anthropic | 1-2 hrs | Medio (formato distinto) | Tu calidad mejora >10% |
| Cloud → Modal | 1-2 días | Medio | Volumen burst + control de modelo |
| Cloud → Self-hosted | 1-2 semanas | Alto | Volumen muy alto y constante + compliance |
Trampas comunes
Trampa 1 — "Cambié de proveedor pero olvidé el prompt template."
Cada modelo tiene su template ideal. Mistral usa [INST] ... [/INST]. Llama 3 usa otro. ChatML para muchos. Si copias el mismo prompt sin formatear, la calidad cae sin razón aparente. Verifica las model cards.
Trampa 2 — "Quedé pegado a una feature exclusiva." Si usas function calling sofisticado de OpenAI con multiples tools concurrentes, migrar a un modelo open-source que no lo soporta requiere rewrite mayor. Diseña asumiendo que solo tienes lo común y agrega features avanzadas como mejoras opcionales.
Trampa 3 — "Migré y ahora tengo dos proveedores corriendo." Pasa: querías reemplazar OpenAI con OpenRouter, pero dejaste el código viejo "por si acaso" y nunca lo borraste. Resultado: dos integraciones que mantener, dos sets de keys, doble billing. Borra el código del antiguo en cuanto la migración esté estable.
Trampa 4 — "Mi rollback plan era 'volver a la rama anterior'." Si tu código nuevo persistió datos en formato distinto, "volver" no es trivial. Considera feature flag que permita switch sin redeploy.
Trampa 5 — "Subestimé el cambio de pricing." Migración exitosa técnicamente, factura inesperada. Re-benchmarea costo con datos reales en la primera semana post-migración, no esperes al cierre del mes.
Ejercicio
Tu producto actual usa OpenAI GPT-4o-mini. Tu CTO te pide preparar 3 migration playbooks para escenarios distintos:
- Playbook A: OpenAI baja gpt-4o-mini un 50%. ¿Cambias algo? ¿Re-bencheas?
- Playbook B: Tu cliente más grande exige data residency EU. Tienes 30 días.
- Playbook C: Tu volumen se quintuplica de 100K req/mes a 500K req/mes en un trimestre.
Para cada uno: estimación de esfuerzo, riesgos, decisión recomendada (con razón).
Ver guía de respuestas
Playbook A — Bajada de precio de gpt-4o-mini:
- Esfuerzo: 0 (ya estás ahí)
- Acción: re-benchear costo proyectado para validar que tu factura baja como esperas; actualizar la matriz de decisión por si el cambio afecta a competidores; comunicar al equipo el ahorro.
- Decisión: mantener, monitorear si Anthropic / OpenRouter / Modal hacen contramovida.
Playbook B — Data residency EU en 30 días:
- Opciones viables: OpenAI EU (si certifica), Anthropic EU, OpenRouter con filtro EU, Modal en región EU (verificar), Self-hosted EU.
- Esfuerzo: 1-2 semanas (depende de opción)
- Riesgos: re-bencheo de calidad (modelos EU pueden tener variantes), latencia desde tus servidores, posibles diferencias de calidad si cambia modelo
- Decisión recomendada: empezar A/B test inmediatamente con la opción EU más probable; en paralelo, validar legal/compliance; estar listo para deploy en día 25 con rollback plan.
Playbook C — 5× de volumen:
- Costo actual proyectado: $200/mes → $1000/mes (gpt-4o-mini)
- Punto de cruce con Self-hosted: probable que aún no compense (Self-hosted = ~$720/mes con A10G 24/7, asumiendo 70% utilización)
- Riesgo principal: rate limits de OpenAI tier actual
- Esfuerzo si migras a Self-hosted: 1-2 semanas + mantenimiento ongoing
- Decisión recomendada: mantener OpenAI; subir tier; agregar caching de respuestas frecuentes (-30% de requests fácil); re-evaluar en 6 meses con datos reales.
Resumen
Aprendiste:
- ✅ El formato OpenAI es estándar de facto — la mayoría de migraciones son cambio de URL
- ✅ Cinco migraciones clave: OpenAI↔OpenRouter (5min), OpenAI↔Ollama (10min), Cloud↔Modal (hrs), Modal↔Self-hosted (días), OpenAI↔Anthropic (30min)
- ✅ La capa de abstracción (Unified Client) reduce migración a un cambio de parámetro
- ✅ Checklist de migración: baseline, tests, side-by-side, rollback, docs
- ✅ Trampas: prompt template, feature exclusiva, dos proveedores conviviendo, rollback frágil
Checkpoint: si puedes estimar en 30 segundos "¿cuánto cuesta cambiar de X a Y?" para cualquier par del path, estás listo.
Siguiente cápsula
07 — Tabla comparativa completa. Consolidamos todo lo aprendido en una sola tabla que sirve de referencia rápida para tu equipo. Es la cápsula que vas a marcar y volver a leer cuando tengas que decidir.
Recursos
- OpenAI API reference — el estándar de facto.
- Ollama OpenAI compatibility — modo OpenAI-compatible de Ollama.
- Anthropic — Comparing to OpenAI — guía oficial de migración.
- LiteLLM — librería tipo "OpenAI client para cualquier proveedor", inspiración para el Módulo 8.
- Architectural Decision Records — patrón para documentar migraciones.