Comment utiliser l'API WebSocket Mode d'OpenAI ?

Ashley Innocent

Ashley Innocent

24 February 2026

Comment utiliser l'API WebSocket Mode d'OpenAI ?

Apidog pour les entreprises

Déploiement sur site

SSO & RBAC

Conforme SOC 2

Découvrir Apidog Enterprise

TL;DR

OpenAI propose deux modes d'API WebSocket pour différents cas d'utilisation : le mode WebSocket de l'API de réponses pour les workflows agentiques avec de nombreux appels d'outils (jusqu'à 40 % plus rapide pour plus de 20 appels d'outils), et l'API en temps réel pour les applications vocales et audio à faible latence. Les deux utilisent des connexions WebSocket persistantes au lieu de requêtes HTTP sans état, ce qui réduit la latence en éliminant les frais généraux de connexion répétés et permet des interactions événementielles et avec état.

Introduction

L'API d'OpenAI a évolué au-delà des simples modèles de requête-réponse. Pour les applications nécessitant des appels d'outils rapides ou le streaming audio en temps réel, le modèle HTTP traditionnel génère une surcharge inutile. Chaque nouvelle requête nécessite la mise en place d'une connexion, une authentification et la transmission de l'état — même lorsque vous poursuivez la même conversation.

L'API WebSocket d'OpenAI résout ce problème en maintenant une connexion persistante et bidirectionnelle. Pour les workflows agentiques avec plus de 20 appels d'outils séquentiels, cela se traduit par une exécution de bout en bout environ 40 % plus rapide. Pour les applications vocales, cela permet des conversations naturelles et interruptibles avec des latences inférieures à 500 ms.

💡
Le test des connexions WebSocket nécessitait traditionnellement des outils de débogage complexes. L'interface de test WebSocket d'Apidog vous permet d'établir des connexions, d'envoyer des événements et de surveiller les réponses en temps réel — essentiel pour valider les intégrations WebSocket d'OpenAI avant le déploiement en production.
bouton

Ce guide couvre les deux modes WebSocket d'OpenAI : l'API de réponses pour les workflows d'agents à forte utilisation d'outils, et l'API en temps réel pour le streaming audio. Vous apprendrez quand utiliser chacun d'eux, comment les implémenter et comment les tester efficacement.

Qu'est-ce que l'API WebSocket d'OpenAI ?

L'API WebSocket d'OpenAI offre un mécanisme de transport alternatif à HTTP pour interagir avec les modèles linguistiques d'OpenAI. Au lieu de créer une nouvelle connexion pour chaque appel d'API, WebSocket établit une connexion unique et durable qui reste ouverte pendant toute la durée de votre session.

Caractéristiques Clés

Principes de Base du Protocole WebSocket

Les connexions WebSocket commencent par une requête de mise à niveau HTTP, puis passent au protocole WebSocket. Pour OpenAI, vous vous connecterez à des points d'accès comme :

Le schéma wss:// indique une connexion WebSocket sécurisée (analogue à HTTPS pour HTTP).

Deux Modes WebSocket Expliqués

OpenAI propose deux modes WebSocket distincts, chacun optimisé pour des cas d'utilisation différents.

Mode WebSocket de l'API de Réponses

L'API de Réponses prend en charge les connexions WebSocket pour les workflows agentiques où vous devez effectuer de nombreux appels d'outils séquentiels. Ce mode est conçu pour les assistants de codage, les systèmes d'orchestration et les agents autonomes qui appellent à plusieurs reprises des outils pour accomplir des tâches complexes.

Comment ça Fonctionne :

Sur une connexion WebSocket active, le service maintient un état de réponse précédente dans un cache en mémoire local à la connexion (la réponse la plus récente). Lorsque vous continuez un tour, vous n'envoyez que :

Le serveur réutilise l'état mis en cache au lieu de retraiter l'historique complet de la conversation.

Avantages en Termes de Performance :

