Skip to main content

Einführung

Die Echtzeit-Konversation stellt über WebSocket (ein Protokoll, das eine langlebige, bidirektionale Verbindung zwischen Client und Server hält) eine dauerhafte Verbindung her, überträgt Ihre Audio- oder Texteingabe in Echtzeit an das Konversationsmodell, und das Modell schiebt Text- und Sprachantworten inkrementell zurück. Sie eignet sich für Sprachassistenten, Echtzeit-Fragen und Antworten, Sprechübungen und andere Szenarien mit wechselseitiger Interaktion. Wie die Echtzeit-Transkription läuft sie über WebSocket, die beiden haben jedoch unterschiedliche Zwecke: Verfügbares Modell:
  • gpt-realtime-2.1: Konversations-Sprachmodell, unterstützt Audio- und Texteingabe und gibt Text- und Sprachantworten in Echtzeit aus.
Diese API ist für die serverseitige Integration gedacht; Browser können sich nicht direkt verbinden. Aus Sicherheitsgründen prüft und lehnt das Gateway Verbindungen mit einem Origin-Header ab, lehnt das openai-insecure-api-key-Subprotokoll ab und akzeptiert den Schlüssel nur über den Standard-Header Authorization. Ein vom Browser initiierter WebSocket fügt automatisch einen Origin-Header hinzu und wird daher abgelehnt. Wenn Sie Echtzeit-Konversation im Frontend benötigen, stellen Sie die Verbindung zum Gateway von Ihrem eigenen Server aus her und leiten Sie Audio und Ergebnisse zwischen Frontend und Server weiter.

Schnellstart

Verbindungsendpunkt

  • model=gpt-realtime-2.1: erforderlich, das Modell wird beim Verbindungsaufbau durch den URL-Parameter festgelegt und kann während der Sitzung nicht mehr geändert werden (siehe die Einschränkungen unten).
  • Beachten Sie den Unterschied zur Transkription: Der Konversationsendpunkt übernimmt kein intent=transcription.

Authentifizierung

Übergeben Sie den Schlüssel beim Handshake in einem Standard-HTTP-Header:

Anforderungen an das Audioformat

Audioeingabe und -ausgabe unterstützen derzeit nur ein Format. Konvertieren Sie Ihr Audio vor dem Senden:
  • Kodierung: PCM16 (16-Bit-Ganzzahl mit Vorzeichen, Little-Endian)
  • Abtastrate: 24000 Hz
  • Kanäle: Mono
Also audio/pcm@24000. Wird für Eingabe oder Ausgabe ein anderes Format (etwa G.711/µ-law) deklariert, wird dies abgelehnt und die Sitzung geschlossen.
Anders als bei der Transkription unterstützen Konversationssitzungen die Sprachaktivitätserkennung (turn_detection / VAD). Ist sie aktiviert, erkennt das Modell automatisch das Ende eines Redebeitrags und löst eine Antwort aus; ist sie deaktiviert (auf null gesetzt), steuern Sie selbst, wann Audio übergeben und wann eine Antwort angefordert wird. Wählen Sie je nach Bedarf.

Sitzungskonfiguration (session.update)

Nach dem Verbindungsaufbau kann der Client einen session.update-Frame senden, um Konversationsparameter zu konfigurieren (etwa Stimme, Systemanweisungen, ob VAD aktiv ist). Das Modell der Konversationssitzung ist bereits durch die Verbindungs-URL verankert, daher können Sie ohne session.update direkt sprechen; senden Sie ihn, wenn Sie eine eigene Stimme oder Anweisungen benötigen.

Konfigurationsparameter

