Zum Inhalt springen
Deutsch

Streaming

Streaming auf 1折AI: Anthoropics natives SSE-Ereignisformat, OpenAI-kompatible Chunk-Formatierung und der Umgang mit abgebrochenen Streams.

Für lange Antworten Streaming verwenden ("stream": true), damit das erste Wort schneller erscheint und die Anfrage nicht durch zu lange Bearbeitungszeit von Zwischen-Netzwerken abgebrochen wird. Beide Protokolle werden unterstützt, das Format entspricht jeweils dem offiziellen.

Im Request "stream": true hinzufügen, die Antwort ist ein Server-Sent-Events-Stream. Ein normaler Stream läuft in dieser Reihenfolge (aus der Anthropic Streaming-Dokumentation):

EreignisBedeutung
message_startNachrichtenbeginn, mit Modell und anfänglichem usage
content_block_startBeginn eines Inhaltsblocks (Text, thinking, tool_use)
content_block_deltaInkrementelle Inhaltsaktualisierung, Text steht in delta.text
content_block_stopEnde dieses Inhaltsblocks
message_deltaNachrichtenaktualisierung, mit stop_reason und der finalen Anzahl an Output-Token
message_stopEnde der gesamten Nachricht

Dazwischen können ping-Ereignisse auftreten, diese können ignoriert werden; bei Fehlern wird ein error-Ereignis empfangen.

bash
curl -N https://1zheai.com/v1/messages \
-H "x-api-key: $ONEZHE_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{"model":"claude-sonnet-5-5","max_tokens":128,"stream":true,
"messages":[{"role":"user","content":"从一数到五"}]}'

Bei Verwendung eines SDK müssen die Ereignisse nicht selbst geparst werden, siehe die Streaming-Beispiele in der Anthropic SDK.

/v1/chat/completions mit "stream": true ergänzen, die Antwort sind Chunks im Format data: {...}, der Text steht in choices[0].delta.content, der Stream endet mit data: [DONE]. SDK-Beispiele siehe OpenAI SDK.

Der letzte Chunk vor [DONE] enthält usage, choices ist ein leeres Array. Wird auch zurückgegeben, wenn stream_options.include_usage nicht übergeben wird. Am 2026-10-15 getesteter vollständiger Stream:

text
data: {"id":"msg_011Cg3ERqM8nN58LxLt7TVuG","object":"chat.completion.chunk","created":1792031230,"model":"claude-sonnet-4-6","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"msg_011Cg3ERqM8nN58LxLt7TVuG","object":"chat.completion.chunk","created":1792031230,"model":"claude-sonnet-4-6","choices":[{"index":0,"delta":{"content":"ok"},"finish_reason":null}]}
data: {"id":"msg_011Cg3ERqM8nN58LxLt7TVuG","object":"chat.completion.chunk","created":1792031230,"model":"claude-sonnet-4-6","choices":[{"index":0,"delta":{"content":""},"finish_reason":"stop"}]}
data: {"id":"msg_011Cg3ERqM8nN58LxLt7TVuG","object":"chat.completion.chunk","created":1792031230,"model":"claude-sonnet-4-6","choices":[],"usage":{"prompt_tokens":370,"completion_tokens":4,"total_tokens":374}}
data: [DONE]

Beim Verarbeiten von Chunks zuerst prüfen, ob choices leer ist; das Beispiel auf der OpenAI-SDK-Seite ist bereits so geschrieben.

  • Zuerst prüfen, ob ein Proxy im Spiel ist: Proxy deaktivieren und direkt verbinden, dann erneut versuchen.
  • Das Lese-Timeout des Clients muss länger sein als die Generierungszeit des Modells; bei langen Ausgaben das Timeout erhöhen.
  • overloaded_error aus dem error-Ereignis empfangen: einige Sekunden warten und erneut versuchen, siehe Fehlercodes und Fehlersuche.

Ein in der Mitte abgebrochener Request ist nicht kostenlos, abgerechnet werden die bis zum Abbruch bereits generierten Output-Token, protokolliert im Aufruf-Log. Die abgerechnete Ausgabe kann etwas größer sein als das, was der Client tatsächlich erhalten hat. Am 2026-10-15 getestet: Das Modell sollte von 1 bis 600 zählen, der Client brach nach 4 Sekunden ab und erhielt 188 Zeilen (ca. 380 Output-Token), im Aufruf-Log standen 750 Token. Bei unerwünschten langen Ausgaben ist es besser, von Anfang an max_tokens klein zu setzen, statt den Stream in der Mitte abzubrechen.