Los agentes de voz solían requerir tres piezas: voz a texto, un modelo de lenguaje y texto a voz. Cada salto añadía latencia y podía perder tono. La API en tiempo real de OpenAI reduce ese flujo a un modelo de voz a voz, y gpt-realtime-2.1-mini es el nivel más económico y rápido de esa familia. Escucha audio, razona y responde mediante una única conexión de streaming.
En esta guía verá cómo integrarlo de punta a punta: qué ID de modelo usar, cómo conectarse por WebSocket y WebRTC, cómo configurar una sesión y cómo probar los endpoints con Apidog antes de llevarlo a una aplicación. Todo se alinea con la guía oficial de OpenAI Realtime.
Primero: use el nombre de modelo correcto
Hay dos identificadores relevantes para el modelo mini:
-
gpt-realtime-2.1-mini: ID versionado. Aparece en la página de precios de OpenAI y fija el modelo a la generación 2.1. -
gpt-realtime-mini: alias de familia. Apunta a la última instantánea, actualmentegpt-realtime-mini-2025-12-15.
Las instantáneas ayudan a bloquear el comportamiento en producción:
| Identificador | A qué apunta |
|---|---|
gpt-realtime-mini |
Última instantánea mini, con actualización automática |
gpt-realtime-2.1-mini |
Mini de generación 2.1 |
gpt-realtime-mini-2025-12-15 |
Instantánea fijada actual |
gpt-realtime-mini-2025-10-06 |
Instantánea fijada anterior |
Use el alias mientras prototipa. Antes de producción, fije una instantánea con fecha para evitar que una actualización del modelo cambie el comportamiento del agente sin aviso.
Qué hace gpt-realtime-2.1-mini
gpt-realtime-2.1-mini es un modelo de voz a voz. Usted transmite audio y el modelo devuelve audio con entonación natural, sin pasos separados de transcripción o TTS. También acepta texto, por lo que puede combinar entrada escrita y salida hablada en la misma sesión.
Especificaciones de la página del modelo:
| Propiedad | Valor |
|---|---|
| Modalidades de entrada | Texto, imagen, audio |
| Modalidades de salida | Texto, audio |
| Ventana de contexto | 32,000 tokens |
| Salida máxima | 4,096 tokens |
| Conexiones | WebRTC, WebSocket, SIP |
| Voces | alloy, ash, ballad, coral, echo, sage, shimmer, verse, marin, cedar |
marin y cedar son las voces más nuevas, exclusivas de la API en tiempo real, y OpenAI las recomienda para una salida más natural. Las voces anteriores siguen disponibles si necesita un timbre específico.
El nivel mini reduce algo de profundidad de razonamiento a cambio de menor latencia y menor costo. Para bots de soporte, toma de pedidos y frontends de voz, suele ser la opción inicial correcta. Use gpt-realtime-2.1 completo cuando la conversación requiera razonamiento más complejo.
Cuánto cuesta
El modelo mini cuesta aproximadamente un tercio del modelo completo. Tarifas de tokens de la página de precios:
| Modelo | Entrada de texto | Entrada en caché | Entrada de audio | Salida de audio |
|---|---|---|---|---|
gpt-realtime-2.1-mini |
$0.60 / 1M | $0.30 / 1M | $10 / 1M | $20 / 1M |
gpt-realtime-2.1 completo |
$4.00 / 1M | $0.40 / 1M | $32 / 1M | $64 / 1M |
El audio domina la factura. La variable más importante es cuánto habla el agente. Un agente que habla 35 segundos por minuto puede costar aproximadamente el doble que uno que habla 15 segundos por minuto.
Como referencia, los costos reales por minuto para el mini pueden oscilar entre $0.06 y $0.15 según la verbosidad. Para controlar esto, incluya instrucciones explícitas como:
Responde en una o dos frases. Sé directo y evita explicaciones largas salvo que el usuario las pida.
Las tarifas pueden cambiar, así que confirme siempre en la página de precios antes de estimar costos.
Requisitos previos
Necesita:
- Una clave API de OpenAI con acceso a Realtime, disponible como variable de entorno:
export OPENAI_API_KEY="sk-..."
Node.js 18+ para los ejemplos del servidor.
El paquete
wssi va a probar WebSocket:
npm install ws
- Para audio en navegador, una página servida por HTTPS o
localhost, porquegetUserMedialo requiere.
Regla importante: nunca envíe su clave API real al navegador o a una app móvil. Para clientes use tokens efímeros de corta duración.
Elija un método de conexión
gpt-realtime-2.1-mini admite tres transportes:
| Transporte | Úselo cuando | Autenticación |
|---|---|---|
| WebRTC | El audio se captura o reproduce en navegador o app móvil | Secreto de cliente efímero |
| WebSocket | Su servidor ya maneja audio crudo en un pipeline de medios | Clave API del lado servidor |
| SIP | Integra telefonía o sistemas telefónicos | Clave API |
Flujo recomendado:
- Prototipe con WebSocket desde servidor.
- Valide eventos y configuración.
- Pase a WebRTC cuando necesite micrófono y reproducción en navegador.
Inicio rápido 1: WebSocket desde servidor
El endpoint WebSocket usa el modelo en la query string:
wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini
En la interfaz GA se autentica con:
Authorization: Bearer OPENAI_API_KEY
No necesita el antiguo encabezado OpenAI-Beta.
Cree un archivo realtime-text.js:
import WebSocket from "ws";
const url = "wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini";
const ws = new WebSocket(url, {
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
},
});
ws.on("open", () => {
// 1. Configurar la sesión
ws.send(JSON.stringify({
type: "session.update",
session: {
type: "realtime",
model: "gpt-realtime-2.1-mini",
output_modalities: ["text"],
instructions: "Eres un agente de soporte de APIs. Responde de forma breve y técnica.",
},
}));
// 2. Añadir un mensaje del usuario
ws.send(JSON.stringify({
type: "conversation.item.create",
item: {
type: "message",
role: "user",
content: [
{
type: "input_text",
text: "¿Qué es una petición idempotente?",
},
],
},
}));
// 3. Solicitar respuesta
ws.send(JSON.stringify({
type: "response.create",
}));
});
ws.on("message", (raw) => {
const event = JSON.parse(raw.toString());
if (event.type === "response.output_text.delta") {
process.stdout.write(event.delta);
}
if (event.type === "response.done") {
console.log("\n\nRespuesta completada.");
ws.close();
}
});
ws.on("error", console.error);
Ejecute:
node realtime-text.js
El patrón es siempre el mismo:
- Configure la sesión con
session.update. - Envíe entrada con
conversation.item.create. - Solicite una respuesta con
response.create. - Procese los eventos de streaming.
Eventos útiles:
| Evento | Para qué sirve |
|---|---|
session.created / session.updated
|
Confirmar que la configuración fue aceptada |
response.output_text.delta |
Recibir fragmentos de texto |
response.output_audio.delta |
Recibir fragmentos de audio base64 |
response.output_audio_transcript.delta |
Recibir transcripción de lo que dice el modelo |
response.done |
Detectar el final del turno |
Para pasar de texto a voz, cambie output_modalities a ["audio"] y añada configuración de audio en la sesión.
Inicio rápido 2: WebRTC en el navegador
Use WebRTC cuando el navegador capture el micrófono y reproduzca el audio del modelo. Esto reduce latencia y delega el manejo de medios al navegador.
La autenticación cambia: el cliente no debe recibir la clave API real. Su servidor genera primero un token efímero.
Paso 1: genere un token efímero en el servidor
// server side
const r = await fetch("https://api.openai.com/v1/realtime/client_secrets", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
session: {
type: "realtime",
model: "gpt-realtime-2.1-mini",
},
}),
});
const { value } = await r.json(); // ephemeral key, empieza con "ek_"
Envíe value al navegador. Expira rápidamente, lo que reduce el riesgo si se filtra.
Paso 2: conecte el navegador con WebRTC
HTML mínimo:
<audio id="audio" autoplay></audio>
Código del navegador:
// browser side: EPHEMERAL_KEY viene de su servidor
const pc = new RTCPeerConnection();
// Reproducir el audio remoto del modelo
pc.ontrack = (event) => {
document.getElementById("audio").srcObject = event.streams[0];
};
// Enviar audio del micrófono
const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
pc.addTrack(mic.getTracks()[0]);
// Canal de datos para eventos JSON
const channel = pc.createDataChannel("oai-events");
channel.onopen = () => {
channel.send(JSON.stringify({
type: "session.update",
session: {
type: "realtime",
model: "gpt-realtime-2.1-mini",
output_modalities: ["audio"],
instructions: "Eres un asistente de reservas. Sé breve y confirma los datos importantes.",
audio: {
output: {
voice: "marin",
},
},
},
}));
};
channel.onmessage = (event) => {
console.log(JSON.parse(event.data));
};
// SDP handshake
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const sdpResp = await fetch(
"https://api.openai.com/v1/realtime/calls?model=gpt-realtime-2.1-mini",
{
method: "POST",
body: offer.sdp,
headers: {
Authorization: `Bearer ${EPHEMERAL_KEY}`,
"Content-Type": "application/sdp",
},
}
);
await pc.setRemoteDescription({
type: "answer",
sdp: await sdpResp.text(),
});
Cuando la conexión queda activa:
- El modelo escucha la pista del micrófono.
- La respuesta de audio llega por
pc.ontrack. - Los eventos JSON se envían y reciben por el canal
oai-events.
Configurar la sesión
El objeto session controla el comportamiento del agente. Esta es una configuración de audio completa:
{
type: "session.update",
session: {
type: "realtime",
model: "gpt-realtime-2.1-mini",
output_modalities: ["audio"],
instructions: "Eres un asistente de reservas amable. Confirma los detalles antes de actuar y responde de forma breve.",
audio: {
input: {
format: {
type: "audio/pcm",
rate: 24000
},
turn_detection: {
type: "semantic_vad"
}
},
output: {
format: {
type: "audio/pcm",
rate: 24000
},
voice: "marin"
}
}
}
}
Campos clave:
-
instructions: prompt de sistema. Defina rol, reglas, estilo y límites. Si el costo importa, indique explícitamente que responda breve. -
output_modalities: use["audio"]para un agente que habla o["text"]para respuestas de texto. -
audio.output.voice: elija una voz.marinycedarsuelen ser las opciones más naturales. -
audio.input.turn_detection: controla cuándo el modelo considera que el usuario terminó de hablar.-
semantic_vad: espera una pausa natural en el significado. -
server_vad: se activa por silencio.
-
Puede cambiar campos durante la llamada enviando otro session.update. No necesita reconectar.
Añadir herramientas para que el agente actúe
Un agente de voz útil no solo conversa: también consulta sistemas, valida datos o ejecuta acciones. Realtime usa el mismo contrato de llamada a funciones que el resto de la plataforma.
El flujo es:
- Declare herramientas en la sesión.
- El modelo emite una llamada de función.
- Su servidor ejecuta la función.
- Devuelve el resultado como un nuevo item de conversación.
- Solicita la siguiente respuesta.
Ejemplo conceptual de herramienta:
{
type: "session.update",
session: {
tools: [
{
type: "function",
name: "consultar_estado_pedido",
description: "Consulta el estado de un pedido por ID.",
parameters: {
type: "object",
properties: {
pedido_id: {
type: "string",
description: "ID del pedido"
}
},
required: ["pedido_id"]
}
}
]
}
}
Después, escuche eventos como:
response.function_call_arguments.done
Ejecute su lógica y publique el resultado con conversation.item.create antes de enviar el siguiente response.create.
Si ya ha usado herramientas en la API de chat, el modelo mental es el mismo. Para profundizar, vea el tutorial sobre llamada a funciones de OpenAI. Si necesita argumentos estrictos, las salidas estructuradas ayudan a controlar la forma de los datos. Para flujos más complejos, AgentKit de OpenAI ofrece una capa de orquestación de mayor nivel.
Pruebe los endpoints con Apidog antes de construir
No depure WebRTC, WebSocket y REST al mismo tiempo dentro de una app a medio construir. Valide cada pieza de forma aislada primero. Apidog encaja bien en este flujo.
1. Probar el endpoint de token efímero
Cree una solicitud REST:
POST https://api.openai.com/v1/realtime/client_secrets
Authorization: Bearer {{OPENAI_API_KEY}}
Content-Type: application/json
Body:
{
"session": {
"type": "realtime",
"model": "gpt-realtime-2.1-mini"
}
}
Debe recibir un token ek_ y su caducidad. Con eso valida:
- que la clave API funciona;
- que la cuenta tiene acceso a Realtime;
- que el ID del modelo es correcto.
Es el mismo enfoque que usaría para probar otras superficies REST de OpenAI, como la API de respuestas.
2. Probar el flujo WebSocket
Abra una conexión WebSocket en Apidog a:
wss://api.openai.com/v1/realtime?model=gpt-realtime-2.1-mini
Añada el header:
Authorization: Bearer {{OPENAI_API_KEY}}
Envíe estos mensajes en orden.
Primero, configure la sesión:
{
"type": "session.update",
"session": {
"type": "realtime",
"model": "gpt-realtime-2.1-mini",
"output_modalities": ["text"],
"instructions": "Eres un asistente técnico. Responde de forma breve."
}
}
Luego, cree un mensaje de usuario:
{
"type": "conversation.item.create",
"item": {
"type": "message",
"role": "user",
"content": [
{
"type": "input_text",
"text": "Explica qué es WebRTC en una frase."
}
]
}
}
Finalmente, solicite respuesta:
{
"type": "response.create"
}
Ver los eventos del servidor en un panel legible hace que la secuencia sea más fácil de depurar. También puede guardar los mensajes como ejemplos para su equipo. Si ya trabaja con estrategias de prueba de API, este paso encaja como una prueba de contrato para la capa de transporte.
Cuando algo falle después en la app, ya sabrá si el problema está en su cliente o en el contrato con la API. Puede descargar Apidog para seguir el flujo.
Mantenga la factura bajo control
La salida de audio es la parte más costosa. Aplique estas prácticas desde el primer prototipo:
-
Indique al modelo que sea breve. Por ejemplo:
Responde en una o dos frases. -
Fije una instantánea en producción.
gpt-realtime-mini-2025-12-15no cambia; el aliasgpt-realtime-minipuede actualizarse. -
Use
semantic_vad. Reduce interrupciones falsas y respuestas parciales desperdiciadas. - Cachee el prompt de sistema. La entrada en caché cuesta $0.30 por 1M frente a $0.60 por entrada de texto nueva.
- Cierre sesiones inactivas. No mantenga conexiones abiertas si el usuario abandonó el flujo.
- Mida segundos hablados por minuto. Es una métrica práctica para estimar costo real.
Errores comunes y soluciones
| Problema | Causa probable | Solución |
|---|---|---|
401 Unauthorized |
Clave incorrecta o token efímero caducado | Genere un token nuevo por sesión |
Model not found |
ID mal escrito | Use gpt-realtime-2.1-mini, no gpt-realtime-mini-2.1
|
| No hay audio en navegador | No adjuntó el stream remoto o no está en HTTPS/localhost | Revise pc.ontrack y permisos de micrófono |
| El modelo interrumpe al usuario | Detección de turno demasiado sensible | Use semantic_vad
|
| El modelo no responde | Faltó response.create
|
Envíelo después de añadir entrada |
| Eventos inesperados | Sesión mal configurada | Escuche session.updated y revise errores del servidor |
| Header beta enviado | Está usando configuración antigua | Elimine OpenAI-Beta: realtime=v1
|
Preguntas frecuentes
¿gpt-realtime-2.1-mini es lo mismo que gpt-realtime-mini?
Efectivamente sí, pero no son el mismo tipo de identificador. gpt-realtime-2.1-mini es el ID versionado. gpt-realtime-mini es el alias que apunta a la última instantánea, actualmente gpt-realtime-mini-2025-12-15.
Use el alias para construir y una instantánea fijada para producción.
¿Puedo usarlo solo para transcripción?
La API en tiempo real está diseñada para conversación interactiva de voz a voz. Para transcripciones puntuales, los modelos de transcripción dedicados de OpenAI suelen ser más adecuados. Use Realtime cuando necesite una conversación bidireccional de baja latencia.
¿Necesito WebRTC o WebSocket es suficiente?
WebSocket es suficiente para pipelines del lado servidor y prototipos rápidos. Use WebRTC cuando un navegador o app móvil capture y reproduzca audio directamente, porque maneja el flujo de medios y el jitter por usted.
¿Qué voz debería elegir?
marin y cedar son las voces más nuevas y naturales, exclusivas de la API en tiempo real. Las otras ocho voces —alloy, ash, ballad, coral, echo, sage, shimmer, verse— siguen funcionando si necesita un sonido concreto.
¿Cómo se factura?
Por token y por modalidad. Para el mini:
- $0.60 por 1M de entrada de texto.
- $0.30 por 1M de entrada en caché.
- $10 por 1M de entrada de audio.
- $20 por 1M de salida de audio.
La salida de audio suele dominar el costo, por lo que la verbosidad del agente es la principal palanca.
¿Puede llamar funciones como los modelos de chat?
Sí. Realtime usa el mismo contrato de llamada a funciones. Un agente de voz puede consultar pedidos, verificar inventario o activar acciones durante la conversación.
A dónde ir ahora
Ya tiene el ciclo completo:
- Elegir el ID correcto del modelo.
- Probar acceso con WebSocket.
- Configurar una sesión.
- Pasar a WebRTC para micrófono real.
- Añadir herramientas.
- Validar REST y WebSocket en Apidog.
- Fijar una instantánea antes de producción.
Empiece con el ejemplo WebSocket solo texto. Después cambie output_modalities a ["audio"]. Cuando el contrato funcione, implemente WebRTC en el navegador. Mantenga las respuestas cortas, use semantic_vad y fije una instantánea para tener un agente de voz de baja latencia sin sorpresas en producción.

Top comments (0)