string
erforderlich
Sitzungstyp, für Konversation realtime.
string
Systemanweisungen, die Rolle, Ton und Antwortvorgaben des Modells festlegen.
string[]
Ausgabemodalitäten, entweder ["audio"] oder ["text"]: Mit ["audio"] (Standard) gibt das Modell Sprache aus, und der Antworttext kommt über das Ereignis response.output_audio_transcript.delta. Mit ["text"] gibt es nur Text aus, der über response.output_text.delta geliefert wird. Jede andere Kombination (zum Beispiel ["audio", "text"]) wird abgelehnt und liefert ein error-Ereignis.
object
erforderlich
Audioformat der Eingabe, festgelegt auf { "type": "audio/pcm", "rate": 24000 }.
object | null
Sprachaktivitätserkennung. Übergeben Sie { "type": "server_vad" }, um die automatische Turn-Erkennung zu aktivieren; übergeben Sie null, um sie zu deaktivieren und Audio sowie Antwortanforderungen manuell vom Client zu steuern.
object
erforderlich
Audioformat der Ausgabe, festgelegt auf { "type": "audio/pcm", "rate": 24000 }.
string
Stimme der Antwortausgabe. Sie kann nach Beginn der ersten Antwort nicht mehr geändert werden: Sobald die Sitzung in den Generierungszustand wechselt, wird ein erneut gesendetes voice ignoriert (die übrigen Einstellungen gelten weiterhin). Legen Sie die Stimme daher vor der ersten Antwortanforderung fest.
Die folgenden Funktionen werden in dieser Version nicht unterstützt und schließen die Sitzung bei Konfiguration (Schließcode 1008): das Aktivieren der Inline-Transkription innerhalb einer Konversationssitzung (audio.input.transcription, Grund input_transcription_not_supported), das Einbringen von Audio (Grund item_audio_not_supported) oder Bildern (Grund image_input_not_supported) über Konversationselemente sowie jeder andere Inhaltselementtyp als Text (Grund unsupported_content_part). Senden Sie Audio ausschließlich über den Kanal input_audio_buffer.append.

Eingabe senden

Audio senden

Zerlegen Sie PCM16-Audio in kleine Stücke (etwa ein Stück pro 100 ms), kodieren Sie sie mit base64 und senden Sie sie fortlaufend über das Ereignis input_audio_buffer.append:
Bei aktiviertem VAD erkennt das Modell das Ende eines Redebeitrags und löst automatisch eine Antwort aus. Bei deaktiviertem VAD müssen Sie nach dem Senden eines Abschnitts manuell übergeben und eine Antwort anfordern:

Text senden

Sie können auch direkt eine Textnachricht einbringen und dann eine Antwort anfordern:

Antworten empfangen

Der Server schiebt fortlaufend Ereignisse. Wichtige Ereignistypen:
event
Bestätigung, dass die Sitzung erstellt oder ihre Konfiguration aktualisiert wurde. Nach session.created können Sie Audio und Text senden.
event
Ein Konversationselement wurde geschrieben: jede Nutzereingabe und jede Modellantwort erzeugt ein Element.
event
Bei aktivierter VAD hat der Server erkannt, dass der Nutzer zu sprechen beginnt oder aufhört. Ein speech_started-Ereignis bedeutet meist, dass der Nutzer das Modell unterbricht; siehe Unterbrechung und Kürzung.
event
Eine Antwort wurde zu generieren begonnen.
event
Das Ausgabeelement der Antwort hat begonnen und ist abgeschlossen. Das Feld item.id im added-Ereignis ist die ID des Konversationselements, die Sie beim späteren Kürzen von Audio referenzieren.
event
Ein inkrementeller Ausschnitt des Antwort-Audios (base64-kodiertes PCM16) und seine Abschlussmarkierung; Sie können ihn beim Eintreffen abspielen.
event
Das inkrementelle Transkript passend zum Antwort-Audio, Satz für Satz, und seine Abschlussmarkierung; das Feld delta enthält den neu hinzugefügten Text. Bei aktivierter Audioausgabe nehmen Sie den Antworttext aus diesem Ereignis, etwa um während der Wiedergabe Untertitel anzuzeigen.
event
Ein inkrementeller Ausschnitt einer reinen Textantwort und ihre Abschlussmarkierung, nur bei der Ausgabemodalität Text (output_modalities: ["text"]).
event
Eine Antwort ist abgeschlossen. Dieses Ereignis trägt den Token-Verbrauch des Turns (usage), auf dem die Abrechnung basiert.
event
Bestätigung, dass die Kürzungsanforderung wirksam wurde; siehe Unterbrechung und Kürzung.
event
Fehlereignis mit Fehlercode und Beschreibung. Ein Problem der Anfrage selbst (etwa ein ungültiger Wert für output_modalities) liefert ein einzelnes error-Ereignis, und die Sitzung bleibt nutzbar; Richtlinienfragen (Modellwechsel, aufgebrauchtes Guthaben) schließen die Sitzung.
Wählen Sie das richtige Ereignis für den Antworttext. Standardmäßig (Ausgabe enthält Audio) schiebt das Modell nur response.output_audio_transcript.delta und nicht response.output_text.delta; setzen Sie die Ausgabemodalität auf reinen Text, wandert der Text zu response.output_text.delta. Überwachen Sie in beiden Modi beide Ereignisse, damit kein Text verloren geht (siehe Ausgabe aus dem Messlauf unten).

