RESUMEN
OpenAI ofrece dos modos de API WebSocket para diferentes casos de uso: el modo WebSocket de la API de respuestas para flujos de trabajo de agentes con mucha llamada a herramientas (hasta un 40% más rápido para más de 20 llamadas a herramientas), y la API en tiempo real para aplicaciones de voz y audio de baja latencia. Ambos utilizan conexiones WebSocket persistentes en lugar de solicitudes HTTP sin estado, lo que reduce la latencia al eliminar la sobrecarga de conexión repetida y permite interacciones impulsadas por eventos y con estado.
Introducción
La API de OpenAI ha evolucionado más allá de los patrones simples de solicitud-respuesta. Para aplicaciones que requieren llamadas rápidas a herramientas o transmisión de audio en tiempo real, el modelo HTTP tradicional crea una sobrecarga innecesaria. Cada nueva solicitud requiere configuración de conexión, autenticación y transmisión de estado, incluso cuando se continúa la misma conversación.
La API WebSocket de OpenAI resuelve esto manteniendo una conexión persistente y bidireccional. Para flujos de trabajo de agentes con más de 20 llamadas de herramientas secuenciales, esto se traduce en una ejecución de extremo a extremo aproximadamente un 40% más rápida. Para aplicaciones de voz, permite conversaciones naturales con capacidad de interrupción y latencias inferiores a 500 ms.
Esta guía cubre ambos modos WebSocket de OpenAI: la API de respuestas para flujos de trabajo de agentes con muchas herramientas y la API en tiempo real para la transmisión de audio. Aprenderá cuándo usar cada uno, cómo implementarlos y cómo probarlos de manera efectiva.
¿Qué es la API WebSocket de OpenAI?
La API WebSocket de OpenAI proporciona un mecanismo de transporte alternativo a HTTP para interactuar con los modelos de lenguaje de OpenAI. En lugar de crear una nueva conexión para cada llamada a la API, WebSocket establece una única conexión de larga duración que permanece abierta durante toda la sesión.
Características clave
Conexión persistente: Una vez establecida, la conexión WebSocket permanece abierta hasta que se cierra explícitamente, eliminando la sobrecarga de conexión por solicitud.
Comunicación bidireccional: Tanto el cliente como el servidor pueden enviar mensajes en cualquier momento, lo que permite arquitecturas verdaderamente impulsadas por eventos.
Sesiones con estado: El servidor mantiene el contexto de la conexión actual, lo que le permite hacer referencia a respuestas anteriores sin volver a enviar el historial completo de la conversación.
Modelo impulsado por eventos: La comunicación se realiza a través de eventos discretos (mensajes JSON) en lugar de pares de solicitud-respuesta.
Fundamentos del protocolo WebSocket
Las conexiones WebSocket comienzan con una solicitud de actualización HTTP y luego cambian al protocolo WebSocket. Para OpenAI, se conectará a puntos finales como:
- API de respuestas:
wss://api.openai.com/v1/responses - API en tiempo real:
wss://api.openai.com/v1/realtime?model=gpt-realtime
El esquema wss:// indica una conexión WebSocket segura (análoga a HTTPS para HTTP).
Explicación de los dos modos WebSocket
OpenAI ofrece dos modos WebSocket distintos, cada uno optimizado para diferentes casos de uso.
Modo WebSocket de la API de respuestas
La API de respuestas admite conexiones WebSocket para flujos de trabajo de agentes donde necesita realizar muchas llamadas de herramientas secuenciales. Este modo está diseñado para asistentes de codificación, sistemas de orquestación y agentes autónomos que llaman repetidamente a herramientas para realizar tareas complejas.
Cómo funciona:
En una conexión WebSocket activa, el servicio mantiene un estado de respuesta anterior en una caché en memoria local de la conexión (la respuesta más reciente). Cuando continúa un turno, solo envía:
previous_response_id(referencia a la última respuesta)- Nuevos elementos de entrada (mensajes de usuario, resultados de herramientas, etc.)
El servidor reutiliza el estado almacenado en caché en lugar de volver a procesar todo el historial de la conversación.
Beneficios de rendimiento:
Para flujos de trabajo con más de 20 llamadas de herramientas, OpenAI informa hasta un 40% más rápido de ejecución de extremo a extremo en comparación con HTTP. Esto proviene de:
- Sin configuración de conexión por solicitud
- Sin sobrecarga de autenticación repetida
- El estado en caché reduce el tiempo de procesamiento
- Menor latencia de red para mensajes de continuación pequeños
Compatibilidad:
El modo WebSocket funciona tanto con Retención Cero de Datos (ZDR) como con las opciones store=false, lo que lo hace adecuado para aplicaciones sensibles a la privacidad.
Modo WebSocket de la API en tiempo real
La API en tiempo real proporciona capacidades de audio de baja latencia y transmisión para aplicaciones controladas por voz. Permite interacciones de voz a voz donde el modelo puede responder a la entrada de audio con salida de audio, manejando las interrupciones de forma natural.
Cómo funciona:
La API en tiempo real utiliza WebSocket para crear una sesión con estado e impulsada por eventos. Usted transmite fragmentos de audio a la API, y esta devuelve tanto las transcripciones como las respuestas de audio generadas. La conexión admite:
- Transmisión de entrada de audio (enviar fragmentos de audio a medida que se capturan)
- Transmisión de salida de audio (recibir audio generado en tiempo real)
- Entrada/salida de texto (para interacciones híbridas de texto+voz)
- Manejo automático de interrupciones (detener la generación cuando el usuario habla)
Características clave:
Detección de actividad de voz (VAD): La API incluye VAD semántico que comprende cuándo un usuario ha terminado de hablar en lugar de simplemente hacer una pausa. Esto crea un flujo de conversación más natural.
Capacidades multimodales: Acceso directo a las capacidades multimodales nativas de GPT-4o, procesando audio y texto en un modelo unificado.
Baja latencia: Diseñada para latencias inferiores a 500 ms para interacciones de voz, adecuada para conversaciones en tiempo real.
WebSocket vs HTTP: Comparación de rendimiento
Elegir entre WebSocket y HTTP depende de las características de su aplicación. Aquí es cuando cada protocolo sobresale.