Pour les workflows avec plus de 20 appels d'outils, OpenAI rapporte jusqu'à 40 % d'exécution de bout en bout plus rapide par rapport à HTTP. Cela provient de :

Compatibilité :

Le mode WebSocket fonctionne avec les options Zero Data Retention (ZDR) et store=false, le rendant adapté aux applications soucieuses de la confidentialité.

Mode WebSocket de l'API en Temps Réel

L'API en Temps Réel offre des capacités audio en streaming à faible latence pour les applications vocales. Elle permet des interactions parole-à-parole où le modèle peut répondre à une entrée audio avec une sortie audio, gérant les interruptions naturellement.

Comment ça Fonctionne :

L'API en Temps Réel utilise WebSocket pour créer une session avec état, axée sur les événements. Vous diffusez des fragments audio vers l'API, et elle renvoie en streaming à la fois les transcriptions et les réponses audio générées. La connexion prend en charge :

Fonctionnalités Clés :

Détection d'Activité Vocale (VAD) : L'API inclut une VAD sémantique qui comprend quand un utilisateur a fini de parler par opposition à une simple pause. Cela crée un flux de conversation plus naturel.

Capacités Multimodales : Accès direct aux capacités multimodales natives de GPT-4o, traitant à la fois l'audio et le texte dans un modèle unifié.

Faible Latence : Conçu pour des latences inférieures à 500 ms pour les interactions vocales, adapté aux conversations en temps réel.

WebSocket vs HTTP : Comparaison des Performances

Le choix entre WebSocket et HTTP dépend des caractéristiques de votre application. Voici quand chaque protocole excelle.

WebSocket vs HTTP

Quand WebSocket Surpasse HTTP

Volume Élevé d'Appels d'Outils :
Si votre workflow effectue plus de 10 appels d'outils séquentiels, la connexion persistante de WebSocket élimine la surcharge de configuration répétée. Chaque requête HTTP nécessite :

WebSocket le fait une fois, puis réutilise la connexion.

Applications Sensibles à la Latence :
Pour les applications vocales ou de chat en temps réel où chaque milliseconde compte, la connexion persistante de WebSocket et ses capacités de streaming réduisent considérablement la latence perçue.

Mises à Jour Initiées par le Serveur :
WebSocket permet au serveur de pousser des données aux clients sans interrogation. Pour les tâches d'agent de longue durée, le serveur peut envoyer des mises à jour de progression à mesure que les événements se produisent.

Quand HTTP est Suffisant

Requête-Réponse Simple :
Pour les appels d'API ponctuels ou les workflows avec 1 à 2 appels d'outils, HTTP est plus simple à implémenter et à déboguer. La plupart des développeurs sont familiers avec les clients HTTP, et l'infrastructure (répartiteurs de charge, proxys) gère bien HTTP.

Opérations Sans État :
Si vous n'avez pas besoin de maintenir l'état de session entre les requêtes, la nature sans état de HTTP est en fait un avantage — aucune gestion de connexion n'est requise.

Contraintes d'Infrastructure :
Certains environnements de déploiement (fonctions sans serveur, certains proxys) ne prennent pas en charge les connexions WebSocket de longue durée. HTTP fonctionne universellement.

Métriques de Performance

Basé sur la documentation d'OpenAI et les tests de la communauté :

MétriquesHTTPWebSocket (API de Réponses)WebSocket (API en Temps Réel)
Établissement de la ConnexionChaque requête (~100-300ms)Une fois (~100-300ms)Une fois (~100-300ms)
Workflow avec 20+ Appels d'OutilsRéférence~40% plus rapideN/A
Latence Aller-Retour VocaleN/A (non conçu pour cela)N/A<500ms
Surcharge MémoireFaible (sans état)Moyenne (état mis en cache)Moyenne-Élevée (état de session)
Complexité d'ImplémentationFaibleMoyenneMoyenne-Élevée

Comment Utiliser le Mode WebSocket de l'API de Réponses

