AGTCloud API Docs
GuidesRéférence APIIntégrations et ressourcesMises à jour et aide
Interaction en temps réel

GPT-Live Voix en temps réel

Effectuez des interactions vocales full-duplex et gérez les événements de session via GPT-Live WebSocket.

GPT-Live fournit des interactions vocales full-duplex sur une connexion WebSocket persistante. Une même session permet d’envoyer de l’audio d’entrée, de recevoir la voix et les transcriptions, de mettre à jour sa configuration et de conserver le contexte sur plusieurs tours. Le modèle actuellement référencé est gpt-live-1 ; sa disponibilité réelle dépend du compte actuel et du catalogue de modèles.

WSS
wss://api.agtcloud.cn/v1/live/sessions

Authentification et connexion

Les applications serveur utilisent une clé API Bearer dans les Headers du handshake WebSocket. Le modèle n’est pas placé dans les paramètres de requête de l’URL : il est configuré dans le premier événement session.start après connexion.

ÉlémentValeur
Adresse de connexionwss://api.agtcloud.cn/v1/live/sessions
AuthorizationBearer your-api-key
Emplacement du modèlesession.start.session.model
Audio d’entréeBlocs audio PCM bruts encodés en Base64

Conservez les clés API de longue durée uniquement sur un serveur de confiance. Cette page couvre uniquement cette route WebSocket, pas WebRTC, SIP, sideband, les forks de session ni le téléchargement d’enregistrements.

Déroulement de la session

  1. Établissez une connexion WebSocket avec une clé API Bearer.
  2. Envoyez session.start pour configurer le modèle, les instructions, l’audio et la délégation.
  3. Commencez à envoyer de l’audio ou des commandes applicatives après réception de session.started.
  4. Traitez continuellement les transcriptions d’entrée et de sortie, l’audio de sortie et les événements d’utilisation.
  5. Envoyez session.close après avoir arrêté la production audio.
  6. Continuez à recevoir les événements et finalisez avec l’utilisation finale de session.closed.

La fin d’un tour de parole ne signifie pas la fin de la session. Conservez la même connexion pour une conversation à plusieurs tours et n’envoyez session.close que lorsque l’application est prête à terminer toute la session.

Paramètres de démarrage

ChampTypeDescription
typestringToujours session.start dans la première trame
event_idstringIdentifiant d’événement client facultatif pour associer les erreurs
session.modelstringObligatoire, ID du modèle GPT-Live
session.instructionsstringInstructions facultatives de l’assistant vocal
session.audio.formatobjectFormat audio, par exemple audio/pcm, 24 kHz
session.audio.output.voicestringVoix de sortie, par exemple marin ; les valeurs disponibles dépendent du modèle
session.delegationobjectMode de délégation, client ou responses

Après démarrage, utilisez session.update pour modifier les paramètres autorisés, comme les instructions, puis attendez la confirmation session.updated. N’envoyez pas de nouveau session.start sur la même connexion et ne changez pas le modèle vocal de premier niveau via un événement de mise à jour.

Préparation audio et exemples d’appel

L’exemple utilise de l’audio PCM signed 16-bit little-endian, 24 kHz, mono, sans en-tête WAV. Chaque intervalle de 100 ms représente 4800 octets ; encodez chaque bloc audio en Base64 avant l’envoi.

# Préparer l’audio d’entrée
ffmpeg -i input.wav -f s16le -acodec pcm_s16le -ac 1 -ar 24000 audio.pcm

# Lire l’audio de sortie enregistré
ffplay -f s16le -ar 24000 -ac 1 reply.pcm

L’exemple Node.js nécessite ws ; l’exemple Python vérifie uniquement le démarrage et la fermeture de la session, sans envoyer d’audio.

npm install ws
python -m pip install websocket-client
WSSExemples de session GPT-Live
import fs from 'node:fs';
import WebSocket from 'ws';

const key = process.env.API_KEY;
const file = process.argv[2];
if (!key || !file) throw new Error('API_KEY et le chemin du fichier PCM sont requis');

const pcm = fs.readFileSync(file);
if (!pcm.length || pcm.length % 2) {
  throw new Error('Le PCM ne doit pas être vide et doit être aligné sur des échantillons de 16 bits');
}

const ws = new WebSocket('wss://api.agtcloud.cn/v1/live/sessions', {
  headers: { Authorization: 'Bearer ' + key },
  handshakeTimeout: 10000,
});
const audioOut = fs.createWriteStream('reply.pcm');
let started = false;
let closing = false;
let finalized = false;
let sender;
let drain;
let offset = 0;
let inputFinishedAt = 0;
let lastOutputAt = 0;

function send(event) {
  ws.send(JSON.stringify(event));
}

function closeSession(reason) {
  if (closing) return;
  closing = true;
  clearInterval(sender);
  console.error('Demande de fermeture :', reason);
  if (started && ws.readyState === WebSocket.OPEN) {
    send({ type: 'session.close' });
    drain = setTimeout(() => ws.terminate(), 15000);
  } else {
    ws.terminate();
  }
}

const limit = setTimeout(() => closeSession('Limite de 60 secondes de l’exemple'), 60000);