Cuando WebSocket supera a HTTP
Alto volumen de llamadas a herramientas:
Si su flujo de trabajo realiza más de 10 llamadas a herramientas secuenciales, la conexión persistente de WebSocket elimina la sobrecarga de configuración repetida. Cada solicitud HTTP requiere:
- Búsqueda DNS (si no está en caché)
- Handshake TCP (de 3 vías)
- Handshake TLS (2 viajes de ida y vuelta para TLS 1.3)
- Encabezados de solicitud/respuesta HTTP
WebSocket lo hace una vez y luego reutiliza la conexión.
Aplicaciones sensibles a la latencia:
Para aplicaciones de voz o chat en tiempo real donde cada milisegundo cuenta, la conexión persistente de WebSocket y las capacidades de transmisión reducen significativamente la latencia percibida.
Actualizaciones iniciadas por el servidor:
WebSocket permite al servidor enviar datos a los clientes sin sondeo. Para tareas de agente de larga duración, el servidor puede enviar actualizaciones de progreso a medida que ocurren los eventos.
Cuando HTTP es suficiente
Solicitud-Respuesta simple:
Para llamadas API únicas o flujos de trabajo con 1-2 llamadas a herramientas, HTTP es más simple de implementar y depurar. La mayoría de los desarrolladores están familiarizados con los clientes HTTP, y la infraestructura (balanceadores de carga, proxies) maneja bien HTTP.
Operaciones sin estado:
Si no necesita mantener el estado de la sesión entre solicitudes, la naturaleza sin estado de HTTP es en realidad una ventaja: no se requiere gestión de conexión.
Restricciones de infraestructura:
Algunos entornos de implementación (funciones sin servidor, ciertos proxies) no admiten conexiones WebSocket de larga duración. HTTP funciona universalmente.
Métricas de rendimiento
Según la documentación de OpenAI y las pruebas de la comunidad:
| Métrica | HTTP | WebSocket (API de respuestas) | WebSocket (API en tiempo real) |
|---|---|---|---|
| Configuración de conexión | Cada solicitud (~100-300ms) | Una vez (~100-300ms) | Una vez (~100-300ms) |
| Flujo de trabajo de más de 20 llamadas a herramientas | Base | ~40% más rápido | N/A |
| Latencia de ida y vuelta de voz | N/A (no diseñado para esto) | N/A | <500ms |
| Sobrecarga de memoria | Baja (sin estado) | Media (estado en caché) | Media-Alta (estado de sesión) |
| Complejidad de implementación | Baja | Media | Media-Alta |
Cómo usar el modo WebSocket de la API de respuestas
Implementemos una conexión WebSocket a la API de respuestas para un flujo de trabajo de agente.
Requisitos previos
- Clave API de OpenAI con acceso a la API de respuestas
- Biblioteca cliente de WebSocket (
wspara Node.js owebsocket-clientpara Python) - Comprensión de la llamada a herramientas en la API de OpenAI
Configuración de conexión
Ejemplo de Node.js:
const WebSocket = require('ws');
// Conectarse al punto final WebSocket de la API de respuestas
const ws = new WebSocket('wss://api.openai.com/v1/responses', {
headers: {
'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
'OpenAI-Beta': 'responses-api=v1'
}
});
ws.on('open', () => {
console.log('Conectado a la API de respuestas de OpenAI');
// Enviar solicitud inicial
const initialMessage = {
model: 'gpt-4o',
messages: [
{ role: 'user', content: 'Ayúdame a analizar esta base de código y sugerir mejoras.' }
],
tools: [
{
type: 'function',
function: {
name: 'read_file',
description: 'Leer el contenido de un archivo',
parameters: {
type: 'object',
properties: {
path: { type: 'string', description: 'Ruta del archivo a leer' }
},
required: ['path']
}
}
},
{
type: 'function',
function: {
name: 'search_code',
description: 'Buscar patrones de código',
parameters: {
type: 'object',
properties: {
pattern: { type: 'string', description: 'Patrón de expresión regular a buscar' }
},
required: ['pattern']
}
}
}
]
};
ws.send(JSON.stringify(initialMessage));
});
ws.on('message', (data) => {
const response = JSON.parse(data);
console.log('Recibido:', response);
// Comprobar si el modelo quiere llamar a herramientas
if (response.choices[0].finish_reason === 'tool_calls') {
const toolCalls = response.choices[0].message.tool_calls;
// Ejecutar herramientas (simplificado)
const toolResults = toolCalls.map(call => ({
tool_call_id: call.id,
output: executeToolLocally(call.function.name, call.function.arguments)
}));
// Continuar la conversación con los resultados de las herramientas
const continuation = {
previous_response_id: response.id, // Referenciar respuesta anterior
input: toolResults
};
ws.send(JSON.stringify(continuation));
}
});
ws.on('error', (error) => {
console.error('Error de WebSocket:', error);
});
ws.on('close', () => {
console.log('Conexión cerrada');
});
function executeToolLocally(name, args) {
// Su lógica de ejecución de herramientas
if (name === 'read_file') {
const { path } = JSON.parse(args);
return fs.readFileSync(path, 'utf-8');
}
// ... otras herramientas
}
Ejemplo de Python:
import websocket
import json
import os
def on_message(ws, message):
response = json.loads(message)
print(f"Recibido: {response}")
# Manejar llamadas a herramientas
if response['choices'][0]['finish_reason'] == 'tool_calls':
tool_calls = response['choices'][0]['message']['tool_calls']
# Ejecutar herramientas
tool_results = []
for call in tool_calls:
result = execute_tool(call['function']['name'],
json.loads(call['function']['arguments']))
tool_results.append({
'tool_call_id': call['id'],
'output': result
})
# Enviar continuación solo con nueva entrada + previous_response_id
continuation = {
'previous_response_id': response['id'],
'input': tool_results
}
ws.send(json.dumps(continuation))
def on_error(ws, error):
print(f"Error: {error}")
def on_close(ws, close_status_code, close_msg):
print("Conexión cerrada")
def on_open(ws):
print("Conectado a la API de respuestas de OpenAI")
# Enviar solicitud inicial
initial_message = {
'model': 'gpt-4o',
'messages': [
{'role': 'user', 'content': 'Analiza esta base de código y sugiere mejoras.'}
],
'tools': [
{
'type': 'function',
'function': {
'name': 'read_file',
'description': 'Leer el contenido del archivo',
'parameters': {
'type': 'object',
'properties': {
'path': {'type': 'string'}
},
'required': ['path']
}
}
}
]
}
ws.send(json.dumps(initial_message))
def execute_tool(name, args):
if name == 'read_file':
with open(args['path'], 'r') as f:
return f.read()
# ... otras herramientas
# Crear conexión WebSocket
ws = websocket.WebSocketApp(
"wss://api.openai.com/v1/responses",
header={
"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}",
"OpenAI-Beta": "responses-api=v1"
},
on_open=on_open,
on_message=on_message,
on_error=on_error,
on_close=on_close
)
ws.run_forever()
Detalles clave de implementación
Gestión de estado:
La diferencia crítica con HTTP es el uso de previous_response_id en las continuaciones. Esto le dice a la API que reutilice el estado en caché de la última respuesta.
Continuaciones solo de entrada:
Al continuar un turno, envíe solo:
previous_response_id: Referencia la respuesta en cachéinput: Nuevos datos (resultados de herramientas, mensajes de usuario, etc.)
No reenvíe el array completo messages: el servidor ya tiene ese contexto.
Retención Cero de Datos:
Para usar ZDR con el modo WebSocket, incluya store: false en su solicitud inicial.
Cómo usar el modo WebSocket de la API en tiempo real
La API en tiempo real permite interacciones de voz de baja latencia. Así es como se implementa.
Requisitos previos
- Clave API de OpenAI con acceso a la API en tiempo real
- Capacidades de captura/reproducción de audio
- Biblioteca cliente de WebSocket
- Codificación de audio (PCM mono de 24 kHz, 16 bits para mejores resultados)
Configuración de conexión
Ejemplo de JavaScript (Navegador):
// Conectarse a la API en tiempo real
const ws = new WebSocket(
`wss://api.openai.com/v1/realtime?model=gpt-realtime`,
['realtime', 'openai-insecure-api-key.' + process.env.OPENAI_API_KEY]
);
ws.addEventListener('open', () => {
console.log('Conectado a la API en tiempo real');
// Configurar sesión
ws.send(JSON.stringify({
type: 'session.update',
session: {
modalities: ['text', 'audio'],
voice: 'alloy',
input_audio_format: 'pcm16',
output_audio_format: 'pcm16',
turn_detection: {
type: 'server_vad', // o 'semantic_vad' para detección más inteligente
threshold: 0.5,
prefix_padding_ms: 300,
silence_duration_ms: 500
}
}
}));
});
ws.addEventListener('message', (event) => {
const message = JSON.parse(event.data);
switch (message.type) {
case 'session.created':
console.log('Sesión creada:', message.session);
break;
case 'conversation.item.created':
console.log('Nuevo elemento:', message.item);
break;
case 'response.audio.delta':
// Fragmento de audio recibido - reproducirlo
const audioChunk = base64ToArrayBuffer(message.delta);
playAudioChunk(audioChunk);
break;
case 'response.audio_transcript.delta':
// Fragmento de transcripción recibido
console.log('Transcripción:', message.delta);
break;
case 'input_audio_buffer.speech_started':
console.log('El usuario empezó a hablar');
break;
case 'input_audio_buffer.speech_stopped':
console.log('El usuario dejó de hablar');
break;
case 'error':
console.error('Error de API:', message.error);
break;
}
});
// Enviar audio desde el micrófono
async function streamMicrophoneToAPI() {
const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
const audioContext = new AudioContext({ sampleRate: 24000 });
const source = audioContext.createMediaStreamSource(stream);
const processor = audioContext.createScriptProcessor(4096, 1, 1);
processor.onaudioprocess = (e) => {
const inputData = e.inputBuffer.getChannelData(0);
// Convertir Float32 a Int16 PCM
const pcmData = new Int16Array(inputData.length);
for (let i = 0; i < inputData.length; i++) {
pcmData[i] = Math.max(-32768, Math.min(32767, inputData[i] * 32768));
}
// Enviar a la API
ws.send(JSON.stringify({
type: 'input_audio_buffer.append',
audio: arrayBufferToBase64(pcmData.buffer)
}));
};
source.connect(processor);
processor.connect(audioContext.destination);
}
// Enviar entrada de texto
function sendTextMessage(text) {
ws.send(JSON.stringify({
type: 'conversation.item.create',
item: {
type: 'message',
role: 'user',
content: [
{ type: 'input_text', text: text }
]
}
}));
// Solicitar generación de respuesta
ws.send(JSON.stringify({
type: 'response.create'
}));
}
function playAudioChunk(arrayBuffer) {
const audioContext = new AudioContext({ sampleRate: 24000 });
audioContext.decodeAudioData(arrayBuffer, (buffer) => {
const source = audioContext.createBufferSource();
source.buffer = buffer;
source.connect(audioContext.destination);
source.start();
});
}
Ejemplo de Python:
import websocket
import json
import base64
import pyaudio
# Configuración de audio
RATE = 24000
CHUNK = 4096
FORMAT = pyaudio.paInt16
CHANNELS = 1
audio = pyaudio.PyAudio()
def on_open(ws):
print("Conectado a la API en tiempo real")
# Configurar sesión
ws.send(json.dumps({
'type': 'session.update',
'session': {
'modalities': ['text', 'audio'],
'voice': 'alloy',
'input_audio_format': 'pcm16',
'output_audio_format': 'pcm16',
'turn_detection': {
'type': 'server_vad',
'threshold': 0.5,
'silence_duration_ms': 500
}
}
}))
# Iniciar transmisión del micrófono
stream_microphone(ws)
def on_message(ws, message):
data = json.loads(message)
if data['type'] == 'response.audio.delta':
# Decodificar y reproducir audio
audio_chunk = base64.b64decode(data['delta'])
play_audio(audio_chunk)
elif data['type'] == 'response.audio_transcript.delta':
print(f"Transcripción: {data['delta']}", end='', flush=True)
elif data['type'] == 'input_audio_buffer.speech_started':
print("\n[Usuario hablando...]")
elif data['type'] == 'error':
print(f"Error: {data['error']}")
def stream_microphone(ws):
stream = audio.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK
)
def audio_thread():
while True:
audio_data = stream.read(CHUNK)
ws.send(json.dumps({
'type': 'input_audio_buffer.append',
'audio': base64.b64encode(audio_data).decode('utf-8')
}))
import threading
threading.Thread(target=audio_thread, daemon=True).start()
def play_audio(audio_chunk):
stream = audio.open(
format=FORMAT,
channels=CHANNELS,
rate=RATE,
output=True
)
stream.write(audio_chunk)
stream.stop_stream()
stream.close()
# Crear conexión WebSocket
ws = websocket.WebSocketApp(
f"wss://api.openai.com/v1/realtime?model=gpt-realtime",
header={
"Authorization": f"Bearer {os.environ['OPENAI_API_KEY']}"
},
on_open=on_open,
on_message=on_message
)
ws.run_forever()
Detalles clave de implementación
Tipos de eventos:
La API en tiempo real utiliza comunicación impulsada por eventos. Eventos comunes:
Cliente → Servidor:
session.update- Configurar parámetros de sesióninput_audio_buffer.append- Enviar fragmentos de audioconversation.item.create- Añadir mensajes de textoresponse.create- Solicitar respuesta de IA
Servidor → Cliente:
session.created- Confirma la configuración de la sesiónresponse.audio.delta- Fragmento de audio de la IAresponse.audio_transcript.delta- Transcripción del audio de la IAinput_audio_buffer.speech_started/stopped- Eventos de VADerror- Notificaciones de error
Detección de actividad de voz:
Elija entre dos modos de VAD:
server_vad: Detección básica de actividad de voz basada en el volumen del audio y la duración del silencio.
semantic_vad: Detección más inteligente que comprende las pausas naturales frente a la finalización del turno. Use esto para conversaciones más naturales donde los usuarios podrían hacer una pausa a mitad de una idea.
Probando conexiones WebSocket con Apidog
Probar APIs WebSocket difiere de las pruebas HTTP: necesita mantener una conexión, enviar eventos y monitorear el flujo de mensajes bidireccional. Apidog proporciona capacidades especializadas de prueba de WebSocket.