Implémentons une connexion WebSocket à l'API de Réponses pour un workflow agentique.

Prérequis

Configuration de la Connexion

Exemple Node.js :

const WebSocket = require('ws');

// Se connecter au point d'accès WebSocket de l'API de Réponses
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('Connected to OpenAI Responses API');

  // Envoyer la requête initiale
  const initialMessage = {
    model: 'gpt-4o',
    messages: [
      { role: 'user', content: 'Help me analyze this codebase and suggest improvements.' }
    ],
    tools: [
      {
        type: 'function',
        function: {
          name: 'read_file',
          description: 'Read contents of a file',
          parameters: {
            type: 'object',
            properties: {
              path: { type: 'string', description: 'File path to read' }
            },
            required: ['path']
          }
        }
      },
      {
        type: 'function',
        function: {
          name: 'search_code',
          description: 'Search for code patterns',
          parameters: {
            type: 'object',
            properties: {
              pattern: { type: 'string', description: 'Regex pattern to search' }
            },
            required: ['pattern']
          }
        }
      }
    ]
  };

  ws.send(JSON.stringify(initialMessage));
});

ws.on('message', (data) => {
  const response = JSON.parse(data);
  console.log('Received:', response);

  // Vérifier si le modèle veut appeler des outils
  if (response.choices[0].finish_reason === 'tool_calls') {
    const toolCalls = response.choices[0].message.tool_calls;

    // Exécuter les outils (simplifié)
    const toolResults = toolCalls.map(call => ({
      tool_call_id: call.id,
      output: executeToolLocally(call.function.name, call.function.arguments)
    }));

    // Continuer la conversation avec les résultats des outils
    const continuation = {
      previous_response_id: response.id, // Référence la réponse précédente
      input: toolResults
    };

    ws.send(JSON.stringify(continuation));
  }
});

ws.on('error', (error) => {
  console.error('WebSocket error:', error);
});

ws.on('close', () => {
  console.log('Connection closed');
});

function executeToolLocally(name, args) {
  // Votre logique d'exécution d'outil
  if (name === 'read_file') {
    const { path } = JSON.parse(args);
    return fs.readFileSync(path, 'utf-8');
  }
  // ... autres outils
}

Exemple Python :

import websocket
import json
import os

def on_message(ws, message):
    response = json.loads(message)
    print(f"Received: {response}")

    # Gérer les appels d'outils
    if response['choices'][0]['finish_reason'] == 'tool_calls':
        tool_calls = response['choices'][0]['message']['tool_calls']

        # Exécuter les outils
        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
            })

        # Envoyer la continuation avec seulement la nouvelle entrée + 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("Connection closed")

def on_open(ws):
    print("Connected to OpenAI Responses API")

    # Envoyer la requête initiale
    initial_message = {
        'model': 'gpt-4o',
        'messages': [
            {'role': 'user', 'content': 'Analyze this codebase and suggest improvements.'}
        ],
        'tools': [
            {
                'type': 'function',
                'function': {
                    'name': 'read_file',
                    'description': 'Read file contents',
                    '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()
    # ... autres outils

# Créer la connexion 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()

Détails Clés de l'Implémentation

Gestion de l'État :
La différence essentielle par rapport à HTTP est l'utilisation de previous_response_id dans les continuations. Cela indique à l'API de réutiliser l'état mis en cache de la dernière réponse.

Continuations Uniquement d'Entrée :
Lors de la continuation d'un tour, n'envoyez que :

Ne renvoyez pas le tableau messages complet — le serveur a déjà ce contexte.

Rétention Zéro Données :
Pour utiliser le ZDR avec le mode WebSocket, incluez store: false dans votre requête initiale.

Comment Utiliser le Mode WebSocket de l'API en Temps Réel

L'API en Temps Réel permet des interactions vocales à faible latence. Voici comment l'implémenter.

Prérequis

Configuration de la Connexion

Exemple JavaScript (Navigateur) :

// Se connecter à l'API en Temps Réel
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('Connected to Realtime API');

  // Configurer la session
  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', // or 'semantic_vad' for smarter detection
        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('Session created:', message.session);
      break;

    case 'conversation.item.created':
      console.log('New item:', message.item);
      break;

    case 'response.audio.delta':
      // Fragment audio reçu - le lire
      const audioChunk = base64ToArrayBuffer(message.delta);
      playAudioChunk(audioChunk);
      break;

    case 'response.audio_transcript.delta':
      // Fragment de transcription reçu
      console.log('Transcript:', message.delta);
      break;

    case 'input_audio_buffer.speech_started':
      console.log('User started speaking'); // L'utilisateur a commencé à parler
      break;

    case 'input_audio_buffer.speech_stopped':
      console.log('User stopped speaking'); // L'utilisateur a arrêté de parler
      break;

    case 'error':
      console.error('API error:', message.error); // Erreur API
      break;
  }
});

// Envoyer l'audio du microphone
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 en 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));
    }

    // Envoyer à l'API
    ws.send(JSON.stringify({
      type: 'input_audio_buffer.append',
      audio: arrayBufferToBase64(pcmData.buffer)
    }));
  };

  source.connect(processor);
  processor.connect(audioContext.destination);
}

