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

GPT-Live-Sitzungen verwalten

Konfiguriere Sitzungen, halte den Kontext aktuell und verwalte den Gesprächslebenszyklus.

Nachdem du eine Verbindung zu GPT-Live hergestellt hast, kannst du mit Sitzungsereignissen den Kontext aktualisieren, Transkripte anzeigen und den Lebenszyklus der Verbindung verwalten. Das Modell kann gleichzeitig zuhören und sprechen. Verwalte deshalb empfangene Ereignisse, Audiowiedergabe und den Status von Backend-Aufgaben in deiner Anwendung getrennt voneinander.

Diese Anleitung setzt voraus, dass deine Verbindung das Ereignis session.started ausgegeben hat. Unter Verbindungen findest du Informationen zum Verbindungsaufbau und Audio-Streaming, unter Delegation und Werkzeuge Informationen zur Arbeit im Backend.

Eine Sitzung konfigurieren

Wähle beim Erstellen der Sitzung das Modell, die Stimme und den Delegationsmodus aus. Gib dem Modell Anweisungen für das Gespräch und füge den relevanten Verlauf hinzu. GPT-Live verwaltet den Kontext automatisch, während das Gespräch länger wird.

Konfigurationsfelder

EinstellungBeim Start konfigurierenWährend der Sitzung ändern
ModellLege den erforderlichen Parameter model fest.Starte eine neue Sitzung, um das Modell zu ändern.
AnweisungenLege mit instructions das Verhalten im Gespräch fest. Dafür stehen bis zu 16.384 Token zur Verfügung.Füge mit session.instructions.append Anweisungen hinzu.
VerlaufGib in input relevante frühere Textnachrichten an. Der Standardwert ist [].Füge Kontext hinzu, ohne den beim Start übergebenen Verlauf zu ersetzen.
StimmeSetze audio.output.voice auf eine unterstützte Stimme oder eine autorisierte benutzerdefinierte Stimme. Der Standardwert ist marin.Starte eine neue Sitzung, um die Stimme zu ändern.
DelegationSetze delegation.type auf client oder responses. Wenn die Delegation nicht angegeben oder auf null gesetzt ist, wird der Client-Modus gewählt.Aktualisiere die Responses-Einstellungen innerhalb des bestehenden Modus.
SpeicherungSetze store auf true, damit die Sitzung geforkt werden kann. Der Standardwert ist false.Beim Start festlegen.

Stimmenoptionen

Wähle beim Erstellen der Sitzung eine Stimme aus. Setze audio.output.voice auf den API-Namen, zum Beispiel "quartz". GPT-Live bietet diese zusätzlichen Stimmenoptionen:

StimmeAPI-NameSpracheRegionale PrägungStimmwirkungHerkunft
QuartzquartzEnglischAustralischWeiblichGeneriert
RipplerippleEnglischAustralischMännlichNatürlich
VespervesperEnglischBritischMännlichNatürlich
WillowwillowEnglischIrischWeiblichNatürlich
StonestoneEnglischIrischMännlichNatürlich
GleamgleamEnglischNordamerikanischWeiblichNatürlich
MeridianmeridianEnglischNordamerikanischMännlichNatürlich
BossabossaPortugiesischBrasilianischWeiblichNatürlich
TempotempoPortugiesischBrasilianischMännlichNatürlich
BeaconbeaconEnglischPhilippinischMännlichGeneriert
DeltadeltaEnglischUS-SüdstaatenWeiblichGeneriert
CindercinderEnglischUS-SüdstaatenMännlichGeneriert

Die regionale Prägung beschreibt den Sprechstil einer Stimme und garantiert keine akzentgetreue Wiedergabe. Informationen zu einer genehmigten Stimme, die aus deiner eigenen Aufnahme erstellt wird, findest du unter Benutzerdefinierte Stimmen.

Wähle bei WebSocket das gemeinsame audio.format beim Start aus. Es kann während der Sitzung nicht geändert werden. Lasse dieses Feld bei WebRTC weg, da die Verbindung ihr Audioformat aushandelt. Einzelheiten zu Formaten und Streaming findest du unter WebSocket-Audioformate.

Eine laufende Sitzung aktualisieren

Verwende session.update, um session.delegation.responses in einer Sitzung zu ändern, die bereits die Responses-Delegierung nutzt. Sende nur die Einstellungen, die du ändern möchtest. Ausgelassene Einstellungen behalten ihre Werte. Informationen zu den Einstellungen und zum Aktualisierungsablauf findest du unter Responses-Delegierung konfigurieren.

