Por qué dejamos de llamar OpenAI directamente
A finales de 2024 teníamos tres proyectos productivos consumiendo la API de OpenAI: un chatbot de soporte, un pipeline de análisis de documentos y un módulo de generación de resúmenes. La factura mensual rondaba los USD 180, lo que en pesos colombianos —con el dólar por encima de los $4.100 COP— representaba más de $700.000 mensuales solo en tokens.
El problema no era solo el precio: era la falta de flexibilidad. Si GPT-4o resultaba excesivo para una tarea sencilla de clasificación, no había opción económica de OpenAI que fuera competitiva con los nuevos modelos chinos. Empezamos a evaluar alternativas y encontramos OpenRouter.
Qué es OpenRouter y cómo funciona
OpenRouter es un proxy unificado que expone más de 100 modelos de lenguaje —de OpenAI, Anthropic, Google, Mistral, DeepSeek, Meta y otros— bajo una única API compatible con el estándar de OpenAI. Sin subscripciones: pagas solo por los tokens que consumes.
La propuesta de valor es concreta:
- Una sola key de API para acceder a todos los proveedores.
- Fallback automático: si un proveedor falla, redirige a otro con el mismo modelo.
- Sin compromisos: no hay tier mínimo, no hay suscripción de $20/mes.
- Dashboard de costos en tiempo real por modelo y por endpoint.
El markup de OpenRouter sobre el precio base del proveedor varía entre 0% y ~10% dependiendo del modelo. Para DeepSeek V3 y modelos similares el costo es idéntico al directo; para GPT-4o hay un pequeño overhead que en la mayoría de casos queda compensado por la conveniencia operativa.
Comparativa de precios: los modelos que más usamos
Precios en USD por 1 millón de tokens (vigentes abril 2025). La columna “vía OpenRouter” incluye el markup del intermediario.
Fuente: páginas de precios de OpenAI, Anthropic y OpenRouter. Los precios pueden variar; verifica siempre antes de escalar a producción.
Caso real: chatbot de soporte con 10.000 mensajes al mes
Tomemos un chatbot de soporte técnico con el siguiente perfil de uso mensual:
- 10.000 mensajes de usuario procesados.
- Prompt de sistema: ~300 tokens por llamada (contexto del producto).
- Mensaje promedio de usuario: ~60 tokens.
- Respuesta promedio del modelo: ~200 tokens.
- Total estimado: ~5.6M tokens de input + ~2M tokens de output al mes.
Comparando GPT-4o con DeepSeek V3 para este chatbot, el ahorro es de ~$30 USD mensuales, que al tipo de cambio de $4.100 COP son $123.000 COP que quedan en la caja. En un año: más de $1.470.000 COP solo por cambiar el modelo en un proyecto.
Contexto para startups colombianas: el dólar caro hace que cualquier optimización en servicios denominados en USD impacte directamente el runway. Para un equipo bootstrapped, la diferencia entre pagar $34 y $3.71 al mes por el mismo chatbot puede determinar si un feature se construye o no.
Cómo integrar OpenRouter en TypeScript
OpenRouter es 100% compatible con el SDK de OpenAI: solo cambias la baseURL y el nombre del modelo. No tienes que instalar nada adicional.
Variables de entorno (.env.local):
# .env.local
OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
OPENROUTER_BASE_URL=https://openrouter.ai/api/v1
# Opcional: identifica tu app en el dashboard de OpenRouter
OPENROUTER_SITE_URL=https://tuapp.com
OPENROUTER_APP_NAME=Tu AppCliente base reutilizable:
// lib/openrouter.ts
import OpenAI from 'openai'
export const openrouter = new OpenAI({
baseURL: process.env.OPENROUTER_BASE_URL ?? 'https://openrouter.ai/api/v1',
apiKey: process.env.OPENROUTER_API_KEY!,
defaultHeaders: {
'HTTP-Referer': process.env.OPENROUTER_SITE_URL ?? '',
'X-Title': process.env.OPENROUTER_APP_NAME ?? '',
},
})
// Modelos disponibles — centralizar evita typos
export const MODELS = {
// Razonamiento complejo, visión, tool calling avanzado
FLAGSHIP: 'openai/gpt-4o',
// Balance costo/calidad para tareas generales
BALANCED: 'deepseek/deepseek-chat-v3-0324',
// Contextos largos (hasta 200k tokens)
LONG_CONTEXT: 'anthropic/claude-3-5-haiku',
// Clasificación, extracción simple, tareas repetitivas
CHEAP: 'mistralai/mistral-7b-instruct',
} as constLlamada típica con selección de modelo:
// app/api/chat/route.ts
import { openrouter, MODELS } from '@/lib/openrouter'
import { NextRequest, NextResponse } from 'next/server'
export async function POST(req: NextRequest) {
const { message, useCase } = await req.json()
// Selección de modelo según la complejidad de la tarea
const model =
useCase === 'analysis' ? MODELS.FLAGSHIP :
useCase === 'summary' ? MODELS.BALANCED :
MODELS.CHEAP
const completion = await openrouter.chat.completions.create({
model,
messages: [
{
role: 'system',
content: 'Eres un asistente de soporte técnico para software colombiano.',
},
{ role: 'user', content: message },
],
max_tokens: 512,
temperature: 0.3,
})
const text = completion.choices[0].message.content ?? ''
return NextResponse.json({
text,
model: completion.model,
usage: completion.usage,
})
}Cuándo usar cada modelo: nuestra guía práctica
Úsalo cuando necesites razonamiento multi-paso, análisis de imágenes, tool calling con alta fiabilidad o cuando el output incorrecto tiene costo real (decisiones financieras, contratos, diagnósticos). No lo uses para tareas de volumen alto.
El mejor ratio precio/calidad que hemos encontrado para tareas de texto: chatbots de soporte, resúmenes, extracción de datos estructurados, generación de copy, traducción. Supera a GPT-4o mini en benchmarks de razonamiento y cuesta aproximadamente lo mismo.
Ventana de contexto de 200k tokens. Ideal para análisis de documentos largos (contratos, PDFs extensos), RAG con chunks grandes o conversaciones con historial extenso. El costo por token es mayor que DeepSeek pero la capacidad de contexto justifica la diferencia en estos casos.
Para clasificaciones simples (positivo/negativo, categoría A/B/C), routing de mensajes, detección de idioma o cualquier tarea donde el volumen sea alto y la instrucción sea muy concreta. A $0.06 el millón de tokens, casi no importa cuántas llamadas hagas.
Latencia: el costo oculto del intermediario
OpenRouter introduce entre 50 y 100 ms adicionales de latencia por llamada comparado con conectarse directamente al proveedor. Esto es un hecho documentado, no una estimación.
En la práctica, para la mayoría de casos de uso —chatbots, generación de contenido, análisis batch— esa diferencia es imperceptible. El tiempo de generación de tokens (TTFT + generación) suele estar en el rango de 1-5 segundos, así que 100 ms son ruido.
Donde sí importa es en pipelines de streaming en tiempo real o aplicaciones donde el primer token debe llegar en menos de 200 ms (interfaces de voz, por ejemplo). Para esos casos, conectar directamente al proveedor y usar la API de OpenAI o Anthropic native tiene sentido.
El problema con response_format: json_object
Aquí hay un gotcha importante: DeepSeek V3 no soporta el parámetro response_format: { type: "json_object" }. Si lo mandas, la API retorna un error 400. Lo mismo ocurre con varios modelos open-source en OpenRouter.
La solución es doble: instruir al modelo en el system prompt + parsear con regex de fallback en caso de que el modelo devuelva texto extra.
// lib/json-llm.ts
import { openrouter, MODELS } from './openrouter'
interface ExtractOptions {
systemPrompt: string
userMessage: string
/** Si es true, no envía response_format (necesario para DeepSeek y otros) */
noNativeJson?: boolean
}
export async function extractJson<T>(options: ExtractOptions): Promise<T> {
const { systemPrompt, userMessage, noNativeJson = false } = options
// Para modelos sin soporte nativo de JSON, forzamos via prompt
const systemWithJsonInstruction = noNativeJson
? `${systemPrompt}
IMPORTANTE: Responde ÚNICAMENTE con JSON válido, sin texto adicional,
sin bloques de código markdown, sin explicaciones. Solo el objeto JSON.`
: systemPrompt
const completion = await openrouter.chat.completions.create({
model: noNativeJson ? MODELS.BALANCED : MODELS.FLAGSHIP,
messages: [
{ role: 'system', content: systemWithJsonInstruction },
{ role: 'user', content: userMessage },
],
// Solo enviamos response_format si el modelo lo soporta
...(!noNativeJson && {
response_format: { type: 'json_object' },
}),
temperature: 0,
max_tokens: 1024,
})
const raw = completion.choices[0].message.content ?? ''
// Intento 1: parsear directamente
try {
return JSON.parse(raw) as T
} catch {
// Intento 2: extraer el primer bloque JSON con regex
const match = raw.match(/{[sS]*}|[[sS]*]/)
if (match) {
try {
return JSON.parse(match[0]) as T
} catch {
// Intento 3: limpiar markdown code fences
const cleaned = match[0]
.replace(/^```json\n?/, '')
.replace(/\n?```$/, '')
.trim()
return JSON.parse(cleaned) as T
}
}
throw new Error(`No se pudo extraer JSON del response: ${raw.slice(0, 200)}`)
}
}
// Ejemplo de uso:
// const result = await extractJson<{ sentiment: string; score: number }>({
// systemPrompt: 'Analiza el sentimiento del texto.',
// userMessage: 'El servicio fue excelente pero el tiempo de entrega fue largo.',
// noNativeJson: true, // DeepSeek
// })Tip: crea un wrapper por modelo que ya sepa si ese modelo soporta json_object o no. Así no tienes que recordarlo en cada llamada. Nosotros mantenemos un objeto de capacidades por modelo en lib/model-capabilities.ts.
Nuestra recomendación: OpenRouter para el 80% de los casos
Después de seis meses usando OpenRouter en producción, esta es nuestra postura:
Usa OpenRouter cuando…
- →Quieres experimentar con diferentes modelos sin abrir cuentas en 5 proveedores.
- →Tu caso de uso es sensible al costo (volumen alto, budget limitado).
- →Necesitas fallback automático entre proveedores para alta disponibilidad.
- →Tu equipo no quiere gestionar múltiples credenciales y dashboards.
Ve directo al proveedor cuando…
- →Usas features exclusivos: fine-tuning en OpenAI, artifacts en Claude.ai, embeddings de tercera generación.
- →La latencia es crítica y 100 ms importan (voz, streaming en tiempo real).
- →Tienes un contrato Enterprise con condiciones especiales de precio.
- →Necesitas garantías de cumplimiento que un intermediario no puede certificar.
En Edwsystem, hoy el 80% de nuestras llamadas van por OpenRouter y el 20% restante va directo a OpenAI (principalmente para tareas que requieren visión avanzada con GPT-4o y para embeddings con text-embedding-3-large).
Conclusión: el contexto colombiano cambia el cálculo
En Silicon Valley, la diferencia entre $34 y $3.71 al mes puede parecer trivial. En Colombia, con el dólar a $4.100 COP y operando con márgenes de startup, esa diferencia se siente. Multiplícalo por varios proyectos y la optimización de costos en APIs se convierte en una decisión estratégica, no cosmética.
OpenRouter nos dio acceso al ecosistema completo de modelos de lenguaje con una sola integración. La API es idéntica a la de OpenAI, la migración tomó menos de una hora por proyecto, y el ahorro fue inmediato. Si estás pagando por OpenAI directo para tareas que no requieren razonamiento avanzado, probablemente estás dejando dinero sobre la mesa.
El stack que recomendamos para empezar: DeepSeek V3 para el 70% de las tareas, GPT-4o para el 20% que requiere razonamiento complejo y un modelo barato (Mistral 7B) para el 10% de clasificaciones simples. Monitoriza los costos desde el dashboard de OpenRouter y ajusta según el uso real.
Si tienes preguntas sobre la implementación o quieres que revisemos tu arquitectura de IA, escríbenos. Trabajamos con startups y empresas colombianas que quieren hacer el dólar rendir.