// Envoyer l'entrée texte
function sendTextMessage(text) {
  ws.send(JSON.stringify({
    type: 'conversation.item.create',
    item: {
      type: 'message',
      role: 'user',
      content: [
        { type: 'input_text', text: text }
      ]
    }
  }));

  // Demander la génération de réponse
  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();
  });
}

Exemple Python :

import websocket
import json
import base64
import pyaudio

# Configuration audio
RATE = 24000
CHUNK = 4096
FORMAT = pyaudio.paInt16
CHANNELS = 1

audio = pyaudio.PyAudio()

def on_open(ws):
    print("Connected to Realtime API")

    # Configurer la session
    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
            }
        }
    }))

    # Commencer le streaming du microphone
    stream_microphone(ws)

def on_message(ws, message):
    data = json.loads(message)

    if data['type'] == 'response.audio.delta':
        # Décoder et lire l'audio
        audio_chunk = base64.b64decode(data['delta'])
        play_audio(audio_chunk)

    elif data['type'] == 'response.audio_transcript.delta':
        print(f"Transcript: {data['delta']}", end='', flush=True)

    elif data['type'] == 'input_audio_buffer.speech_started':
        print("\n[User speaking...]") # L'utilisateur parle...

    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()

# Créer la connexion 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()

Détails Clés de l'Implémentation

Types d'Événements :

L'API en Temps Réel utilise une communication événementielle. Événements courants :

Client → Serveur :

Serveur → Client :

Détection d'Activité Vocale :

Choisissez entre deux modes VAD :

server_vad : Détection d'activité vocale de base basée sur le volume audio et la durée du silence.

semantic_vad : Détection plus intelligente qui comprend les pauses naturelles par opposition à la fin du tour. Utilisez-la pour des conversations plus naturelles où les utilisateurs pourraient faire une pause en pleine réflexion.

Tester les Connexions WebSocket avec Apidog

Tester les API WebSocket diffère du test HTTP — vous devez maintenir une connexion, envoyer des événements et surveiller le flux de messages bidirectionnel. Apidog offre des capacités spécialisées de test WebSocket.

Interface de Conception Web Apidog

Configuration des Tests WebSocket dans Apidog

Étape 1 : Créer une Requête WebSocket

Dans Apidog, créez une nouvelle requête et sélectionnez "WebSocket" comme protocole. Entrez votre URL de connexion :

Créer une Requête WebSocket Dans Apidog
wss://api.openai.com/v1/responses

Étape 2 : Configurer les En-têtes

Ajoutez les en-têtes d'authentification :

Authorization: Bearer YOUR_OPENAI_API_KEY
OpenAI-Beta: responses-api=v1