Du kannst den Delegierungsmodus nach dem Start nicht ändern. Insbesondere wählt das Setzen von delegation auf null den Client-Modus aus; es setzt keine Responses-Sitzung zurück. Die Startfelder model, instructions, input, audio und store werden bei Aktualisierungen nicht akzeptiert. Unbekannte Konfigurationsfelder werden abgelehnt.

Eine erfolgreiche Aktualisierung löst session.updated mit der vollständigen aufgelösten Sitzungskonfiguration aus. Wenn du eine event_id angibst, gibt die Bestätigung sie als client_event_id zurück. Achte neben Bestätigungen auch auf abgelehnte Befehle. Die Annahme bestätigt die Konfigurationsaktualisierung. Sie belegt weder, dass eine Backend-Aufgabe ausgeführt wurde, noch, dass das Modell gesprochen hat.

Verlauf und Kontext bereitstellen

Nutze den beim Start übergebenen Verlauf, um ein Thema wieder aufzugreifen, und ergänze im weiteren Gespräch relevante Kontextinformationen. Halte vertrauenswürdige Anweisungen der Anwendung getrennt von Nachrichten der Nutzenden und sachlichen Ergebnissen.

Eine Sitzung mit einem bisherigen Gespräch initialisieren

Füge beim Erstellen der Sitzung frühere Textnachrichten in session.input ein. Ergänze beispielsweise dieses input-Feld in deiner Konfiguration zur Sitzungserstellung:

export const session = {
  model: "gpt-live-1",
  input: [
    {
      type: "message",
      role: "user",
      content: [
        {
          type: "input_text",
          text: "I need help with my recent order.",
        },
      ],
    },
    {
      type: "message",
      role: "assistant",
      content: [
        {
          type: "output_text",
          text: "What is the order number?",
        },
      ],
    },
  ],
};

Die Liste akzeptiert bis zu 128 Nachrichten mit insgesamt höchstens 8.192 Tokens. Unterstützt werden die Rollen developer, user und assistant, jeweils mit einem Textteil. Nachrichten mit Entwickler- oder Nutzerrolle verwenden input_text; Assistentennachrichten verwenden text oder output_text. Hinterlege vertrauenswürdige Anweisungen der Anwendung in instructions oder in einer Nachricht mit Entwicklerrolle. Die Liste akzeptiert die Rolle system nicht.

Wähle den Verlauf aus, der für die nächste Interaktion benötigt wird. input ist ein Feld für den Sitzungsstart und bietet keine Möglichkeit, den Verlauf während einer laufenden Sitzung zu ersetzen. Es akzeptiert außerdem nicht alle Arten von Backend-Eingabeelementen, die bei der Responses-Delegierung verwendet werden.

Verstehen, wann Kontext das Modell erreicht

Der gesamte Inhalt von input, den du beim Erstellen der Sitzung übergibst, steht dem Modell beim Sitzungsstart zur Verfügung. Hinterlege in diesem Feld den Kontext, den das Modell von Anfang an benötigt.

Während einer laufenden Sitzung führen die Ereignisse session.instructions.append, session.thinking.append und session.commentary.append dem Modell nach und nach Inhalte zu. Ihre Bestätigungen erfolgen erst, wenn die Frame-Verarbeitung den geschätzten Endzeitpunkt der Kontextzuführung erreicht hat. Die zurückgegebenen Werte start_ms und end_ms beschreiben einen geschätzten Bereich auf der Zeitleiste der Sitzung, nicht den Abschluss der Sprachausgabe oder Wiedergabe. Sie belegen nicht, dass das Modell die gesamte Aktualisierung verarbeitet hat. Gehe nicht davon aus, dass seine nächste Sprachausgabe die gesamte Aktualisierung berücksichtigt.

Wenn die Frame-Verarbeitung zum Stillstand kommt, kann eine Bestätigung ausstehen bleiben. Beim Schließen der Sitzung wird für ausstehende Ergänzungen ein Fehler gemeldet. Ordne jede Bestätigung über client_event_id der ausgehenden event_id zu und behandle auch während des Wartens weiterhin Fehler.

Während des Gesprächs Kontext hinzufügen

Wähle das Ereignis danach aus, wie das Modell die Aktualisierung nutzen soll:

  • session.instructions.append: Füge vertrauenswürdige Anweisungen der Anwendung hinzu, die Verhalten und Sprachausgabe beeinflussen.
  • session.thinking.append: Füge sachlichen Kontext hinzu, ohne das Modell aufzufordern, ihn sofort auszusprechen.
  • session.commentary.append: Stelle Informationen bereit, die das Modell laut aussprechen soll. Es kann sie dabei umformulieren.

