ストリーミング応答はパフォーマンスの決定ではなくUXの決定だ
モデルの応答をストリーミングすることは速度の修正ではなく、最初のトークンまでの時間に関するユーザー体験の選択だ。構造化出力やツール使用ではむしろ悪化させることもある。

ストリーミングはモデルを速くしない。待ち時間を短く感じさせるだけだ。応答を生成する総時間は、ストリーミングしてもしなくてもほぼ同じだ。ストリーミングが変えるのは、ユーザーが最初のトークンを目にするタイミングであり、その一つの数値、最初のトークンまでの時間が、速さの体感全体を左右する。ストリーミングをUXの決定として扱うこと。実際そうなのだから。そうすれば、いつ使い、いつ積極的に害になるかについて、より良い判断ができるようになる。
反射的な反応としてInvokeModelWithResponseStreamやConverseStreamに手を伸ばしたくなる。ストリーミングが性能的な選択のように感じられるからだ。しかしモデルは、どちらの方法でも同じトークンを同じ総時間で生成する。あなたはスループットを最適化しているのではない。人間が6秒間白い画面を見つめるか、300ミリ秒後にテキストが現れるのを見るかを決めているだけだ。
なぜ最初のトークンまでの時間が重要な数値なのか
ストリーミングしない応答には、ユーザーが体感するレイテンシが一つしかない。最初から最後まで、生成全体だ。3段落を求めれば、ユーザーはそのすべてが表示されるまで待つ。総時間が問題なくても、その待ち時間はシステムが遅いと感じられる。
ストリーミングはそれを2つの数値に分割する。最初のトークンまでの時間は、何かが現れるまでの時間だ。その後、トークンは継続的に届き、人間はモデルが生成するよりゆっくり読むため、テキストは読者より先を行き続ける傾向にある。体感される体験は「即座で流れるような」ものになる。総生成時間は変わっていないにもかかわらずだ。これはプログレスバーと同じ心理学だ。動きは進捗として読み取られ、白い画面はハングとして読み取られる。人がプローズとして出力を読むような会話的な用途では、この理由だけでストリーミングはほぼ必須だ。
ストリーミングが静かに事態を悪化させる場所
ストリーミングはデフォルトであって法則ではない。いくつかのよくあるケースでは、完全な応答を待つほうがうまくいく。
クライアントがパースしなければならない構造化出力
応答がフロントエンドがデシリアライズするJSONなら、部分的なストリームは無用か、むしろ有害だ。JSONオブジェクトの半分をパースすることはできないし、半分構築された構造をユーザーに見せるのは、スピナーを見せるよりも悪い。出力の消費者が読者ではなくコードである場合は、全体を待ってから一度でパースすること。ストリーミングは何のメリットももたらさず、不正な部分的状態をレンダリングするリスクだけを追加する。
エージェント内でのツール使用
モデルがツールを呼び出す決定をストリーミングするとき、ユーザーが読むべきものは何もない。「出力」はプローズではなくツールの呼び出しだからだ。関数呼び出しのトークンをUIにストリーミングすると、ユーザーが見たいとも思っていなかった内部機構を見せてしまう。正しいパターンは、最終的なユーザー向けの答えをストリーミングし、中間のツール呼び出しの推論は画面に出さないか、生のストリーミングトークンとしてではなく「注文を確認しています」のようなステータスとして表現することだ。
短い応答
答えが一文であれば、ストリーミングは知覚できるメリットもなくプロトコルの複雑さを追加するだけだ。どちらの方法でも全体が数百ミリ秒で届く。ストリーミングの配管は、待ち時間が体感されるほど長い応答のために取っておくべきだ。
ストリーミングを選ぶことで背負うコスト
ストリーミングはタダで手に入るエンジニアリングではない。その間ずっと接続を開いたままにする必要があり、タイムアウト、リトライ、ロードバランシングの考え方を変えなければならない。エラーハンドリングも難しくなる。ストリームの途中での失敗は、検出して回復しなければならない切り詰められた答えをユーザーに残す。バッファリングされた呼び出しでのきれいなオールオアナッシングの失敗とは違う。そして、すでにトークンごとにユーザーに見せてしまった応答に対しては、Guardrailsの出力チェックやJSON検証を実行できない。検証が重要なら、バッファリングするか、ストリーミングしながら検証して撤回する準備をしておく必要があり、これは本物の手間だ。ストリーミングが厳密に優れていると仮定するのではなく、UX上の利得と天秤にかけること。
数値そのものを下げる、という選択肢もある
問題が本当に最初のトークンが出るまで時間がかかりすぎることなら、ストリーミングはそれを隠すだけで修正はしない。プロンプトキャッシュは修正する。長いプロンプトの安定した接頭辞をキャッシュすると、生成が始まる前の時間が直接短くなり、最初のトークンまでの時間を直接下げる。重厚にプロンプトされたエージェントでは、プロンプトを刈り込んでキャッシュすることが、ストリーミングよりも体感速度に効くことがあり、しかもストリーミングしないケースや構造化されたケースにも役立つ。
結論
ストリーミングはモデルの実行速度を変えない。最初のトークンまでの時間を変え、それがシステムの体感速度を変える。だからこれはUXの決定だ。人間が読んでいる会話的なプローズはストリーミングする。クライアントがパースしなければならない構造化出力、生のツール呼び出しの推論、一行の回答はストリーミングしない。そして最初のトークンのレイテンシが本当の不満点であるときは、ストリーミングでごまかすのではなく、プロンプトをキャッシュして数値そのものを下げること。
次に読む
- Bedrock Agents vs Rolling Your Own Loop。中間ステップをストリーミングすることが助けよりも害になる、ツール使用ループについて。
- Stop Fine-Tuning. You Need RAG, a Cache, and Better Prompts。最初のトークンのレイテンシを実際に下げる方法としてのプロンプトキャッシュについて。
長時間持続する接続とエッジでのレイテンシの背後にあるインフラについては、クラウドのフィールドノートがercan.cloudにあり、ハブはercanermis.comにある。
Ercan の他のサイト
同じ著者、別の領域のサイトが2つ。