← Resources
TUTORIAL · 2026-03-26
Migra del Vercel AI SDK a una pila BYOK autoalojable
El Vercel AI SDK está bien hasta que necesitas claves portátiles, enrutamiento personalizado o un destino de despliegue que no sea Vercel. Esta guía mapea cada primitiva a una pila BYOK autoalojable y te da un corte dual-write de una semana.
Por qué los equipos superan al Vercel AI Gateway
El AI SDK avanza rápido: `streamText`, `generateText` y `generateObject` cubren la mayoría de las necesidades de producción con una sola superficie TypeScript. La fricción aparece después, normalmente en tres sitios.
Primero, el runtime está opinionado hacia Vercel. Las peculiaridades del edge runtime, las primitivas de streaming ajustadas para Next.js y el AI Gateway como router recomendado asumen que tu destino de producción es Vercel.
Segundo, el AI Gateway se sienta en la ruta de la petición incluso con BYOK. Según los precios públicos del Vercel AI Gateway a mayo de 2026, BYOK funciona con un 0 % de margen sobre tokens, pero tu equipo debe mantener financiados los créditos del AI Gateway en todo momento porque las peticiones BYOK fallidas se reintentan contra las credenciales del sistema de Vercel. Ese acoplamiento importa una vez que entran en juego el cumplimiento o el enrutamiento por VPC.
Tercero, la política por tenant vive en el código de tu app. No hay un concepto nativo de tenant, lista blanca de modelos o tope presupuestario en el SDK. Los equipos que ejecutan SaaS multi-tenant acaban escribiendo un segundo mini-gateway sobre el primero.
Mapeando primitivas de Vercel a una pila BYOK
La buena noticia: la superficie pública del AI SDK es pequeña. La mayoría de las llamadas se reducen a tres funciones y un objeto de proveedor. Mapéalas así:
- `streamText` y `generateText` mapean directamente a `chat.completions.create` del SDK de OpenAI con `stream: true` o `false`. Cualquier endpoint compatible con OpenAI funciona como `baseURL`, lo que significa llama.cpp, vLLM, LiteLLM o un proveedor alojado detrás de un proxy consciente del tenant.
- `generateObject` mapea a `response_format: { type: 'json_schema' }` en servidores compatibles con OpenAI, o a un adaptador de salida estructurada para proveedores que usen un esquema diferente (tools de Anthropic, modo JSON de Gemini).
- Los objetos de proveedor (`openai('gpt-4o')`, `anthropic('claude-...')`) se convierten en un único cliente apuntando a tu gateway, con el id del modelo pasado como cadena. El enrutamiento ocurre en el servidor en lugar de estar incrustado en el import.
Mantén tus hooks de React existentes. `useChat` y `useCompletion` solo necesitan una ruta que devuelva un stream Server-Sent Events con la misma forma.
Streaming, llamadas a herramientas y salidas estructuradas sin bloqueo
Las tres funciones sobreviven a la migración si eliges un gateway compatible con OpenAI. Aquí está la misma llamada antes y después.
Antes, con el Vercel AI SDK:
import { streamText } from 'ai';
import { openai } from '@ai-sdk/openai';
const result = await streamText({
model: openai('gpt-4o'),
messages,
tools: { search: searchTool },
});
return result.toDataStreamResponse();
```
Después, con el SDK de OpenAI apuntando a tu propio gateway:
import OpenAI from 'openai';
const client = new OpenAI({ baseURL: process.env.GATEWAY_URL, apiKey: tenantKey });
const stream = await client.chat.completions.create({
model: 'gpt-4o',
messages,
tools: [searchToolSchema],
stream: true,
});
```
Las llamadas a herramientas llegan en `delta.tool_calls`. Las salidas estructuradas usan `response_format`. Ambos son campos estándar de la especificación OpenAI que LiteLLM, vLLM y la mayoría de proveedores gestionados respetan.
Claves, cuotas y enrutamiento por tenant
Aquí es donde un SDK fino vale la pena. Una vez que las peticiones fluyen por un único endpoint compatible con OpenAI que controlas, cada preocupación transversal sale del código de la app.
Un gateway autoalojado como LiteLLM te permite acuñar claves virtuales por tenant, establecer techos de RPM y TPM, adjuntar presupuestos y enrutar por alias de modelo. Una petición para `model: 'fast'` puede resolverse a Groq Llama para un tenant y a un servidor llama.cpp local para otro, sin cambios de código en la app Next.js.
osFoundry adopta la misma postura BYOK pass-through pura y añade reglas de enrutamiento por tenant, streaming, llamadas a herramientas y salidas estructuradas en un único runtime que puedes autoalojar. Citación cruzada: LiteLLM es la línea base open-source obvia aquí y es la elección correcta para muchos equipos; elige el que coincida con tu modelo de operaciones.
La decisión de carga es hacer que el gateway, no la app, sea el propietario de claves y cuotas. Todo lo demás, incluidos los cambios de modelo, se convierte en un cambio de configuración.
Autoalojar o ejecutar en híbrido: coste y operaciones
Tres formas de despliegue cubren a la mayoría de los equipos.
1. Totalmente autoalojado. Gateway en tu VPC, BYOK a proveedores, modelos locales opcionales en una caja con GPU. Margen cero, audit trail completo, tú asumes la guardia. Lo mejor cuando el cumplimiento o la residencia de datos guían la decisión.
2. Híbrido. Gateway autoalojado para enrutamiento y política, proveedores gestionados para inferencia, modelos locales solo para cargas baratas o privadas. Es el estado estable común.
3. Gateway gestionado, tus claves. Usa un proxy alojado compatible con OpenAI que soporte pass-through BYOK. Cedes algo de control sobre la ruta de la petición; ganas no tener que ejecutar otro servicio.
El coste operativo de la opción 1 es real: un contenedor pequeño, un Postgres para claves y gasto, envío de logs y una cadencia de actualizaciones. Para la mayoría de equipos por debajo de unos pocos cientos de millones de tokens al mes, los ahorros frente a un gateway basado en margen son menores que el tiempo dedicado a debatirlo. Elige por control, no por céntimos.
Script de corte: dual-write durante una semana
No cambies el import en un solo PR. Haz dual-write durante siete días, compara y luego corta.
Día 0: añade el nuevo cliente del gateway tras un feature flag. Para cada petición, ejecuta la ruta antigua `streamText` y, en paralelo, dispara la nueva llamada `chat.completions` con los mismos mensajes. Descarta la segunda respuesta, pero registra latencia, recuentos de tokens, motivo de finalización y cualquier discrepancia en la forma de las llamadas a herramientas.
Días 1-3: sombrea el 100 % del tráfico. Diffea las salidas estructuradas y el JSON de los argumentos de las llamadas a herramientas. La mayoría de las regresiones son de esquema: Anthropic devuelve stop reasons ligeramente diferentes, Gemini envuelve el JSON de manera distinta. Arregla en el gateway, no en la app.
Días 4-6: cambia el 10 %, luego el 50 % y luego el 100 % de las rutas de solo lectura (chat, summarize). Mantén las rutas de escritura o agénticas en la ruta antigua hasta que el diff esté limpio durante 24 horas.
Día 7: elimina los paquetes `ai` y `@ai-sdk/*`, borra las variables de entorno del AI Gateway y archiva el flag.
Post-migración: caché, observabilidad, evaluaciones
Poseer la ruta de la petición desbloquea tres cosas que eran incómodas dentro del SDK.
Caché: un gateway puede hashear sobre `(model, messages, tools, response_format)` y servir peticiones idénticas desde Redis. Para RAG y bucles de agentes con system prompts repetidos, el caché de prefijo de prompt a nivel de proveedor (Anthropic, OpenAI) se superpone encima. Cablea ambos; los aciertos de caché se ven inmediatamente en la latencia p50.
Observabilidad: emite un log estructurado por petición con el id del tenant, modelo, tokens de prompt, tokens de finalización, recuento de llamadas a herramientas, motivo de finalización y latencia upstream. Envíalo a lo que ya uses. Ya no necesitas una integración de tracing específica del proveedor para ver lo que hizo el modelo.
Evaluaciones: con todo el tráfico fluyendo por un endpoint, el muestreo para un conjunto de evaluación es una consulta SQL. Reproduce contra nuevos modelos cambiando el campo `model`. Esta es la razón a largo plazo para poseer el gateway: la elección de modelo se vuelve un experimento semanal, no una migración trimestral.
Frequently asked questions
- ¿Abandonar el Vercel AI SDK significa que pierdo useChat y los hooks de streaming de React?
- No. Los hooks están desacoplados del runtime del servidor siempre que tu ruta API devuelva un stream Server-Sent Events con la forma que el hook espera. Puedes mantener `useChat` y `useCompletion` del paquete `ai` y apuntarlos a una ruta que haga proxy de una respuesta de streaming compatible con OpenAI. Muchos equipos mantienen el lado de React intacto durante el primer mes de la migración y solo cambian el handler del servidor. Si eventualmente quieres eliminar por completo la dependencia `ai`, un parser SSE fino son unas 30 líneas de TypeScript.
- ¿Es LiteLLM una alternativa real o un parche temporal?
- Es una alternativa real y está ampliamente desplegado en producción. LiteLLM es un proxy open-source compatible con OpenAI que cubre más de 140 proveedores, soporta claves virtuales, presupuestos por clave, límites RPM y TPM y balanceo de carga. Funciona como un único contenedor Docker con Postgres. La contrapartida frente a un runtime de orquestación más completo está sobre todo en los bucles de agentes, la normalización de salidas estructuradas entre proveedores y la política por tenant más allá de claves y presupuestos. Para un caso de uso puro de enrutamiento y BYOK, LiteLLM suele ser la respuesta correcta por sí solo.
- ¿Cómo mantengo las salidas estructuradas funcionando entre proveedores tras la migración?
- Normaliza en el gateway, no en la app. OpenAI y los servidores compatibles con OpenAI aceptan `response_format: { type: 'json_schema', json_schema: {...} }`. Anthropic usa un patrón de llamadas a herramientas para imponer esquemas. Gemini tiene un `responseMimeType` más `responseSchema`. Una pequeña capa de adaptador en el gateway traduce una forma canónica de petición a cualquier proveedor al que estés despachando y valida el JSON devuelto antes de responder. Esto mantiene tu código de aplicación llamando a una sola función y te permite cambiar de modelo sin tocar la lógica de manejo de esquemas.
- ¿Y la latencia? Añadir un gateway autoalojado suena a otro salto.
- En la práctica, la latencia añadida es de un dígito de milisegundos si el gateway está en la misma región que tu app, lo cual es eclipsado por el tiempo de inferencia del modelo (cientos de ms a segundos). La ganancia mayor en latencia está en el lado de la caché: un gateway puede servir prompts repetidos desde Redis en menos de 5 ms, lo cual es imposible si cada petición va directa al proveedor. Mide p50 y p95 antes y después; los equipos suelen ver cifras neutras o mejoradas una vez que el caché está activo.
Sources