Jedes Ereignis akzeptiert content als einfache Zeichenfolge mit bis zu 500 Tokens und erfordert eine delegation_id. Verwende null für Kontext, der für die gesamte Sitzung gilt. Sende beispielsweise Folgendes, nachdem deine Anwendung die Zustimmung der nutzenden Person überprüft und die Abfrage gestartet hat:

export function sendUpdate(connection) {
  connection.send({
    type: "session.thinking.append",
    event_id: "context_1",
    delegation_id: null,
    content:
      "The user has already accepted the terms. The account lookup is still running.",
  });
}

Warte auf session.thinking.appended mit client_event_id: "context_1" oder behandle einen Fehler. Die Bestätigung besagt, dass der Kontext angenommen wurde. Sie bestätigt weder eine Sprachausgabe noch eine Wiedergabe oder den Abschluss einer externen Aktion.

Nicht unmittelbar ausgesprochener Kontext kann spätere Sprachausgaben beeinflussen und bietet keinen Vertraulichkeitsschutz. Übermittle mit keinem der drei Ereignisse Zugangsdaten, Geheimnisse oder Texte, die das Modell niemals offenlegen darf. Verwende das Anweisungsereignis für Verhaltensvorgaben der Anwendung, nicht für nicht vertrauenswürdige Tool-Ausgaben. Setze Berechtigungen und erforderliche Bestätigungen in deiner Anwendung durch.

Unter UI-Kontext teilen erfährst du, wie du mit knappen Aktualisierungen zur Seitennavigation, zu ausgewählten Elementen und anderen UI-Änderungen GPT-Live dabei hilfst, zu verstehen, worauf sich die nutzende Person bezieht.

Verwende für Ergebnisse, die zu einer Backend-Aufgabe gehören, eine bekannte Client-Delegierungs-ID und befolge die Anleitung unter Die passende Art von Aktualisierung senden. Diese ID ist weder eine Antwort-ID aus Responses noch eine Tool-Aufruf-ID.

Verwende Anweisungen, um das Gespräch zu steuern, nachdem eine Prüfung der Anwendung anschlägt. Dein Server kann Ereignisse überwachen und diese Korrekturen über einen mit der bestehenden Sitzung verbundenen Sideband-WebSocket oder über ihren primären WebSocket senden. Informationen zu parallelen Prüfungen, zum Blockieren von Aktionen und zur Wiedergabesteuerung findest du unter Schutzmechanismen für Gespräche anwenden.

Die Gesprächsoberfläche entwickeln

Zeige Transkripte und Mikrofonstatus unabhängig vom Fortschritt im Backend an. Der Empfang von Assistententext sagt nichts darüber aus, wie viel Audio die nutzende Person bereits gehört hat.

Transkript-Deltas

Achte auf session.input_transcript.delta für Sprachbeiträge der nutzenden Person und auf session.output_transcript.delta für Sprachbeiträge des Assistenten. Jedes Ereignis enthält ein Textfragment und dessen Intervall auf der Sitzungszeitachse:

{
  "type": "session.input_transcript.delta",
  "event_id": "event_transcript_1",
  "delta": "What is",
  "start_ms": 1000,
  "end_ms": 1200
}

Füge die Fragmente für jede sprechende Seite der Reihe nach an und behalte start_ms und end_ms bei. Diese Werte geben Millisekunden auf der Sitzungszeitachse an. Die Intervalle schließen den Anfang ein und das Ende aus. Es handelt sich weder um Zeitstempel der tatsächlichen Uhrzeit noch um Ankunftszeiten von Paketen oder exakte zeitliche Zuordnungen einzelner Wörter.

Nur Intervalle mit Transkripttext erzeugen Ereignisse, und die Übertragung über das Netzwerk kann ungleichmäßig erfolgen. Schließe aus einem fehlenden Ereignis nicht auf Stille und behandle ein Fragment nicht als vollständigen Gesprächsbeitrag der nutzenden Person. Transkript-Deltas haben weder eine Element-ID noch ein Ereignis, das den Abschluss eines Gesprächsbeitrags verbindlich bestätigt.

Die Verarbeitung von Transkriptfragmenten ist optional. Du kannst damit deine UI aktualisieren, Prüfungen ausführen oder frühzeitig Aufgaben starten, während das Gespräch weiterläuft. Für einfache Prüfungen kommt ein kleines Modell wie gpt-5.6-luna mit geringem Reasoning-Aufwand infrage. Beispiele und Hinweise zur Verbindung findest du unter Auf Transkriptfragmente reagieren.

Prüfe für Schutzmechanismen im Gespräch den bis dahin empfangenen Text der nutzenden Person und des Assistenten, sobald neue Fragmente eintreffen. Die Transkriptübertragung bietet keinen Vorlaufpuffer, mit dem sich Sprache vor der Wiedergabe genehmigen lässt. Siehe Wiedergabe bei Bedarf steuern.