ws.on('open', () => send({
  type: 'session.start',
  event_id: 'start_001',
  session: {
    model: 'gpt-live-1',
    instructions: 'Répondez brièvement en chinois et attendez que l’utilisateur parle en premier.',
    audio: {
      format: { type: 'audio/pcm', rate: 24000 },
      output: { voice: 'marin' },
    },
    delegation: { type: 'client' },
  },
}));

ws.on('message', (raw) => {
  let event;
  try {
    event = JSON.parse(raw.toString());
  } catch {
    closeSession('JSON non valide');
    return;
  }

  if (event.type !== 'session.output_audio.delta') {
    console.log(raw.toString());
  }
  if (event.type === 'session.started' && !started) {
    started = true;
    sender = setInterval(() => {
      if (closing || ws.readyState !== WebSocket.OPEN) return;
      if (offset >= pcm.length) {
        inputFinishedAt ||= Date.now();
        if (
          lastOutputAt &&
          Date.now() - Math.max(lastOutputAt, inputFinishedAt) >= 3000
        ) {
          closeSession('Sortie terminée');
          return;
        }
        send({
          type: 'session.input_audio.append',
          audio: Buffer.alloc(4800).toString('base64'),
        });
        return;
      }
      const chunk = pcm.subarray(offset, offset + 4800);
      offset += chunk.length;
      send({
        type: 'session.input_audio.append',
        audio: chunk.toString('base64'),
      });
    }, 100);
  }
  if (event.type === 'session.output_audio.delta') {
    lastOutputAt = Date.now();
    audioOut.write(Buffer.from(event.delta, 'base64'));
  }
  if (event.type === 'session.output_transcript.delta') {
    lastOutputAt = Date.now();
  }
  if (event.type === 'session.closed') {
    finalized = true;
    ws.close(1000);
  }
  if (event.type === 'error') closeSession('Erreur de service');
});

ws.on('error', (error) => {
  console.error(error.message);
  closeSession('Erreur de connexion');
});

ws.on('close', (code, reason) => {
  clearTimeout(limit);
  clearTimeout(drain);
  clearInterval(sender);
  audioOut.end();
  console.error({ code, reason: reason.toString(), finalized });
  if (!finalized || code !== 1000) process.exitCode = 1;
});

process.on('SIGINT', () => closeSession('Arrêt demandé par l’utilisateur'));

Référence des événements

Cette interface envoie l’audio Base64 avec session.input_audio.append. Elle n’utilise ni les trames audio binaires et endStream de Muse, ni les événements input_audio_buffer.* d’OpenAI Realtime.

Événements du client · Session

session.start

Démarre une session GPT-Live et transmet la configuration du modèle, des instructions, de l’audio et de la délégation.

ChampTypeObligatoireDescriptionExemple
typestringOuiValeur fixe : session.start.session.start
event_idstringNonIdentifiant d’événement client.start_001
session.modelstringOuiID de modèle GPT-Live.gpt-live-1
session.instructionsstringNonInstructions de conversation de l’assistant vocal.Répondez brièvement en chinois.
session.audio.format.typestringNonType de format audio.audio/pcm
session.audio.format.rateintegerNonFréquence d’échantillonnage audio.24000
session.audio.output.voicestringNonVoix de sortie.marin
session.delegation.typestringOuiMode de délégation.client
Exemple JSON
{
  "type": "session.start",
  "event_id": "start_001",
  "session": {
    "model": "gpt-live-1",
    "instructions": "Répondez brièvement en chinois.",
    "audio": {
      "format": {
        "type": "audio/pcm",
        "rate": 24000
      },
      "output": {
        "voice": "marin"
      }
    },
    "delegation": {
      "type": "client"
    }
  }
}

Utilisation et facturation

session.usage.updated renvoie l’utilisation cumulée de la session actuelle, pas un ajout propre à un tour. Le client ne doit pas additionner les valeurs des différentes étapes ; lors d’une fermeture normale, session.closed.usage.seconds représente la durée finale de la session.

Les frais peuvent inclure la durée de session vocale, l’utilisation des modèles en arrière-plan et les appels d’outils. Consultez le catalogue de modèles pour les tarifs et la disponibilité du modèle actuel.

Modes de délégation

  • client : l’application traite elle-même les tâches à déléguer ; ce mode convient pour vérifier d’abord la session vocale de base.
  • responses : le serveur exécute le modèle Responses et les outils configurés. Le modèle cible, les outils et les autorisations doivent être disponibles sur le site actuel.

Avec responses, les modèles et outils des tâches en arrière-plan peuvent générer des frais séparés. Ne considérez pas MODEL_ID dans l’exemple comme un modèle garanti disponible.

Gestion des erreurs

SymptômeVérification et traitement
Handshake renvoyant 401Vérifiez la clé API Bearer, les autorisations du modèle et l’adresse du site actuel
Route renvoyant 404Vérifiez que le chemin final est /v1/live/sessions, sans duplication de /v1
Première trame incorrecte ou délai de démarrage dépasséEnvoyez d’abord session.start après connexion et attendez session.started avant l’audio
Aucun son ou son déforméVérifiez la profondeur PCM, l’ordre des octets, la fréquence, les canaux et l’en-tête WAV
session.closed non reçuConservez la dernière utilisation cumulée, les erreurs et le motif de fermeture ; ne renvoyez pas automatiquement tout l’audio
Délégation en arrière-plan refuséeVérifiez le modèle Responses, les outils, les autorisations et la prise en charge sur le site actuel

Références