← PC・IT用語集へ戻る

ストリーミング応答

Streaming Response
生成AIの出力を、全文の完成を待たずに少しずつ受け取る方式。
ストリーミング応答 (Streaming Response)

概要(サマリー)

ストリーミング応答とは、LLMの出力を、全文ができてからまとめて受け取るのではなく、できた断片から順に受け取る方式である。

チャット画面で文字が少しずつ増えていくのは、この方式であることが多い。OpenAIでは stream を有効にし、HTTPの Server-Sent Events で断片を受け取る。

待ち時間が短く感じられるだけで、消費するトークンが減るわけではない。全文の生成が終わるまで、応答は未完成である。

詳細解説

まとめて返す方式との違い

ストリーミングを切ると、APIは出力を最後まで作ってから、1つのHTTPレスポンスで返す。長い回答では、最初の文字が見えるまで時間がかかる。

ストリーミングを入れると、生成の途中経過が順に届く。利用者は、完了前に内容を読み始められる。アプリは、届いた断片を画面へ足していく。

OpenAIのResponses APIでは、断片に種類がある。文章の続きは response.output_text.delta、完了は response.completed、失敗は error のように分かれる。見たい種類だけを拾い、それ以外は無視できる。

stream = client.responses.create(
    model="使用するモデル名",
    input="この関数が何をするか、3行で説明してください。",
    stream=True,
)

for event in stream:
    if event.type == "response.output_text.delta":
        print(event.delta, end="")

delta は、その時点で増えた差分である。前の断片とつなげて、初めて文章になる。

料金と上限は減らない

早く見え始めることと、安くなることは別である。出力トークンは、ストリーミングでも同じように数える。途中で画面を閉じても、サーバー側の生成が続く実装がある。不要になったら、アプリ側で接続を明示的に閉じる。閉じた時点までに生成された分が課金されるかどうかは、サービスの説明で確認する。

ツール呼び出しも、引数のJSONが断片で届くことがある。断片の時点ではJSONとして閉じていない。パースして実行するのは、引数が完成してからにする。

エラーの出るタイミング

リクエストが拒否されるエラーは、ストリームが始まる前にHTTPステータスで返ることがある。一方、生成が始まったあとの失敗は、ストリームの中のイベントとして届く。

始まる前の失敗は、同じ依頼を送り直せる場合がある。断片をすでに画面へ出したあとの失敗は、送り直すと二重に表示される。どこまで利用者へ見せたかを持ってから、再試行するかを決める。

検査が遅れる

OpenAIは、ストリーミングすると出力の検査が難しくなると説明している。断片だけでは、完成後に問題になる文面かを判断しにくい。OpenAIには、有害な表現かどうかを点数で返す検査(モデレーション)を生成と同時に頼む機能がある。ただし、その点数は全文ができてから届き、途中の断片には付かない。

公開アプリで、不適切な出力を出さないことが要件なら、断片を仮表示するか、完成後に検査してから確定表示するかを先に決める。仮表示した文字は、あとから消す処理も要る。

WebSocketとの違い

WebSocketは、ブラウザとサーバーが接続を保ったまま双方向にメッセージを送る通信方式である。ストリーミング応答は、「1回の生成結果を分割して届ける」という受け取り方である。

OpenAIは、通常のストリーミングを Server-Sent Events で説明し、接続を保って追加入力する用途には別のWebSocketモードがあると分けている。動画のストリーミング配信とも、言葉は似ているが対象が違う。こちらはモデルの文章出力の届け方である。

AIコーディングとの関係

エディタのチャットで提案が一行ずつ出るのは、完成を待たずに差分を描いているからである。生成が遅いモデルでも、最初の数行で方向が違えば、その時点で止められる。

止めずに最後まで待ってから差分へ適用する実装もある。途中の文章は、コードとしてまだ閉じていない。括弧や文字列が欠けた断片を、その場でファイルへ保存しない。

AIにストリーミング対応のコードを書かせるときは、完成イベントとエラーイベントの両方を指定する。「文字が出れば成功」と書くと、途中の切断を成功扱いしがちである。

よくある勘違い

ストリーミングにすると安い?

料金の計算が変わる方式ではない。最初の文字が早く見える。トークン数は、生成した量で数える。

WebSocketを使うということ?

一般的なHTTPストリーミングは、サーバーからクライアントへの一方向のイベントである。双方向のWebSocketとは別の方式として説明されている。

途中まで見えたら、その内容で確定?

断片は未完成である。あとから続く文で意味が変わり、エラーで止まることもある。確定した応答は、完了イベントのあとである。

動画配信のストリーミングと同じ?

言葉は共通でも、ここではモデルの出力トークンを順に届けるAPIの話である。映像の配信方式ではない。

まとめ

  • ストリーミング応答は、生成AIの出力を断片ごとに受け取る方式である
  • 体感の待ち時間は短くなるが、トークン料金が減るわけではない
  • 文章、完了、エラーは別のイベントとして届く
  • 途中の断片はJSONとしても文章としても未完成なことがある
  • 有害な出力の検査は、全文がそろってからでないと判定しにくい

情報ソース

より詳しくAIに聞いてみよう

  • ストリーミング応答を、手紙を書きながら渡すたとえで説明してください。
  • まとめて返す方式と、断片で返す方式の違いを整理してください。
  • ストリーミングしてもAPI料金が減らない理由を説明してください。
  • 途中で接続が切れたとき、画面に残った文章をどう扱うべきか教えてください。
  • AIに、完了とエラーを分けて受け取るストリーミング処理の骨格を書かせる指示文を作ってください。