Wenn deine Oberfläche Text zu Gesprächsbeiträgen gruppiert, muss sich diese Gruppierung nachträglich ändern lassen. Bewahre die ursprünglichen Fragmente auf, lasse zeitliche Überschneidungen zwischen der nutzenden Person und dem Assistenten zu und stimme etwaige Zeitlimits für Sprechpausen anhand aufgezeichneter Gespräche ab. Eine kurze Bestätigung der anderen Seite kann zu einem laufenden Austausch gehören. Das Gruppieren von Fragmenten allein darf weder Tools ausführen noch Aufgaben im Backend abbrechen.

Halte die Zeitangaben des Transkripts von der Audiowiedergabe getrennt. Bei WebSocket enthalten session.output_audio.delta-Ereignisse keine Zeitangaben, und es gibt kein Ereignis für den Abschluss der Audioausgabe. WebRTC überträgt Audio über seine Medienspur. Hinweise zur Audioverarbeitung findest du unter Verbindungen.

Untertitel anzeigen

Erstelle Untertitelzeilen, die erweitert werden können, während beide Seiten sprechen:

  1. Bewahre den Text unverändert auf. Speichere für jede sprechende Seite die ursprünglichen Werte von delta, start_ms und end_ms. Füge den Text exakt so zusammen, wie du ihn empfängst, einschließlich Leerzeichen und wiederholter Wörter. Entferne keine Leerzeichen an den Rändern der Fragmente und füge keine Leerzeichen zwischen ihnen ein.
  2. Aktualisiere beide Seiten unabhängig voneinander. Ermögliche es, die Zeilen der nutzenden Person und des Assistenten zu erweitern, während beide gleichzeitig sprechen. Lass früheren Assistententext nach einer Unterbrechung sichtbar und beginne eine neue Zeile, wenn der Assistent weiterspricht.
  3. Halte die Zeilen stabil. Vergib in deiner Anwendung IDs für die Anzeige und behalte die Reihenfolge der Zeilen bei, während Text hinzukommt. Leite die Identität einer Zeile nicht aus veränderlichem Text oder Endzeitstempeln ab und verschiebe eine Zeile nicht bei jedem neuen Fragment ans Ende.
  4. Überprüfe die Gruppierung bei verspäteten Fragmenten. Gruppiere zeitlich nahe beieinanderliegende Fragmente derselben sprechenden Seite anhand der Transkriptzeitstempel. Ermögliche es, mit verspätet eintreffendem Text frühere Zeilen zu aktualisieren und Fragmente neu zuzuordnen. Bewahre dabei die ursprünglichen Fragmente auf. Diese Anzeigegruppen sind keine inhaltlich vollständigen Gesprächsbeiträge. Schwellenwerte für Sprechpausen legst du für deine Anwendung fest und musst sie testen.
  5. Überlasse den Lesenden die Kontrolle über das Scrollen. Scrolle bei neuem Text automatisch weiter, solange sich die lesende Person am unteren Ende befindet. Pausiere das automatische Scrollen, wenn sie nach oben scrollt, und biete eine Möglichkeit, zu den neuesten Untertiteln zurückzukehren.
  6. Zeige den Fortschritt von Tools in einem Statusbereich an. Nutze die Transkriptereignisse des Assistenten für Untertitel seiner Sprachbeiträge. Zeige Tool-Aktivitäten und Backend-Ergebnisse außerhalb der Untertitel an. Der Empfang eines Ergebnisses bedeutet nicht, dass der Assistent es bereits ausgesprochen hat.

Teste die Anzeige bei gleichzeitigem Sprechen, kurzen Bestätigungen, Unterbrechungen, langen Pausen und Übersetzungen, bei denen der Text beider Seiten unterschiedlich schnell eintrifft.

Mikrofoneingabe steuern

Sende session.input_audio.mute, um die Eingabe stummzuschalten, ohne die Sitzung zu beenden:

export function sendUpdate(connection) {
  connection.send({
    type: "session.input_audio.mute",
    event_id: "mute_1",
  });
}

Warte auf session.input_audio.muted mit client_event_id: "mute_1", bevor du den Befehl als angenommen betrachtest. Um die Eingabe fortzusetzen, sende session.input_audio.unmute und warte auf session.input_audio.unmuted. Behandle Fehler bei beiden Befehlen.

Das Stummschalten der Eingabe stoppt weder die Inferenz noch delegierte Aufgaben oder die generierte Sprachausgabe. Steuere die Mikrofonaufnahme und die Audiowiedergabe in deiner Anwendung separat, wenn du diese Steuerungsmöglichkeiten benötigst.

