For the complete documentation index, see llms.txt. Markdown versions of documentation pages are available by appending .md to the page URL.
Hauptnavigation

WebSockets

Verbinde serverseitig verwaltete Audiostreams über WebSockets.

Wähle die API aus, die deine Anwendung verwendet. Jede API hat eigene Vorgaben für die Authentifizierung, das Erstellen von Sitzungen und den Austausch von Ereignissen.

Einen Server mit GPT-Live verbinden

Verwende eine primäre WebSocket-Verbindung, wenn dein Server Audio aufnimmt oder einen Audiostream für einen Client weiterleitet. Sie überträgt Audio und JSON-Ereignisse in beide Richtungen. Bewahre den Projekt-API-Schlüssel auf diesem vertrauenswürdigen Server auf. Beginne bei Browser- und mobilen Anwendungen mit WebRTC.

Diese Anleitung behandelt die primäre Audioverbindung. Über eine Sideband-Verbindung kann ein Server eine bestehende Live-Sitzung beobachten und steuern. Ein Responses WebSocket verbindet dein Backend mit der Responses API für logisches Denken und Werkzeuge. Keine dieser Verbindungen ersetzt die primäre Audioverbindung.

Authentifizieren und die Sitzung starten

  1. Stelle eine Verbindung zu wss://api.openai.com/v1/live/sessions ohne Abfrageparameter her. Authentifiziere dich mit Authorization: Bearer $OPENAI_API_KEY und füge die im Beispiel gezeigten Verbindungsheader hinzu.
  2. Sende session.start als erste Nachricht. Gib das Modell, die Gesprächsanweisungen, das Audioformat, die Stimme und die Delegationskonfiguration im Objekt session an.
  3. Warte auf session.started, bevor du Audio oder Anwendungsbefehle sendest. Das Ereignis enthält die aufgelöste Sitzungskonfiguration und die Sitzungs-ID.

Das folgende Beispiel verwendet Marin, PCM16-Audio mit 24 kHz und ein Responses-Backend mit Websuche. Halte die Gesprächsanweisungen kurz. Konfiguriere Backend-Anweisungen, Werkzeuge und Werkzeugberechtigungen wie unter Delegation und Werkzeuge beschrieben.

Audio mit einem SDK streamen

Installiere für Node.js openai und ws mit npm install openai ws und speichere das JavaScript-Beispiel als client.mjs. Installiere für Python unter macOS oder Linux openai[realtime] und speichere das Python-Beispiel als client.py. Setze OPENAI_API_KEY in der Serverumgebung. Diese Beispiele erfordern eine SDK-Version mit Live-Unterstützung. Das Beispiel liest rohe PCM16-Mono-Audiodaten mit 24 kHz von der Standardeingabe und schreibt zurückgegebene Audiodaten im selben Format auf die Standardausgabe. Verbinde diese Streams mit der Audioaufnahme und -wiedergabe deiner Anwendung. Protokolle und Transkript-Ereignisse werden auf die Standardfehlerausgabe geschrieben, damit sie den Audiostream nicht beeinträchtigen.

import OpenAI from "openai";
import { LiveWS } from "openai/resources/live/ws";

// stdin and stdout carry raw mono PCM16 audio at 24 kHz, not WAV files.
// Supply microphone bytes continuously and play stdout in the same format.
process.stdin.pause();
const ws = new LiveWS(new OpenAI());
let started = false;
let closing = false;
let finalized = false;
let pendingByte = Buffer.alloc(0);

let closeTimeout;

ws.socket.on("open", () => {
  ws.send({
    type: "session.start",
    event_id: "event_start",
    session: {
      model: "gpt-live-1",
      instructions:
        "Be concise. Delegate requests needing current information to the backend, which can search the web.",
      audio: {
        format: { type: "audio/pcm", rate: 24000 },
        output: { voice: "marin" },
      },
      delegation: {
        type: "responses",
        responses: {
          model: "gpt-5.6-luna",
          tools: [{ type: "web_search" }],
          tool_choice: "auto",
        },
      },
    },
  });
});

