3行でいうと

  • ストリーミングは、標準の「サーバー送信イベント(SSE)」で届きます。HTTPの状態が200で始まったあとにも、ストリームの中でエラーが届くことがあります。Anthropicのエラーの文書は、この場合のエラー処理は通常の仕組みに従わない、と書いています(HTTPエラー処理やSDKの再試行を名指ししてはいません)。
  • 「切れたあとの再開」の作りは、3社で違います。Anthropicは、受け取った分を自分で保存して、続きを頼む形です。OpenAIは、バックグラウンド実行にして、イベントの番号から再開できます。Googleの新しいInteractions APIは、最後のイベントの番号を渡して再開する例があります。
  • タイムアウトは、一つの数字ではありません。Anthropicの公式SDKは、既定で10分、再試行は2回。ほかに、接続の待ち時間、読み取りの待ち時間を分けて決められます。何を何秒にするかは、公式は決めておらず、設計する側が決めます。

この記事は、公式の文書を読んでまとめたもので、実際に使って確かめた記録ではありません。数字や仕様は2026年10月22日に確認しました。変わることがあります。

先に結論

前提:ストリーミングは何を運んでいるか

ふつうのAPIは、生成が終わってから、返事を丸ごと返します。ストリーミングは、できあがった分を細かく、順に送ります。多くのAIのAPIは、これにSSE(サーバー送信イベント)を使います。SSEはHTML標準の文書(WHATWG)に決まりがあり、サーバーからの一方向の送信を、text/event-streamという種類のHTTP応答で行います。

標準の文書の要点は次のとおりです。

注意が要るのは、これは標準が受け取る側に求める決まりだ、という点です。AIのAPIを、自分のサーバーのコードから呼ぶときは、各社のSDKや自作のコードが、この決まりのどこまでを実装するかは別です。たとえばAnthropicの文書が説明する再開は、あとで述べる「続きを頼む」方式で、Last-Event-IDは出てきません。

3社のストリーミングの比べ方

Anthropic(Messages API) OpenAI(Responses API) Google(Gemini API)
有効にする リクエストに"stream": true stream: true SDKでstreamをtrue。RESTは、URLにalt=sseを付けて本体でstreamをtrue(読んだのはInteractions APIの例)
イベントの構造 message_start、各ブロックのcontent_block_start/content_block_delta/content_block_stop、message_delta、message_stop response.created、response.output_text.delta(繰り返し)、response.completed、error interaction.createdから、番号つきの「ステップ」(開始・差分・終了)、interaction.completed(RESTの例では最後にdone)
無通信の確認 pingイベントが、いつでも入りうる。内容はなく無視してよい 読んだ範囲では記載なし 読んだ範囲では記載なし
途中のエラー ストリーム内にerrorイベント(例:過負荷のoverloaded_error。通常の応答ではHTTP 529に当たる) errorイベント errorイベント
未知のイベント 新しい種類が足されうるので、知らないイベントは扱いを決めておく 読んだ範囲では記載なし 知らない種類は、記録して読み飛ばす
ツール呼び出しの引数 input_json_deltaで、JSONの断片が届く。連結して、ブロックの終了で解析 イベントの種類(引数の差分と完了)は載っているが、扱い方は別のガイドとされ、読んでいない 引数が断片で届き、連結してから解析
再開の方法 受け取った分を保存し、続きを新しいリクエストで頼む background: trueとstream: trueを併用し、sequence_numberを目印にstarting_afterで再開 最後のイベントの番号を付けて、同じ「interaction」を再び要求する例がある

Anthropic

公式文書によると、通常の流れは次のとおりです。message_startのあと、内容のブロックごとに、開始、1つ以上の差分、終了のイベントが来ます。message_deltaにはstop_reasonなど全体の変化が入ります。最後にmessage_stopが来ます。

差分には種類があり、文字はtext_delta、ツールの引数はinput_json_delta(JSONの断片)、思考はthinking_delta、思考の完全性を確かめる署名はsignature_deltaです。ツールの引数は、断片をつなげて、そのブロックのcontent_block_stopを受け取ってから解析します。文書によると、現行のモデルは、キーと値の1組を完成させてから出すので、イベントの間に間が空くことがあります。

SDKを使うと、イベントを自分で組み立てずに、最終のMessageを受け取れます。公式の例は次のとおりです(この記事では実行していません)。