Anrufende begrüßen, bevor sie sprechen

So forderst du nach session.started eine Begrüßung an:

  1. Sende ein einzelnes neues session.instructions.append-Ereignis mit delegation_id: null. Gib die Begrüßung und ihre Sprache an sowie die ausdrückliche Anweisung, sofort zu begrüßen, ohne auf die anrufende Person zu warten, und anschließend zu pausieren und zuzuhören. Behalte die vorhandenen Anweisungen vom Sitzungsstart bei.
  2. Warte auf session.instructions.appended und gleiche dessen client_event_id mit deinem Befehl ab. Behandle einen abgelehnten Befehl, bevor du fortfährst.
  3. Übertrage weiterhin Eingabeaudio, einschließlich der Stille, bevor die anrufende Person spricht. Sende bei WebSocket weiterhin session.input_audio.append. Halte bei WebRTC die ausgehandelte Eingabeaudiospur aktiv. Achte im Ausgabetranskript und im Audio auf die Begrüßung.

Verwende die von deiner Anwendung vorgegebene Sprache, bis die anrufende Person spricht. Leite sie nicht aus einem Namen, einer Telefonnummer oder einem Standort ab. Hinweise zur Gestaltung von Prompts findest du unter Prompts für Sprachmodelle formulieren.

Wenn eine Begrüßung den Anweisungen der Anwendung folgen muss, sende diese Anweisungen mit session.instructions.append. Fordere den Assistenten anschließend mit einer kurzen Nachricht über session.commentary.append zum Start auf. Zum Beispiel: “Begin the conversation now, following the instructions provided.” Übertrage weiterhin Eingabeaudio, einschließlich der Stille, bevor die anrufende Person spricht.

Mit Anweisungen forderst du eine Begrüßung an. Sie garantieren weder den genauen Wortlaut noch eine unterbrechungsfreie Wiedergabe. Die API sendet kein Ereignis für den Abschluss der Begrüßung, und eine Bestätigung bedeutet nicht, dass die Begrüßung gehört wurde. Steuere die Wiedergabe über deine Anwendung, wenn die Audioausgabe wortgetreu sein muss. Teste deine Begrüßung mit den Sprachen und Unterbrechungen, die deine Anwendung unterstützt.

Einen Hinweis ausgeben

Verwende session.instructions.append, um einen bestimmten gesprochenen Wortlaut für einen Hinweis anzufordern. Bei session.commentary.append kann der Text umformuliert werden. Sende nach session.started beispielsweise Folgendes:

export function sendUpdate(connection) {
  connection.send({
    type: "session.instructions.append",
    event_id: "disclosure_1",
    delegation_id: null,
    content:
      "Immediately say the following disclosure exactly and in full before responding to the caller: This call may be recorded for quality and training purposes.",
  });
}

Übertrage weiterhin Eingabeaudio, wie unter Anrufende begrüßen, bevor sie sprechen beschrieben. Wähle den Zeitpunkt der Ausgabe bewusst: Eine während des Gesprächs gesendete Anweisung kann einen laufenden Sprachbeitrag unterbrechen.

Damit forderst du den Wortlaut an, garantierst aber keine exakte Ausgabe. Überprüfe den vollständigen gesprochenen Hinweis und die tatsächliche Wiedergabe, bevor du ihn als ausgegeben markierst. session.instructions.appended bestätigt lediglich, dass die Anweisung angenommen wurde. Wenn eine exakte Audioausgabe erforderlich ist, spiele eine überprüfte Aufnahme oder einen gerenderten Clip über deine Anwendung ab und steuere währenddessen die Ausgabe von GPT-Live. Siehe Wiedergabe bei Bedarf steuern.

Längere Gespräche verwalten

GPT-Live verwaltet den Kontext bei langen Gesprächen automatisch. Dafür ist kein Konfigurationsparameter erforderlich. Die Anweisungen, die du beim Sitzungsstart bereitstellst, bleiben während der Compaction (Kontextverdichtung) erhalten. Du musst sie nicht erneut senden.

Das standardmäßige Kontextfenster umfasst 128.000 Token. Dazu gehören deine Anweisungen, der Gesprächstext und Audio-Token, die nicht im Transkript erscheinen.

GPT-Live fasst ältere Gesprächsinhalte im Hintergrund zusammen. Sobald die Kontextauslastung 90 % überschreitet, startet es innerhalb derselben Sitzung eine neue Voice-Engine als Ersatz. Diese erhält deine ursprünglichen Anweisungen und bis zu 8.192 Token aus dem Gesprächsverlauf: die neuesten Nachrichten und, sofern verfügbar, eine Zusammenfassung älterer Nachrichten. Das Erstellen einer Zusammenfassung ändert den Kontext der laufenden Engine nicht sofort.