process.stdin.on("data", (chunk) => {
  if (!started || closing || ws.socket.readyState !== 1) return;
  const bytes = Buffer.concat([pendingByte, chunk]);
  const completeLength = bytes.length - (bytes.length % 2);
  pendingByte = bytes.subarray(completeLength);
  if (completeLength) {
    ws.send({
      type: "session.input_audio.append",
      audio: bytes.subarray(0, completeLength).toString("base64"),
    });
  }
});

// Register the final-event handler before any close command can be sent.
ws.on("event", (event) => {
  if (event.type === "session.started") {
    started = true;
    console.error("Session ready", event.session.id);
    process.stdin.resume();
  } else if (event.type === "session.output_audio.delta") {
    process.stdout.write(Buffer.from(event.delta, "base64"));
  } else if (event.type === "session.closed") {
    finalized = true;
    clearTimeout(closeTimeout);
    process.stdin.pause();
    console.error("Final session usage", event.usage);
    ws.close();
  } else {
    // Includes transcript deltas and nested response.event usage.
    console.error(JSON.stringify(event));
  }
});

process.on("SIGINT", () => {
  if (closing) return;
  if (!started || ws.socket.readyState !== 1) {
    ws.socket.platformSocket.terminate();
    return;
  }
  closing = true;
  process.stdin.pause();
  ws.send({ type: "session.close" });
  closeTimeout = setTimeout(() => {
    console.error("Incomplete finalization: session.closed was not received");
    process.exitCode = 1;
    ws.socket.platformSocket.terminate();
  }, 15_000);
});
ws.on("error", (error) => {
  console.error(error.message);
  process.exitCode = 1;
});
ws.socket.on("close", () => {
  clearTimeout(closeTimeout);
  process.stdin.pause();
  if (!finalized) {
    console.error("Connection closed without final session usage");
    process.exitCode = 1;
  }
});

Führe node client.mjs oder python client.py mit angeschlossener Audioquelle und Wiedergabe aus. Sobald Session ready erscheint, liefere einen kontinuierlichen Mikrofonstream im Tempo seiner Aufnahme-Abtastrate. Eine ganze Datei auf einmal über eine Pipe einzuspeisen, simuliert kein Live-Mikrofon. Ein EOF der Audioquelle beendet das Gespräch nicht. Sende SIGINT an den Prozess, um ein geordnetes Beenden anzufordern.

Das Beispiel verbindet die Audiostreams. Deine Anwendung übernimmt Aufnahme, Pufferung, Wiedergabe und bei Bedarf Resampling. Teste diese Komponenten mit deinen Geräten und deinem Netzwerk, bevor du das Modellverhalten bewertest.

Audioformat auswählen

Lege session.audio.format beim Start fest. Dasselbe Format gilt für Ein- und Ausgabe und lässt sich während der Sitzung nicht ändern.

  • {"type":"audio/pcm","rate":24000}: vorzeichenbehaftetes 16-Bit-PCM in Little-Endian-Bytefolge, mono, mit 24 kHz; die Standardeinstellung.
  • {"type":"audio/pcm","rate":16000}: vorzeichenbehaftetes 16-Bit-PCM in Little-Endian-Bytefolge, mono, mit 16 kHz.
  • {"type":"audio/pcmu","rate":8000}: G.711 μ-law mit 8 kHz, ein Byte pro Sample.
  • {"type":"audio/pcma","rate":8000}: G.711 A-law mit 8 kHz, ein Byte pro Sample.

Kodiere die Rohbytes ohne WAV- oder anderen Container-Header als Base64. PCM-Blöcke müssen vollständige 16-Bit-Samples enthalten. Ihre Länge in Bytes muss daher gerade sein. Das Beispiel übernimmt ein übrig gebliebenes Byte in den nächsten Eingabeblock. Ansonsten sind die Blockgrenzen beliebig: Halte den Stream kontinuierlich und in der richtigen Reihenfolge.

Führe ein Resampling der Audiodaten durch, wenn ihre Abtastrate von der konfigurierten Rate abweicht. Eine Änderung der Formateinstellung konvertiert deine Eingabebytes nicht. Um das Beispiel für G.711 anzupassen, leite die Codec-Bytes jedes Blocks ohne die PCM-spezifische Logik zur Ausrichtung auf Zwei-Byte-Grenzen weiter und konfiguriere die Wiedergabe für denselben Codec. Ein passender G.711-Stream kann ohne Konvertierung in PCM durchgereicht werden. Wie du einen Telefonanruf verbindest, erfährst du unter Telefonie-Integrationen.

