Verwenden der Antwort-API im WebSocket-Modus

Die Responses-API unterstützt einen WebSocket-Modus für lang andauernde, werkzeugintensive Workflows. Im WebSocket-Modus behalten Sie eine dauerhafte Verbindung zu /v1/responses bei und setzen jede Runde fort, indem Sie nur neue Eingabeelemente zusammen mit einem previous_response_id senden. Dieser Ansatz reduziert den Aufwand pro Drehung und verbessert die End-to-End-Latenz über lange Ketten hinweg.

WebSocket-Modus funktioniert mit store=false.

Voraussetzungen

  • Ein Azure OpenAI-Modell bereitgestellt.
  • Eine Authentifizierungsmethode:
    • API-Schlüssel oder
    • Microsoft Entra-ID.
  • Beispiele für Python:
    • Installieren Sie das websocket-client Paket.
    • Installieren Sie azure-identity für Microsoft Entra ID Authentifizierung.

Wann der WebSocket-Modus verwendet werden sollte

Verwenden Sie den WebSocket-Modus, wenn ein Workflow viele Modelltool-Roundtrips umfasst, z. B. agentische Codierungs- oder Orchestrierungsschleifen mit wiederholten Toolaufrufen. Da die Verbindung geöffnet bleibt und jede Übertragung nur inkrementelle Daten sendet, ist die Latenz bei der Fortsetzung niedriger als bei wiederholten HTTP-Anforderungen.

Verwenden Sie für Single-Shot-Anforderungen oder kurze Unterhaltungen die standardmäßige HTTP-Antwort-API.

Funktionsweise

Sie öffnen eine WebSocket-Verbindung zu /v1/responses und steuern diese mit response.create Ereignissen.

  • Das erste response.create-Ereignis startet einen neuen Dialogschritt. Die Nutzlast spiegelt den HTTP-Erstellungstext wieder, mit der Ausnahme, dass transportspezifische Felder wie stream und background nicht angewendet werden.
  • Nachfolgende response.create-Nachrichtenkette aus der vorherigen Antwort, die previous_response_id verwendet und nur neue Eingabeelemente enthält.

Serverereignisse und -sortierung entsprechen dem vorhandenen Antwortstreamingereignismodell.

Starten einer Wende

Senden eines response.create Ereignisses im geöffneten Socket. Die folgenden Beispiele stellen eine Verbindung mit dem WebSocket-Endpunkt her, und stellen Sie dem Modell eine Frage. Der WebSocket-Modus unterstützt sowohl DEN API-Schlüssel als auch die Microsoft Entra ID-Authentifizierung – wählen Sie die Registerkarte aus, die Ihrer Authentifizierungsmethode entspricht.

from websocket import create_connection
import json

ws = create_connection(
    f"wss://{YOUR_RESOURCE_NAME}.openai.azure.com/openai/v1/responses",
    header=[f"Authorization: Bearer {YOUR_AOAI_API_KEY}"],
)

ws.send(json.dumps({
    "type": "response.create",
    "model": "gpt-4.1", # Replace with your model deployment name
    "store": False,
    "input": [
        {
            "type": "message",
            "role": "user",
            "content": [{"type": "input_text", "text": "Find fizz_buzz()"}],
        }
    ],
    "tools": [],
}))

Tipp

Sie können den Anforderungsstatus optional aufwärmen, indem Sie response.create mit generate: false senden. Verwenden Sie diese Option, wenn Sie bereits die Tools, Anweisungen oder Nachrichten kennen, die Sie mit einer bevorstehenden Wendung senden möchten. Ein Warmup gibt keine Modellausgabe zurück, bereitet aber den Anfragezustand vor, sodass der nächste generierte Vorgang schneller gestartet werden kann. Die Warmup-Anforderung gibt eine Antwort-ID zurück, die Sie mithilfe von previous_response_id verketten können.

Streaming der Antwort

Lesen Sie Ereignisse aus dem WebSocket, geben Sie den Text aus, während er hereingestreamt wird, und beenden Sie, wenn die Antwort abgeschlossen ist.

while True:
    event = json.loads(ws.recv())

    if event["type"] == "response.output_text.delta":
        print(event["delta"], end="", flush=True)

    elif event["type"] == "response.completed":
        response_id = event.get("response", {}).get("id")
        print(f"\nResponse ID: {response_id}")
        break

# Close the socket only when you are done with all turns.
# ws.close()

Weiter mit den inkrementellen Eingaben

Um dieselbe Kette fortzusetzen, senden Sie eine weitere response.create über demselben Socket mit:

  • previous_response_id auf die vorherige Antwort-ID festgelegt.
  • input enthält nur neue Elemente, z. B. Toolausgabe und die nächste Benutzernachricht.
ws.send(json.dumps({
    "type": "response.create",
    "model": "gpt-4.1",
    "store": False,
    "previous_response_id": f"{response_id}",
    "input": [
        {
            "type": "message",
            "role": "user",
            "content": [{"type": "input_text", "text": "Now optimize it."}],
        },
    ],
    "tools": [],
}))

Fortsetzungssemantik

Der WebSocket-Modus verwendet dieselbe previous_response_id Verkettung wie der HTTP-Modus, fügt jedoch einen Fortsetzungspfad mit geringerer Latenz für den aktiven Socket hinzu.

Für Workflows mit mehreren Agents können Entwicklerdefinierte Funktionsausgaben in die aktive Antwort einfügen, damit der Warte-Agent fortgesetzt werden kann, während andere Agents fortfahren. Siehe Verwenden der Multi-Agent-Orchestrierung mit der Azure OpenAI-Antwort-API.

