コンテンツへスキップ
日本語

ストリーミング出力

1折AIでのストリーミング出力:AnthropicネイティブのSSEイベントシーケンス、OpenAI互換のchunk形式、および切断時の対処。

長い回答にはストリーミング出力("stream": true)を使います。最初の文字がより早く表示され、単一リクエストの時間が長すぎるために中間ネットワークから切断されるリスクも低くなります。両方のプロトコルに対応しており、形式はそれぞれ公式と一致しています。

リクエストに"stream": trueを追加すると、Server-Sent Eventsが返されます。正常なストリームは次の順序になります(Anthropic Streamingドキュメントより):

イベント意味
message_startメッセージの開始。モデルと初期のusageを含む
content_block_startコンテンツブロックの開始(テキスト、thinking、tool_use)
content_block_deltaコンテンツの増分。テキストはdelta.textにある
content_block_stopこのコンテンツブロックの終了
message_deltaメッセージレベルの更新。stop_reasonと最終的な出力トークン数を含む
message_stopメッセージ全体の終了

途中にpingイベントが挟まる場合があり、無視できます。エラー時にはerrorイベントが届きます。

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":"从一数到五"}]}'

SDKを使う場合はイベントを自分でパースする必要はありません。Anthropic SDKのストリーミング例を参照してください。

/v1/chat/completionsに"stream": trueを追加すると、data: {...}形式のchunkが返され、テキストはchoices[0].delta.contentにあり、最後はdata: [DONE]で終了します。SDKの例はOpenAI SDKを参照してください。

[DONE]の前の最後のchunkにはusageが付き、choicesは空配列です。stream_options.include_usageを渡さなくても返されます。2026-10-15に実測した完全なストリーム:

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]

chunkを処理する際は、まずchoicesが空かどうかを判断してください。上記のOpenAI SDKページの例はすでにそのように書かれています。

  • まずプロキシかどうかを確認します:プロキシをオフにして直接接続して再試行します。
  • クライアントの読み取りタイムアウトはモデルの生成時間より長くしてください。長い出力の場合はタイムアウト設定を増やします。
  • errorイベント内のoverloaded_errorを受け取ったら、数秒待って再試行します。エラーコードとトラブルシューティングを参照してください。

途中で切断されたリクエストが丸ごと無料になるわけではなく、切断前に生成された出力トークンに基づいて課金され、呼び出しログに記録されます。課金される出力は、クライアントが実際に受け取ったものより少し多くなる場合があります。2026-10-15に実測したところ、モデルに1から600まで数えさせ、クライアントが4秒目で切断した場合、188行(約300個の出力トークン)を受け取りましたが、呼び出しログに記録された出力は750トークンでした。不要な長い出力は、途中で切断されるくらいなら、最初からmax_tokensを小さく設定する方が良いでしょう。