Pour l'API en temps réel, vous pouvez également utiliser l'authentification basée sur l'URL :

wss://api.openai.com/v1/realtime?model=gpt-realtime

Avec la clé API dans l'en-tête du sous-protocole.

Étape 3 : Établir la Connexion

Cliquez sur "Connecter" pour établir la connexion WebSocket. Apidog affiche :

Étape 4 : Envoyer des Événements

Utilisez le composeur de messages d'Apidog pour envoyer des événements JSON. Pour l'API de Réponses :

{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "What's the weather in San Francisco?"
    }
  ],
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "get_weather",
        "description": "Get current weather",
        "parameters": {
          "type": "object",
          "properties": {
            "location": { "type": "string" }
          }
        }
      }
    }
  ]
}

Étape 5 : Surveiller les Réponses

Apidog affiche :

Tester les Continuations

Pour tester le modèle de continuation avec previous_response_id :

  1. Envoyez le message initial, notez le response.id dans la réponse
  2. Envoyez la continuation avec seulement la nouvelle entrée :
{
  "previous_response_id": "resp_abc123",
  "input": [
    {
      "tool_call_id": "call_xyz789",
      "output": "{\"temperature\": 72, \"conditions\": \"sunny\"}"
    }
  ]
}
  1. Observez la latence réduite par rapport à la réexpédition du contexte complet

Tester l'API en Temps Réel

Pour l'API en temps réel, Apidog vous permet de :

Ceci est particulièrement utile pour déboguer pourquoi votre assistant vocal pourrait couper les utilisateurs ou ne pas détecter correctement la parole.

Variables d'Environnement

Stockez les clés API en toute sécurité en utilisant les variables d'environnement d'Apidog :

{{OPENAI_API_KEY}}

Cela vous permet de basculer entre les clés de développement et de production sans modifier les requêtes.

Cas d'Utilisation Réels

Explorons des scénarios pratiques où les modes WebSocket d'OpenAI excellent.

Cas d'Utilisation 1 : Agent de Codage Autonome

Scénario : Un assistant de codage qui analyse les bases de code, identifie les problèmes et apporte des améliorations de manière autonome.

Pourquoi l'API de Réponses WebSocket :

Modèle d'Implémentation :

// Tâche initiale
ws.send({ messages: [{ role: 'user', content: 'Audit security vulnerabilities' }], tools: [...] })

// Première réponse : le modèle appelle read_file
ws.on('message', (resp1) => {
  ws.send({ previous_response_id: resp1.id, input: [tool_result_1] })
})

// Deuxième réponse : le modèle appelle search_code
ws.on('message', (resp2) => {
  ws.send({ previous_response_id: resp2.id, input: [tool_result_2] })
})

// Continuer pour plus de 20 itérations...

Cas d'Utilisation 2 : Bot de Service Client Vocal

Scénario : Un bot de support téléphonique qui gère les demandes des clients avec un flux de conversation naturel.

Pourquoi l'API en Temps Réel WebSocket :

Modèle d'Implémentation :

// Diffuser l'audio du téléphone vers l'API
phoneSystem.on('audio', (chunk) => {
  ws.send({
    type: 'input_audio_buffer.append',
    audio: base64Encode(chunk)
  })
})

// Lire les réponses de l'IA immédiatement
ws.on('message', (event) => {
  if (event.type === 'response.audio.delta') {
    phoneSystem.playAudio(base64Decode(event.delta))
  }
})

Dépannage des Problèmes Courants

La Connexion ne S'établit Pas

Symptômes : La connexion WebSocket ne s'ouvre jamais, événement de fermeture immédiat.

Causes Courantes :

  1. Clé API invalide - Vérifiez votre en-tête Authorization
  2. En-tête bêta manquant - L'API de Réponses requiert OpenAI-Beta: responses-api=v1
  3. Restrictions réseau - Certains réseaux d'entreprise bloquent WebSocket
  4. URL incorrecte - Vérifiez wss:// (pas ws://) et le chemin du point d'accès