Unterbrechung und Kürzung

Wenn der Nutzer zu sprechen beginnt, während das Modell spricht, steht bereits generierter, aber noch nicht abgespielter Inhalt dem nächsten Satz des Nutzers entgegen. Bei einer WebSocket-Verbindung übernimmt der Client die Wiedergabe, also schließt der Client auch die Aufräumarbeit nach einer Unterbrechung ab. Bei aktivierter VAD sendet der Server input_audio_buffer.speech_started, sobald er erkennt, dass der Nutzer zu sprechen begonnen hat. Nach Erhalt dieses Ereignisses sollte der Client:
  1. Die lokale Wiedergabe sofort stoppen und festhalten, wie weit die Antwort bereits abgespielt wurde (in Millisekunden).
  2. conversation.item.truncate senden, um das nicht abgespielte Audio aus der Konversation zu entfernen, damit das Modell es im nächsten Turn nicht als gesprochen behandelt.
  • item_id: die ID des Konversationselements dieser Antwort, entnommen aus item.id im Ereignis response.output_item.added.
  • content_index: der Index des Audio-Inhaltsteils, immer 0.
  • audio_end_ms: die beizubehaltende Audiolänge in Millisekunden, nach der tatsächlich abgespielten Position des Clients.
Der Server antwortet mit conversation.item.truncated, sobald die Anforderung verarbeitet ist. Die Kürzung betrifft nur das Audio dieser Antwort und das zugehörige Transkript; die Sitzung selbst bleibt unverändert, und Sie können mit dem nächsten Turn fortfahren. Im OpenAI SDK entspricht das conn.conversation.item.truncate(item_id=..., content_index=0, audio_end_ms=...). Bei deaktivierter VAD (etwa Push-to-Talk) ist der Tastendruck die Unterbrechung: Senden Sie beim Drücken response.cancel, um die laufende Antwort abzubrechen, und kürzen Sie dann wie oben beschrieben. Beim Loslassen senden Sie input_audio_buffer.append, input_audio_buffer.commit und response.create in dieser Reihenfolge.

Vollständige Beispiele

Unten stehen drei Vorgehensweisen; wählen Sie eine:
  • Offizielles OpenAI SDK (empfohlen): Sie müssen keine WebSocket-Frames von Hand schreiben; richten Sie websocket_base_url (der WebSocket-Basis-URL-Parameter des SDK) auf das Gateway und nutzen Sie die offizielle Bibliothek weiter.
  • Offizielles OpenAI Agents SDK: die Echtzeit-Sprachform des offiziellen Agent-Frameworks; ersetzen Sie die url in model_config durch die Gateway-Adresse.
  • Rohes websockets: ohne SDK Frames direkt nach Protokoll austauschen. Wenigste Abhängigkeiten und am einfachsten zu diagnostizieren.
Warum den Modellnamen beim Verbindungsaufbau übergeben? Das AiHubMix-Gateway benötigt das model im Moment des WebSocket-Handshakes, um den Modellanbieter zu wählen, zu authentifizieren und Kontingent zu reservieren, während session.update erst nach Abschluss des Handshakes eintrifft. Mit einem SDK müssen Sie daher model explizit an connect() übergeben (das SDK setzt es in die URL-Abfrage); ohne es lehnt das Gateway bereits beim Handshake ab und es kommt keine Verbindung zustande. Anders als bei der Transkription benötigt der Konversationsendpunkt kein intent=transcription.
Um beliebiges Audio in das von dieser API geforderte rohe PCM-Format zu bringen, nutzen Sie ffmpeg:

Offizielle Beispiele wiederverwenden

Die meisten von OpenAI veröffentlichten Echtzeit-Konversationsbeispiele hängen nur vom Basis-URL-Parameter des SDK ab; richten Sie die Adresse auf den AiHubMix-Endpunkt und Sie können sie wiederverwenden:

Ausgabe aus dem Messlauf (in Produktion)

Nachfolgend das reale Ergebnis des OpenAI-SDK-Beispiels in der Produktionsumgebung aihubmix.com mit dem Modell gpt-realtime-2.1. Die Sitzung aktiviert server_vad, und sowohl die Prompts als auch das Audio sind englisch. Texteingabe
Audioeingabe
Gemessener Unterschied zweier Konfigurationen
Gemessene Bestätigung: Standardmäßig (Ausgabe enthält Audio) trifft der Antworttext zeichenweise nur über response.output_audio_transcript.delta ein, und response.output_text.delta erscheint nie; response.done trägt die usage des Turns; der Handshake dauert etwa 2 bis 4 Sekunden, die Kosten der Kontingentreservierung beim Aufbau der Sitzung.

Abrechnung

  • Abrechnung pro Token: Eine Konversationssitzung gibt die Token-Nutzung jedes Turns (usage) mit dem Ereignis response.done zurück, und darauf basiert die Abrechnung. Die Nutzung wird getrennt nach Komponenten gemessen, darunter Audioeingabe, Audioausgabe, Texteingabe und Textausgabe. Der Stückpreis jeder Komponente folgt dem laufend ausgewiesenen Preis auf der Modelldetailseite.
  • Laufende Abrechnung: Dies ist eine langlebige Verbindung, und die Kosten werden während der Sitzung mit jedem Turn in Echtzeit abgezogen, ohne einmalige Abrechnung am Ende. Beim Aufbau einer Sitzung wird zunächst eine Kontingentreservierung von etwa einer Minute Nutzung vorgenommen (nur eine Zulassungsprüfung, keine tatsächliche Belastung), und die verbleibende Reservierung wird am Ende der Sitzung freigegeben. Das verfügbare Guthaben Ihres Kontos muss daher mindestens etwa eine Minute Nutzung abdecken, damit eine Sitzung aufgebaut werden kann.
  • Jeder Abrechnungsdatensatz einer Echtzeit-Konversation ist in Nutzung und Abrechnung einzeln einsehbar.

Grenzen und Einschränkungen

  1. Sitzungsdauer: Eine WebSocket-Verbindung dauert höchstens 62 Minuten, danach schließt der Server sie (Schließcode 1000, Grund session_duration_limit). Teilen Sie sie auf, wenn Sie länger brauchen.
  2. Trennung bei Inaktivität: Wenn weder der Client noch das Modell 5 Minuten lang Aktivität zeigt, schließt der Server die Sitzung (Schließcode 1008, Grund idle_timeout). Aktivität einer der beiden Seiten setzt den Timer zurück, eine lange weiter gestreamte Antwort wird also nicht unterbrochen.
  3. Unzureichendes Guthaben: Beim Aufbau der Sitzung wird der Handshake direkt abgelehnt (HTTP 403) und keine Sitzung aufgebaut, wenn das verfügbare Guthaben die Reservierung von etwa einer Minute nicht abdeckt; während der Sitzung wird die aufgebaute Verbindung sofort geschlossen, wenn das Guthaben verbraucht ist.
  4. Nur serverseitig: Direkte Browserverbindungen werden nicht unterstützt (der Origin-Header wird geprüft); integrieren Sie serverseitig.
  5. Modell fixiert: Das Modell ist in der Verbindungs-URL festgelegt, und eine Änderung per session.update während der Sitzung wird abgelehnt und schließt die Sitzung.
  6. Format fixiert: Audioeingabe und -ausgabe unterstützen nur audio/pcm@24000 mono; andere Formate werden abgelehnt.
  7. Stimme fixiert: voice kann nach Beginn der ersten Antwort nicht geändert werden; legen Sie sie vor der ersten Antwortanforderung fest.
  8. Nicht unterstützt: Inline-Transkription innerhalb einer Konversationssitzung, das Einbringen von Audio- oder Bildinhalten über Konversationselemente sowie jeder andere Inhaltselementtyp als Text.
  9. Eine Antwort zugleich: Eine Sitzung erlaubt nur eine laufende Antwort; ein weiteres response.create vor Abschluss des aktuellen Turns wird abgelehnt und schließt die Sitzung (Schließcode 1008, Grund response_already_active).

Häufige Fehler


Zuletzt aktualisiert: 2026-09-21