Configuración de pruebas WebSocket en Apidog
Paso 1: Crear solicitud WebSocket
En Apidog, cree una nueva solicitud y seleccione "WebSocket" como protocolo. Ingrese su URL de conexión:

wss://api.openai.com/v1/responses
Paso 2: Configurar encabezados
Agregue encabezados de autenticación:
Authorization: Bearer YOUR_OPENAI_API_KEY
OpenAI-Beta: responses-api=v1
Para la API en tiempo real, también puede usar autenticación basada en URL:
wss://api.openai.com/v1/realtime?model=gpt-realtime
Con la clave API en el encabezado del subprotocolo.
Paso 3: Establecer conexión
Haga clic en "Conectar" para establecer la conexión WebSocket. Apidog muestra:
- Estado de la conexión (conectado/desconectado)
- Métricas de latencia
- Duración de la conexión
Paso 4: Enviar eventos
Use el compositor de mensajes de Apidog para enviar eventos JSON. Para la API de respuestas:
{
"model": "gpt-4o",
"messages": [
{
"role": "user",
"content": "¿Qué tiempo hace en San Francisco?"
}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Obtener el tiempo actual",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
}
}
}
}
]
}
Paso 5: Monitorear respuestas
Apidog muestra:
- Todos los mensajes recibidos en orden cronológico
- Marcas de tiempo y tamaños de los mensajes
- Formato JSON y resaltado de sintaxis
- Capacidades de copiar/exportar para depuración
Probando continuaciones
Para probar el patrón de continuación con previous_response_id:
- Envíe el mensaje inicial, anote el
response.iden la respuesta - Envíe la continuación solo con la nueva entrada:
{
"previous_response_id": "resp_abc123",
"input": [
{
"tool_call_id": "call_xyz789",
"output": "{\"temperatura\": 72, \"condiciones\": \"soleado\"}"
}
]
}
- Observe la latencia reducida en comparación con el reenvío del contexto completo
Probando la API en tiempo real
Para la API en tiempo real, Apidog le permite:
- Enviar fragmentos de audio codificados en base64
- Monitorear eventos de
session.update - Rastrear eventos VAD (inicio/parada de voz)
- Ver deltas de transcripción en tiempo real
Esto es particularmente útil para depurar por qué su asistente de voz podría estar cortando a los usuarios o no detectando el habla correctamente.
Variables de entorno
Almacene las claves API de forma segura utilizando las variables de entorno de Apidog:
{{OPENAI_API_KEY}}
Esto le permite alternar entre claves de desarrollo y producción sin editar las solicitudes.
Casos de uso en el mundo real
Exploremos escenarios prácticos donde los modos WebSocket de OpenAI sobresalen.
Caso de uso 1: Agente de codificación autónomo
Escenario: Un asistente de codificación que analiza bases de código, identifica problemas y realiza mejoras de forma autónoma.
Por qué la API de respuestas WebSocket:
- Flujo de trabajo típico: Leer archivo → Analizar → Buscar patrones similares → Leer más archivos → Sugerir cambios
- Esto crea 15-30 llamadas a herramientas por tarea
- El modo WebSocket reduce el tiempo total de ejecución en ~40%
- La conexión persistente mantiene el contexto en todas las llamadas a herramientas
Patrón de implementación:
// Tarea inicial
ws.send({ messages: [{ role: 'user', content: 'Auditar vulnerabilidades de seguridad' }], tools: [...] })
// Primera respuesta: el modelo llama a read_file
ws.on('message', (resp1) => {
ws.send({ previous_response_id: resp1.id, input: [tool_result_1] })
})
// Segunda respuesta: el modelo llama a search_code
ws.on('message', (resp2) => {
ws.send({ previous_response_id: resp2.id, input: [tool_result_2] })
})
// Continuar por más de 20 iteraciones...
Caso de uso 2: Bot de servicio al cliente por voz
Escenario: Un bot de soporte telefónico que maneja consultas de clientes con un flujo de conversación natural.
Por qué la API en tiempo real WebSocket:
- Baja latencia crítica (<500ms para conversación natural)
- Necesita manejar interrupciones (el cliente habla por encima del bot)
- Procesa la entrada de voz directamente sin transcripción separada
- Transmite respuestas en tiempo real (no espera la frase completa)
Patrón de implementación:
// Transmitir audio del teléfono a la API
phoneSystem.on('audio', (chunk) => {
ws.send({
type: 'input_audio_buffer.append',
audio: base64Encode(chunk)
})
})
// Reproducir respuestas de IA inmediatamente
ws.on('message', (event) => {
if (event.type === 'response.audio.delta') {
phoneSystem.playAudio(base64Decode(event.delta))
}
})
Solución de problemas comunes
La conexión no se establece
Síntomas: La conexión WebSocket nunca se abre, evento de cierre inmediato.
Causas comunes:
- Clave API no válida - Verifique dos veces su encabezado
Authorization - Encabezado beta faltante - La API de respuestas requiere
OpenAI-Beta: responses-api=v1 - Restricciones de red - Algunas redes corporativas bloquean WebSocket
- URL incorrecta - Verifique
wss://(nows://) y la ruta del punto final
Solución:
Use Apidog para probar la conexión con mensajes de error detallados. El inspector de solicitudes muestra exactamente qué encabezados se envían, lo que facilita la detección de claves API faltantes o incorrectas.
Código de depuración:
ws.on('error', (error) => {
console.error('Error de conexión:', error);
});
ws.on('close', (code, reason) => {
console.log(`Cerrado con código ${code}: ${reason}`);
// Códigos comunes:
// 1006: Cierre anormal (a menudo problemas de autenticación)
// 1008: Violación de política (encabezados no válidos)
});
Alta latencia a pesar de WebSocket
Síntomas: La conexión WebSocket funciona pero no es más rápida que HTTP.
Causas comunes:
- No usar
previous_response_id- Está reenviando el contexto completo - Arranque en frío - La primera solicitud en una nueva conexión es más lenta
- Latencia de red - Distancia geográfica a los servidores de la API
- Grandes cargas útiles - Envío de datos innecesarios en las continuaciones
Solución:
Verifique que solo está enviando nueva entrada en las continuaciones:
// INCORRECTO - envía el contexto completo cada vez
ws.send({
messages: [...allPreviousMessages, newMessage],
tools: [...]
})
// CORRECTO - referencia el estado en caché
ws.send({
previous_response_id: lastResponse.id,
input: [newMessage]
})
Fugas de memoria en conexiones de larga duración
Síntomas: La memoria de la aplicación crece con el tiempo con la conexión persistente.
Causas comunes:
- Listeners de eventos no eliminados - Acumulación de listeners en la reconexión
- Buffers de audio no liberados - Mantener referencias al audio reproducido
- Historial de mensajes en crecimiento - Almacenamiento de todos los mensajes recibidos
Solución:
// Limpiar listeners de eventos al reconectar
function cleanupAndReconnect(ws) {
ws.removeAllListeners();
ws.close();
const newWs = createConnection();
return newWs;
}
// Liberar buffers de audio después de reproducir
function playAndRelease(audioBuffer) {
const source = audioContext.createBufferSource();
source.buffer = audioBuffer;
source.connect(audioContext.destination);
source.start();
source.onended = () => {
source.disconnect();
// El buffer será recolectado por el recolector de basura
};
}
// Limitar historial de mensajes
const messageHistory = [];
const MAX_HISTORY = 100;
ws.on('message', (data) => {
messageHistory.push(data);
if (messageHistory.length > MAX_HISTORY) {
messageHistory.shift(); // Eliminar el más antiguo
}
});
Conclusión
Los modos WebSocket de la API de OpenAI abren nuevas posibilidades para las aplicaciones de IA. El modo WebSocket de la API de respuestas ofrece una ejecución hasta un 40% más rápida para flujos de trabajo de agentes con mucha llamada a herramientas, lo que lo hace ideal para asistentes de codificación autónomos y sistemas de orquestación. La API en tiempo real proporciona una latencia inferior a 500 ms para aplicaciones de voz, permitiendo conversaciones naturales con capacidad de interrupción.
Elegir el modo correcto depende de su caso de uso:
- API de respuestas WebSocket: Agentes con muchas herramientas, asistentes de codificación, herramientas de investigación (más de 10 llamadas a herramientas)
- API en tiempo real WebSocket: Asistentes de voz, bots telefónicos, tutores de idiomas (transmisión de audio)
- HTTP: Solicitudes simples, entornos sin servidor, 1-5 llamadas a la API
La naturaleza persistente y basada en eventos de las conexiones WebSocket requiere enfoques de prueba diferentes a los de HTTP. Pruebe las API WebSocket de OpenAI con el cliente WebSocket en tiempo real de Apidog: importe su clave API, establezca conexiones, envíe eventos y monitoree las respuestas con un registro detallado. Pruébelo gratis para validar sus integraciones antes de la implementación en producción.