Solution :
Utilisez Apidog pour tester la connexion avec des messages d'erreur détaillés. L'inspecteur de requêtes montre exactement quels en-têtes sont envoyés, ce qui facilite la détection des clés API manquantes ou incorrectes.

Code de Débogage :

ws.on('error', (error) => {
  console.error('Connection error:', error);
});

ws.on('close', (code, reason) => {
  console.log(`Closed with code ${code}: ${reason}`);
  // Codes courants :
  // 1006 : Fermeture anormale (souvent des problèmes d'authentification)
  // 1008 : Violation de politique (en-têtes invalides)
});

Latence Élevée Malgré WebSocket

Symptômes : La connexion WebSocket fonctionne mais n'est pas plus rapide que HTTP.

Causes Courantes :

  1. Non-utilisation de previous_response_id - Vous renvoyez le contexte complet
  2. Démarrage à froid - La première requête sur une nouvelle connexion est plus lente
  3. Latence réseau - Distance géographique aux serveurs API
  4. Charges utiles volumineuses - Envoi de données inutiles dans les continuations

Solution :
Vérifiez que vous n'envoyez que de nouvelles entrées dans les continuations :

// FAUX - envoie le contexte complet à chaque fois
ws.send({
  messages: [...allPreviousMessages, newMessage],
  tools: [...]
})

// CORRECT - référence l'état mis en cache
ws.send({
  previous_response_id: lastResponse.id,
  input: [newMessage]
})

Fuites de Mémoire dans les Connexions Longue Durée

Symptômes : La mémoire de l'application augmente avec le temps avec une connexion persistante.

Causes Courantes :

  1. Écouteurs d'événements non supprimés - Accumulation d'écouteurs lors de la reconnexion
  2. Tampons audio non libérés - Conservation des références à l'audio lu
  3. Historique des messages croissant - Stockage de tous les messages reçus

Solution :

// Nettoyer les écouteurs d'événements lors de la reconnexion
function cleanupAndReconnect(ws) {
  ws.removeAllListeners();
  ws.close();

  const newWs = createConnection();
  return newWs;
}

// Libérer les tampons audio après la lecture
function playAndRelease(audioBuffer) {
  const audioContext = new AudioContext({ sampleRate: 24000 });
  audioContext.decodeAudioData(audioBuffer, (buffer) => {
    const source = audioContext.createBufferSource();
    source.buffer = buffer;
    source.connect(audioContext.destination);
    source.start();

    source.onended = () => {
      source.disconnect();
      // Le tampon sera collecté par le ramasse-miettes
    };
  });
}

// Limiter l'historique des messages
const messageHistory = [];
const MAX_HISTORY = 100;

ws.on('message', (data) => {
  messageHistory.push(data);
  if (messageHistory.length > MAX_HISTORY) {
    messageHistory.shift(); // Supprimer le plus ancien
  }
});

Conclusion

Les modes API WebSocket d'OpenAI ouvrent de nouvelles possibilités pour les applications d'IA. Le mode WebSocket de l'API de Réponses offre une exécution jusqu'à 40 % plus rapide pour les workflows agentiques avec de nombreux appels d'outils, ce qui le rend idéal pour les assistants de codage autonomes et les systèmes d'orchestration. L'API en Temps Réel offre une latence inférieure à 500 ms pour les applications vocales, permettant des conversations naturelles et interruptibles.

Le choix du bon mode dépend de votre cas d'utilisation :

La nature persistante et événementielle des connexions WebSocket nécessite des approches de test différentes de celles de HTTP. Testez les API WebSocket d'OpenAI avec le client WebSocket en temps réel d'Apidog — importez votre clé API, établissez des connexions, envoyez des événements et surveillez les réponses avec une journalisation détaillée. Essayez-le gratuitement pour valider vos intégrations avant le déploiement en production.

bouton

Pratiquez le Design-first d'API dans Apidog

Découvrez une manière plus simple de créer et utiliser des API