Ältere Gesprächsdetails können zusammengefasst oder ausgelassen werden. Halte wichtige Fakten, bestätigte Aktionen und den aktuellen Aufgabenstatus in deiner Anwendung fest und stelle bei Bedarf relevanten Kontext bereit.

Eine Sitzung speichern und forken

Setze beim Erstellen der Sitzung store in der Sitzungskonfiguration auf true, um eine Aufzeichnung für spätere Downloads oder Forks zu speichern. Die Speicherung ist standardmäßig auf false gesetzt und muss für dein Projekt aktiviert sein. Downloads und Forks setzen eine abgeschlossene, gespeicherte Aufzeichnung und eine Datenrichtlinie voraus, die dauerhafte Speicherung erlaubt. Aufzeichnungen laufen nach 30 Tagen ab. Wenn die Richtlinie „keine Datenaufbewahrung“ gilt, wird store als false behandelt. Downloads von Aufzeichnungen und Forks sind dann nicht verfügbar. Siehe Datenkontrollen für GPT-Live.

Füge dieses Feld beispielsweise dem session-Objekt in deinem WebSocket-Ereignis session.start oder deiner WebRTC-Erstellungsanfrage hinzu:

{
  "store": true
}

Speichere die ID der Ursprungssitzung aus session.started oder der Antwort auf die WebRTC-Erstellungsanfrage. Ein Fork startet anhand des gespeicherten Sitzungszustands eine neue Sitzung mit einer neuen ID. Er öffnet weder die ursprüngliche Verbindung erneut noch verwendet er die ID der Ursprungssitzung wieder.

Starte den Fork über den Transport, den deine Anwendung verwendet:

TransportDen Fork starten
WebSocketStelle eine Verbindung zu wss://api.openai.com/v1/live/sessions/{source_session_id}/fork her.
WebRTCSende ein neues SDP-Angebot an POST /v1/live/sessions/{source_session_id}/fork. Wende die zurückgegebene Antwort aus transport.sdp auf die neue Peer-Verbindung an.

Ein Fork übernimmt die gespeicherte Sitzungskonfiguration unter Berücksichtigung der unten beschriebenen Transportregeln. Sende für einen WebSocket-Fork session.start mit dem erforderlichen session-Objekt. Mit {} überschreibst du keine Einstellungen. Gib kein neues Modell an und wiederhole weder die ursprünglichen Anweisungen noch die ursprüngliche Eingabe. Du kannst store, die Einstellungen für die Responses-Delegation und das Audioformat der neuen WebSocket-Verbindung überschreiben. Bei WebRTC-Forks kannst du store, die Einstellungen für die Responses-Delegation und die Berechtigungen des Frontend-Clients überschreiben. Wenn du store bei einem Fork weglässt, übernimmt er die Einstellung der Ursprungssitzung.

Ein WebSocket-Fork übernimmt das ursprüngliche Audioformat nicht: Setze audio.format ausdrücklich oder verwende das Standardformat PCM16 mit 24 kHz. Außerdem verwirft er übernommene Berechtigungen für den Datenkanal des Frontends. WebRTC-Forks handeln ihr Audioformat aus und lehnen audio.format ab. Sie behalten die Berechtigungseinstellungen des Frontends bei, sofern du sie nicht überschreibst.

Warte auf session.started, bevor du weitere WebSocket-Befehle sendest. WebRTC startet über die HTTP-Anfrage und darf kein zweites session.start über seinen Datenkanal erhalten.

Einen WebSocket-Fork starten

Setze OPENAI_API_KEY. Die Beispiele verwenden die von deiner Anwendung gespeicherte ID der gespeicherten Ursprungssitzung. Sie bestätigen den Start und schließen anschließend den Fork. Um das Gespräch fortzusetzen, sende und empfange nach session.started Audio gemäß dem Ablauf für WebSocket-Verbindungen. Die Felder und Ereignisse für den Start findest du in der Referenz zum Forken über WebSocket.

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

async function forkSession(sourceSessionId) {
  const ws = new ForksWS(new OpenAI(), { session_id: sourceSessionId });
  let finalized = false;
  try {
    for await (const event of ws) {
      if (event.type === "open") {
        ws.send({ type: "session.start", session: {} });
      } else if (event.type === "error") {
        throw event.error;
      } else if (event.type === "message") {
        if (event.message.type === "session.started") {
          console.log("Fork ready:", event.message.session.id);
          // This startup example closes the fork after confirming it is ready.
          ws.send({ type: "session.close" });
        } else if (event.message.type === "session.closed") {
          console.log("Final usage:", event.message.usage);
          finalized = true;
          break;
        }
      }
    }
    if (!finalized) throw new Error("Connection closed before session.closed");
  } finally {
    ws.close();
  }
}