Ereignisse senden und empfangen

Sende jedes Ereignis als JSON-Textnachricht. Audio wird innerhalb dieser Nachrichten als Base64 übertragen.

  • Audio senden: Sende session.input_audio.append mit rohen, Base64-kodierten Bytes in audio. Das Anhängen von Audiodaten wird nicht bestätigt.
  • Audio empfangen: Dekodiere delta aus jedem Ereignis vom Typ session.output_audio.delta und stelle die Audiodaten in die Wiedergabewarteschlange, damit sie in der richtigen Reihenfolge und im konfigurierten Format abgespielt werden.
  • Transkripte empfangen: Hänge den Text in delta aus session.input_transcript.delta und session.output_transcript.delta an das jeweilige Transkript an.
  • Backend-Ereignisse empfangen: Verarbeite bei der Delegation an Responses das verschachtelte event in jeder response.event-Hülle.
  • Fehler behandeln: Behandle abgelehnte Befehle und Sitzungsfehler aus Ereignissen vom Typ error. Verwende error.client_event_id, sofern vorhanden, um den Befehl zu identifizieren.

Ereignisse für die Audioausgabe enthalten keine Zeitangaben, und GPT-Live sendet kein Ereignis, das den Abschluss der Audioausgabe meldet. Verfolge deine Wiedergabewarteschlange, um festzustellen, welche empfangenen Audiodaten bereits abgespielt wurden. Zeitstempel in Transkripten beschreiben Intervalle auf der Sitzungszeitachse. Sie kennzeichnen nicht das Ende der Audiowiedergabe. Auch der Abschluss einer Backend-Antwort bedeutet nicht, dass der Assistent zu Ende gesprochen hat.

GPT-Live steuert während des Audiostreamings, wann es zuhört und spricht. Es verwendet nicht den Realtime-Zyklus für Gesprächsbeiträge mit Eingabepuffer-Commit und response.create. In Live startet response.create delegierte Backend-Aufgaben oder setzt sie fort. Diesen Ablauf findest du unter Delegation und Werkzeuge.

Eine laufende Sitzung konfigurieren

Das Live-Modell, die anfänglichen Gesprächsanweisungen, das Audioformat, die Stimme und der Delegationsmodus werden beim Start festgelegt und sind danach unveränderlich. Verwende session.update für unterstützte Einstellungen innerhalb des bestehenden Delegationsmodus. Nicht angegebene Einstellungen behalten ihre aktuellen Werte. Eine erfolgreiche Aktualisierung gibt session.updated mit der aufgelösten Sitzungskonfiguration zurück.

Verwende session.instructions.append, um Gesprächsanweisungen hinzuzufügen, und session.input_audio.mute oder session.input_audio.unmute, um eingehendes Audio zu steuern. Das Stummschalten der Eingabe bricht weder Backend-Aufgaben ab noch stoppt es die generierte Sprache. Informationen zu Kontextaktualisierungen, Transkripten, Eingabesteuerung und Nutzung findest du unter Sitzungen verwalten.

Die Sitzung schließen

Sende session.close, wenn das Gespräch endet. Registriere zuerst den Listener für session.closed, empfange weiter, bis dieses Ereignis eintrifft, und gib dann die Verbindung frei. Das Beispiel wartet bis zu 15 Sekunden und meldet einen unvollständigen Abschluss, wenn das abschließende Ereignis ausbleibt.

Bewahre die endgültigen Sprachnutzungsdaten aus session.closed und die bereits empfangenen Ereignisse zur Backend-Nutzung auf. Aktualisierungen der Sprachdauer sind kumulative Momentaufnahmen. Addiere sie nicht. Bei einem Übertragungsfehler oder einer Zeitüberschreitung vor session.closed bleibt die endgültige Nutzung unbestätigt. Den vollständigen Lebenszyklus findest du unter Sitzungen verwalten.