AI API Streaming:SSEとTimeout
ChatとResponsesのEvent、SSE Parsing、最初の有効出力、段階別Timeout、499 Cancellationを解説します。
AI APIのStreamingは、完全なResponse Bodyを待たず、モデル生成中にEventを順次届けます。体感応答は改善しますが、モデル自体のLatencyが必ず短くなるわけではなく、クライアントはEndpointに合うProtocolを正しく解析する必要があります。
Chat CompletionsはCompletion Chunk、Responsesは型付きResponse Eventを送ります。期待する形式が違えば、HTTP 200でも画面に何も出ないことがあります。
Bufferingなしで確認する
curl -N -sS https://modelflare.dev/v1/responses \
-H "Authorization: Bearer $MODELFLARE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"YOUR_RESPONSES_MODEL","input":"Explain SSE.","stream":true}'
同じRequestを最初にStreamingなしで試すと、入力検証とStream Parserの問題を分離できます。モデルIDはモデルと料金から選びます。
SSEをProtocolとして扱う
Server-Sent Eventsは境界を持つRecordであり、任意のJSON断片ではありません。本番ClientではHTTP Library、Proxy、UIのBufferingを避け、分割Readを完全なEventまで蓄積し、Text、Reasoning、Tool、Completion、Errorを処理します。Cancellationと最終Usageを保持し、Terminal Event後は接続を閉じます。
遅延を段階別に測る
| 指標 | 意味 |
|---|---|
| 接続と認証 | Gatewayへ到達してKeyを検証するまで |
| Upstream Header | 選択経路が応答を開始するまで |
| 最初の有効出力 | 最初の有用なText、Reasoning、Tool Event |
| 最初の可視Text | ユーザーが実際に見られる最初の文字 |
| 総応答時間 | 完了、失敗、Cancellationまで |
Tool Callは可視Textより前に有効な出力となる場合があります。運用には最初の有効出力、UXには最初の可視Textも使います。
Timeoutを段階別に設計する
接続、HeaderまたはFirst Output、Stream Idle、全体Deadlineを分けます。ReasoningやToolのRequestは可視Textまで長く待つことがあります。短い全体Timeoutを一律適用せず、実測したWorkloadから設定します。
Client、Browser、Proxyが先に接続を閉じると、Modelflareは499を記録することがあります。これはDownstream Cancellationの証拠であり、ModelやChannelの失敗を単独では証明しません。Abort、Proxy Timeout、First Output、Model、Group、時刻を比較します。
文字が表示されないとき
- "stream": falseで同じRequestを送る。
- ModelがEndpointを支えるか確認する。
- UI変換前のRaw Eventを保存する。
- TextなしのToolまたはReasoning Eventを確認する。
- 中間層のBufferingを除外する。
- ParserがTerminal Eventを扱うか確認する。
- Status、Timing、Cancellationを記録で比較する。
非Streamingが成功しRaw Eventも届くなら、原因はParserかRenderingにあることが多いです。Event自体がなければAI APIエラーガイドへ進みます。形式選択はResponses APIとChat Completionsを参照してください。