Bei einer aktiven WebSocket-Verbindung behält der Dienst einen vorherigen Antwortstatus in einem lokalen Speichercache (die letzte Antwort) bei. Die Fortsetzung dieser Antwort ist schnell, da der Dienst den verbindungslokalen Zustand wiederverwendet. Da dieser Zustand nur im Arbeitsspeicher aufbewahrt und nicht auf den Datenträger geschrieben wird, ist der WebSocket-Modus kompatibel mit store=false.

Wenn ein previous_response_id nicht im Arbeitsspeicher-Cache vorhanden ist, hängt das Verhalten davon ab, ob Sie Antworten speichern:

  • Bei store=true kann der Dienst ältere Antwort-IDs aus dem persistenten Zustand hydratisieren. Die Fortsetzung funktioniert weiterhin, verliert jedoch in der Regel den Vorteil der In-Memory-Latenz.
  • Mit store=false gibt es keinen dauerhaften Fallback. Wenn die ID nicht zwischengespeichert ist, gibt die Anforderung zurück previous_response_not_found.

Wenn ein Dialogschritt fehlschlägt (4xx oder 5xx), entfernt der Dienst die referenzierte previous_response_id aus dem verbindungslokalen Cache. Durch diese Entfernung wird verhindert, dass der veraltete Cachestatus für diese fehlerhafte Fortsetzung wiederverwendet wird.

Verdichtung

Wenn Sie die Kontextkomprimierung verwenden, sind zwei unterschiedliche Fortsetzungsmuster vorhanden.

Serverseitige Komprimierung

Wenn Sie die serverseitige Komprimierung (context_management mit compact_threshold) aktivieren, erfolgt die Komprimierung während der normalen /responses Generation. Im WebSocket-Modus fahren Sie wie gewohnt fort: Senden Sie das nächste response.create mit den neuesten previous_response_id und nur neuen Eingabeelementen.

Eigenständige /responses/compact-App

Der eigenständige /responses/compact Endpunkt gibt ein neues komprimiertes Eingabefenster und keine Antwort-ID zurück. Starten Sie nach der Komprimierung eine neue Antwort für Ihre WebSocket-Verbindung, indem Sie previous_response_id weglassen (oder auf null setzen) und die komprimierte Ausgabe als Eingabe sowie die nächsten Benutzer- oder Werkzeugelemente übergeben. Übergeben Sie die komprimierte Ausgabe unverändert; kürzen Sie das zurückgegebene Fenster nicht.

# Compact your current window (HTTP call)
compacted = client.responses.compact(
    model="gpt-4.1",
    input=long_input_items_array,
)

# Start a new response on the WebSocket using the compacted window
ws.send(json.dumps({
    "type": "response.create",
    "model": "gpt-4.1",
    "store": False,
    "input": [
        *compacted.output,
        {
            "type": "message",
            "role": "user",
            "content": [{"type": "input_text", "text": "Continue from here."}],
        },
    ],
    "tools": [],
}))

Verbindungsverhalten und -grenzen

  • Eine einzelne WebSocket-Verbindung kann mehrere response.create Nachrichten empfangen, aber sie wird sequenziell ausgeführt (jeweils eine In-Flight-Antwort).
  • Die Verbindung unterstützt kein Multiplexing. Verwenden Sie mehrere Verbindungen, wenn Parallelausführungen erforderlich sind.
  • Die Verbindungsdauer ist auf 60 Minuten begrenzt. Stellen Sie die Verbindung wieder her, wenn Sie den Grenzwert erreichen.

Erneute Verbindung und Wiederherstellung

Wenn eine Verbindung geschlossen wird oder den Grenzwert von 60 Minuten erreicht, öffnen Sie eine neue WebSocket-Verbindung, und fahren Sie mit einem der folgenden Muster fort:

  • Wenn Ihre vorherige Antwort beibehalten wird (store=true) und Sie über eine gültige Antwort-ID verfügen, fahren Sie mit previous_response_id und neuen Eingabeelementen fort.
  • Wenn Sie die Kette nicht fortsetzen können (z. B. store=false oder previous_response_not_found), beginnen Sie eine neue Antwort, indem Sie previous_response_id weglassen (oder auf null festlegen) und senden Sie den vollständigen Eingabekontext für den nächsten Schritt.
  • Wenn Sie den /responses/compactKontext komprimiert haben, verwenden Sie das zurückgegebene komprimierte Fenster als Basis input für die neue Antwort, und fügen Sie dann die neuesten Benutzer- oder Toolelemente an.

Problembehandlung

  • previous_response_not_found: Die referenzierte Antwort-ID befindet sich nicht im verbindungslokalen Cache, und es gibt keinen persistenten Zustand, von dem aus hydratisiert wird. Starten Sie eine neue Kette, oder aktivieren store=true Sie sie, wenn Ihr Szenario dies zulässt.

    {
      "type": "error",
      "status": 400,
      "error": {
        "code": "previous_response_not_found",
        "message": "Previous response with id 'resp_abc' not found.",
        "param": "previous_response_id"
      }
    }
    
  • websocket_connection_limit_reached: Die Verbindung ist 60 Minuten lang geöffnet. Öffnen Sie eine neue WebSocket-Verbindung, und verwenden Sie weiterhin eines der Muster " Erneute Verbindung" und "Wiederherstellen" .

    {
      "type": "error",
      "status": 400,
      "error": {
        "type": "invalid_request_error",
        "code": "websocket_connection_limit_reached",
        "message": "Responses websocket connection limit reached (60 minutes). Create a new websocket connection to continue."
      }
    }
    

Nächster Schritt