Einen WebRTC-Fork starten

Erstelle in deinem Frontend ein neues SDP-Angebot und sende es an dein Backend. Die folgenden Backend-Beispiele verwenden dieses Angebot und die in deiner Anwendung gespeicherte ID der Ursprungssitzung:

import OpenAI from "openai";

async function forkSession(sourceSessionId, offerSdp) {
  const client = new OpenAI();
  const fork = await client.live.sessions.fork(sourceSessionId, {
    transport: { type: "webrtc", sdp: offerSdp },
  });
  console.log(JSON.stringify(fork));
}

Gib die Antwort an dein Frontend zurück, übernimm transport.sdp als Antwort für die neue Peer-Verbindung und speichere die neue session.id. Bewahre den API-Schlüssel in deinem Backend auf.

Verwende die neue Sitzungs-ID für spätere Sideband-Verbindungen und die Sitzungssteuerung. Speichere den Aufgabenstatus deiner Anwendung separat: Die Wiederherstellung des Gesprächszustands bestätigt nicht, dass eine ausstehende Backend-Aktion abgeschlossen wurde. Kläre ungewisse Ergebnisse, bevor du eine Aktion erneut ausführst. Wenn du keine gespeicherte Sitzung zum Forken hast, initialisiere eine neue Sitzung mit dem gespeicherten Verlauf.

Eine Aufzeichnung herunterladen

Sobald die gespeicherte Aufzeichnung finalisiert ist, kannst du ihre Audiodaten mit GET /v1/live/sessions/{session_id}/content herunterladen. Die Antwort enthält binäre Stereo-WAV-Daten mit den Eingabeaudiodaten im linken und den Ausgabeaudiodaten im rechten Kanal. Die Beispiele verwenden die gespeicherte Sitzungs-ID aus deiner Anwendung und streamen die Antwort nach recording.wav:

import OpenAI from "openai";
import { createWriteStream } from "node:fs";
import { pipeline } from "node:stream/promises";

async function downloadRecording(sessionId) {
  const client = new OpenAI();
  const response = await client.live.sessions.downloadRecording(sessionId);
  if (!response.body) throw new Error("Recording response has no body");
  await pipeline(response.body, createWriteStream("recording.wav"));
}

Fehler behandeln und die Sitzung beenden

Lies weiterhin Sitzungsereignisse, bis die Sitzung finalisiert ist. Unterscheide zwischen einem abgelehnten Befehl, einer fehlgeschlagenen Verbindung und einer abgeschlossenen Sitzung, damit deine Anwendung angemessen darauf reagieren kann.

Abgelehnte Befehle behandeln

Lies neben Bestätigungen auch error-Ereignisse. Sofern vorhanden, identifiziert error.client_event_id den gesendeten Befehl, der fehlgeschlagen ist:

{
  "type": "error",
  "event_id": "event_error",
  "error": {
    "type": "invalid_request_error",
    "code": "immutable_field_update",
    "message": "The delegation type cannot change after session startup.",
    "param": "session.delegation.type",
    "client_event_id": "event_update"
  }
}

Ein Fehlercode kann null sein, und bei einem Fehler kann die Client-Ereignis-ID fehlen. Behandle diese Fälle, ohne davon auszugehen, dass ein Befehl erfolgreich war. Bei einem Fehler aufgrund eines unveränderlichen Felds behältst du die aktuelle Konfiguration bei oder erstellst eine neue Sitzung mit den gewünschten Einstellungen.

Moderation behandeln

Moderation kann sich auf zwei Arten auf die Sitzung auswirken:

  • Einige Moderationsereignisse beenden die Sitzung.
  • Andere brechen die Audioausgabe des Assistenten für den Rest seiner aktuellen Äußerung ab und lösen ein error-Ereignis aus, ohne die Sitzung zu beenden.

Lies error-Ereignisse auch während der Audiowiedergabe. Gehe nicht davon aus, dass jeder Moderationsfehler die Sitzung schließt oder dass eine Audiounterbrechung einen Verbindungsfehler bedeutet. Halte den Anwendungszustand mit dem Sitzungslebenszyklus synchron und markiere eine unterbrochene gesprochene Nachricht nicht als vollständig wiedergegeben. Schutzmechanismen für Gespräche auf Anwendungsebene bleiben von diesem integrierten Moderationsverhalten getrennt.

Nutzungsdaten und geordnetes Beenden

session.usage.updated meldet die kumulierte Sprachdauer in Sekunden:

{
  "type": "session.usage.updated",
  "event_id": "event_usage_1",
  "usage": { "seconds": 12 },
  "context_window": { "usage_ratio": 0.42 }
}

Dies sind Momentaufnahmen, keine Zuwächse, die du addieren solltest. Die Token-Nutzung im Backend wird separat erfasst. Bewahre sie aus den verschachtelten Responses-Abschlussereignissen auf. Informationen zur Nutzungserfassung findest du unter Kosten optimieren.

So beendest du die Sitzung geordnet:

  1. Schließe alle delegierten Responses-Aufgaben ab, die deine Anwendung benötigt, einschließlich ausstehender Funktionsergebnisse und Fortsetzungen von Antworten.
  2. Registriere den Listener für session.closed, bevor du session.close sendest.
  3. Sende session.close und übermittle keine neuen Aufgaben mehr an die Sitzung. Halte die WebSocket- oder WebRTC-Verbindung, den Datenkanal und alle angeschlossenen Sideband-Empfänger aktiv, während die ausstehenden Sitzungsereignisse noch eintreffen.
  4. Lies die endgültigen Werte für usage.seconds und reason sowie die Momentaufnahme der Sitzung aus session.closed. Bewahre bereits über response.event empfangene Nutzungsdaten zu delegierten Aufgaben auf.
  5. Gib nach diesem Ereignis die Ressourcen für Transportverbindungen und Audiogeräte frei. Wenn die Finalisierung fehlschlägt oder ein von deiner Anwendung festgelegtes Zeitlimit überschreitet, melde die unvollständige Finalisierung und gib die Ressourcen frei.

Das Senden von session.close bricht Responses in der Warteschlange ab und führt dazu, dass weitere Befehle abgelehnt werden. Eine aktive Antwort kann noch abgeschlossen werden. Eine Antwort, die auf ein Funktionsergebnis wartet, kann jedoch nicht fortgesetzt werden, sobald das Schließen begonnen hat. Entscheide separat, ob Aufgaben, die deine Anwendung über Client-Delegation ausführt, abgeschlossen oder abgebrochen werden sollen.

Das Ereignis session.closed bestätigt die Finalisierung. Die eingebettete Sitzung ist eine Momentaufnahme der Konfiguration. Ein geschlossener Socket allein bestätigt keinen Erfolg, und ein Schließcode der Transportverbindung nach einem gültigen Abschlussereignis macht die Finalisierung nicht ungültig. Wenn du die WebRTC-Verbindung unmittelbar nach dem Senden des Befehls schließt, kann das die Zustellung des Abschlussereignisses verhindern.

Das Feld reason im Abschlussereignis erklärt, warum die Sitzung beendet wurde:

GrundBedeutung
close_requestedDeine Anwendung hat session.close gesendet oder den Hangup-Endpunkt aufgerufen.
expiredDie Sitzung hat ihre maximale Dauer erreicht.
contentEin Sicherheitsfilter hat die Sitzung beendet.
remote_hangupDie primäre Verbindung wurde von der Gegenstelle geordnet beendet.
connection_lostDie primäre oder die Upstream-Verbindung ist unerwartet abgebrochen.

Ein session.closed-Ereignis bestätigt die Finalisierung auch dann, wenn die Sitzung wegen eines Verbindungsverlusts oder aus Sicherheitsgründen beendet wurde. Ohne dieses Ereignis bleiben die endgültigen Nutzungsdaten unbestätigt. Bei einer gespeicherten Sitzung kann die Finalisierung länger dauern, während ihre Aufzeichnung gespeichert wird. Wähle für deine Anwendung ein Zeitlimit, das diesen Speichervorgang berücksichtigt.

Nach einem Verbindungsfehler fortfahren

Ein HTTP-Fehler beim Erstellen einer Sitzung bedeutet, dass die Sitzung session.started nicht erreicht hat. Behandle Startfehler getrennt von Fehlern in einer laufenden Sitzung. Wenn eine laufende Verbindung vor session.closed fehlschlägt, bewahre die zuletzt erfassten Nutzungsdaten auf und markiere die endgültigen Nutzungsdaten als unbestätigt.

Wenn eine gespeicherte Sitzung verfügbar ist, forke sie, um eine neue Sitzung aus ihrem gespeicherten Zustand zu starten. Andernfalls erstellst du eine Ersatzsitzung mit dem relevanten gespeicherten Verlauf. Gleiche ausstehende Aktionen mit deinem Backend ab, bevor du sie erneut ausführst, und unterdrücke veraltete Ergebnisse aus der vorherigen Sitzung. Stelle den Anwendungszustand explizit wieder her, statt anzunehmen, dass eine neue Verbindung die vorherige Sitzung oder deren ausstehende Aufgaben fortsetzt.