with client.messages.stream(
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello"}],
    model="claude-opus-5-5",
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

エラーからの回復について、同じ文書は次のように説明しています。Claude 4.5以前では、受け取れた分を保存し、それを助手の発言の書き出しとして含めた新しいリクエストを送って続きを受け取ります。Claude 4.6以降では、助手の書き出しではなく、利用者の発言として「前の返事は途中で中断された。ここまでが前の返事。続きから出して」という趣旨の文を、受け取れた分と一緒に送ります。ツールの呼び出しと思考のブロックは、途中から回復できないので、直近の文のブロックから再開します。

OpenAI

Responses APIの文書によると、stream: trueで、型のあるイベントが届きます。文書は、ストリーミングでは途中の文章を審査しにくい、と注意しています。審査のスコアを一緒に求めても、生成が全部終わってから届き、途中の差分には付かない、とも書かれています。

再開については、別のバックグラウンド実行の文書にあります。background: trueで長い処理を非同期にできます。ストリームも使うときは、backgroundとstreamの両方をtrueにし、各イベントのsequence_numberを覚えておけば、切れたときにstarting_afterで再開できます。ただし、再開できるのは、最初からstream=trueで作ったバックグラウンドの応答だけです。ストリームを使わず、状態を定期的に問い合わせる使い方もでき、取り消しの窓口もあります。最初の文字が出るまでの時間は、同期より長い、と書かれています。

Google(Gemini)

読んだ範囲では、Geminiのテキスト生成の文書のストリーミングの節は、Interactions APIの例でした。step.deltaというイベントに文字が入ります。ストリーミングの案内ページでは、ツールの引数は断片で届き、連結してから解析すること、ツールの実行が必要なときはrequires_actionの状態で終わり、結果を付けて次のリクエストを送ること、が書かれています。

「途中で終わる」3つのパターンと、見るもの

見立てです。公式の記述を、切れ方で並べ直しました。

切れ方 兆し 公式が書いていること
1. 接続が切れる・時間切れ 通信の例外、無通信、504 Anthropic:HTTP 504(timeout_error)が時間切れのエラー。長い処理(とくに10分超)には、ストリーミングかバッチを検討する
2. ストリームの中のエラー errorイベント 200を返したあとでも起きる。エラー処理は通常の仕組みに従わない(SDKの再試行が効くかは、原文に明記なし)
3. 完了のイベントが来ないまま終わる message_stop、response.completed、interaction.completedが無い 各社の文書にある完了のイベント。これが無いまま終わったら、「途中で終わった」と扱うのが無難(これは僕らの見立て)

公式の文書は、message_deltaにstop_reasonなどの全体の変化が入る、と書いています。完了の理由の一覧は、今回読んだストリーミングのページには見つからなかったので、使うモデルの文書で確認してください。

タイムアウトの考え方(見立て)

公式の数字を材料に、層に分けて考えます。

見立てです。無音の長さで止める場合は、モデルが長く考える場面や、ツールの引数が大きい場面で、誤って止めないように、余裕を持たせる必要があります。数字は、自分の使うモデルと用途で測って決めるしかありません。

公式の数値と上限の一覧(2026年10月22日に確認)
項目 内容 出どころ
Anthropic SDKの既定のタイムアウト 10分。クライアント全体でも、リクエストごとでも変更できる Anthropic Python SDKの文書
非ストリーミングの事前チェック 約10分を超えると見込まれるとValueError。stream=Trueかtimeoutの明示で回避 同上
再試行 既定2回。接続エラー、408、409、429、500以上。max_retriesで変更、0で無効 同上、エラー文書
TCPキープアライブ SDKは既定で有効 同上
リクエストの大きさ Messages APIとToken Counting APIは32MB、Batch APIは256MB、Files APIは500MB。超えると413 Anthropicのエラー文書
主なHTTPエラー 504(timeout_error)、529(overloaded_error)、429(rate_limit_error。SDKの再試行の対象)。一覧には、400、401、402、403、404、409、413、429、500、504、529がある 同上
リクエストID 応答のrequest-idヘッダーと、エラーの本文のrequest_id。問い合わせのときに伝える 同上
OpenAIのバックグラウンド応答 プロジェクトの設定によっては、約10分だけ一時的に保存、または約10分後に削除される(条件は原文を確認) OpenAIのバックグラウンドの文書
SSEのコメントの間隔 約15秒ごとが、標準の文書にある書き手への提案 WHATWGのSSE

文書にあった、Anthropicの公式SDKの再試行の対象は、上の表のとおりです。ストリームの途中のエラーが含まれるかは、原文に明記がなく確認できていません。

よくある失敗・つまずき

気をつけること

出典

更新履歴