
AI機能のレスポンスが遅い|ストリーミングで体感速度を上げる
「あのAIの機能、ちょっと遅くないですか」
会議の終わり際にそう言われて、その場では「そうですね、見てみます」と返したものの、席に戻ってから途方に暮れた——そんな経験はありませんか。
自分でも薄々わかっていたことです。ボタンを押すと、画面にはくるくる回る印だけが出て、何も起きない時間が続く。実際に測れば十数秒かもしれませんが、待っている側の十数秒は、思っているよりずっと長い。そして厄介なことに、この遅さの多くは自分たちのコードのせいではありません。AIに文章を書かせている以上、書き終わるまで時間がかかるのは当たり前だからです。
だからといって「そういうものなので」とは言いにくい。ここが、AI機能を組み込んだ人がだいたい一度は立ち止まるところです。
結論:やることは2種類に分かれます。「速くする」と「速く感じてもらう」は別の仕事で、先に効くのはたいてい後者です。順番はこう。①まず測って、待ち時間を「最初の一文字が出るまで」と「全部出終わるまで」に分ける。この2つを混ぜて話している限り、打ち手は決まりません。②ストリーミング(書けたところから少しずつ画面に流す)で、最初の一文字を早く出す。合計時間は変わらなくても、無言の時間が消えるだけで体感はまるで違います。③手前のプロキシやロードバランサのバッファを外す。ここを見落とすと、ストリーミングにしたのに結局まとめて届きます。④それでも長い処理は、待たせずに逃がす——先に出せる部分を出す、あるいは非同期にして後で知らせる。そして⑤出力を短くする・モデルを使い分ける・キャッシュを効かせるという「本当に速くする」打ち手は、この後で十分間に合います。
一度に全部やらなくて大丈夫です。 今日は「最初の一文字までに何秒かかっているか」を1回測るだけでも、話がずいぶん進みます。
何が起きているのか——「遅い」の中身は3つに分かれる

まず、いま何が起きているのかを整理させてください。「AIが遅い」とひとことで言っても、中身は分けられます。
- 順番待ちと通信の時間:混み合う時間帯に呼び出しが並ぶ、ネットワークを往復する。ここは自分たちで縮めにくい部分です。
- 入力を読む時間:長いシステムプロンプトや、資料を丸ごと添付している場合にじわじわ効きます。
- 出力を書く時間:これが本命です。AIは文章を先頭から順番に組み立てていくので、出力が長いほど、そのぶん素直に時間が伸びます。1000字の回答は、100字の回答よりだいたい素直に長くかかります。
つまり、AI機能の遅さの主な正体は「長い文章を書かせていること」です。ここが普通のAPIと違うところで、データベースを速くしても、サーバーを増やしても、この部分は縮みません。
そしてもうひとつ。最近よく使われるじっくり考えてから答えるタイプのモデルでは、答えを出す前の思考の分だけ、画面に何も出ない時間がさらに伸びます。品質は上がるのですが、体感の面では逆に働くことがある——この性質は知っておくと、モデル選びのときに迷いません。
ここで大事なのは、利用者が「遅い」と言うとき、たいてい見ているのは合計時間ではなく、何も起きない時間の長さだということです。
- 押してから3秒で文字が出始めて、20秒かけて書き終わる。
- 押してから15秒何も起きず、その後まとめて全部出る。
合計は前者のほうが長いのに、多くの人は前者を「速い」と感じます。人は、動いているものは待てて、止まっているものは待てない。ここに、いちばん効く打ち手があります。
① まず測る——待ち時間を2つに分ける
打ち手を選ぶ前に、1回だけ測ります。難しい計測基盤は要りません。ログに2つの時刻を足すだけです。
- 最初の一文字が返ってくるまでの時間:呼び出してから、最初のかけら(トークン。文章を細かく区切った単位)が届くまで。英語圏ではTTFTと呼ばれる指標です。
- 全部出終わるまでの時間:最後まで受け取り終わるまで。
この2つを分けて記録すると、話が急に具体的になります。
- 最初の一文字までが長い → 順番待ち、入力が長い、思考の時間が長いモデル、あるいはそもそもストリーミングしていない。
- 最初の一文字までは短いのに全体が長い → 出力が長い。短くさせる余地があります。
あわせて、平均だけを見ないことをおすすめします。平均は速そうに見えるのに、10回に1回だけ極端に遅い——という形はよくあります。文句を言われるのは、その1回です。何をログに残しておくかはAI機能の効果測定|導入後に見るログと指標の設計に整理しています。
測ったうえで「思ったより速かった」と分かることもあります。 その場合、問題は速度ではなく見せ方や期待値のほうにあります。それも立派な収穫です。
② ストリーミングで、最初の一文字を早く出す
いちばん効いて、いちばん手数が少ないのがこれです。書き終わるのを待ってから返すのをやめて、書けたところから順に画面へ流す。多くのAI提供元が最初から用意している機能で、呼び出しに指定を足すだけで有効になります。
画面側は、サーバーから少しずつ届くデータを受け取り、そのつど表示に足していく作りにします。伝え方はいくつかありますが、素直なのはサーバーから一方向に少しずつ送る仕組み(Server-Sent Events)か、チャンク転送(レスポンスを小分けにして送り続ける形)です。特別なライブラリがなくても組めます。
そのうえで、現場でつまずきやすい点を先に挙げておきます。どれも、知っていれば避けられるものです。
途中で詰まる場所を外す(ここが最頻出)
「ストリーミングにしたのに、結局まとめてドンと届く」——これは本当によくあります。悪いのはコードではなく、手前にいる誰かです。
- リバースプロキシ・ロードバランサ:応答をいったん溜めてから流す設定になっていると、小分けの意味が消えます。nginxなら応答のバッファリングを切る、あるいはアプリ側から「ここは溜めないで」と伝えるヘッダを返す形が一般的です。
- 圧縮:応答をまとめて圧縮する設定だと、圧縮のために溜め込まれます。
- CDN・WAF・APIゲートウェイ:構成によっては、そもそも小分け転送に対応していない経路があります。
- タイムアウト:長い応答の途中で切られると、利用者からは「途中で止まった」に見えます。読み取り側のタイムアウトを、想定する最長の応答に合わせて見直します。
この4つは、必ず使っている製品・サービスの公式ドキュメントで、いまの仕様を確認してください。 設定名も対応状況も更新が入る部分なので、記憶や過去の記事で決めないほうが安全です。
見分け方は簡単です。サーバー側のログでは細かく送っているのに、画面には一度に出るなら、間に溜めている誰かがいます。
途中で止められるようにしておく
ストリーミングにすると、利用者が「これじゃない」と気づくのが早くなります。だからこそ、止めるボタンを用意しておきたい。
そして画面を閉じただけでは、裏側の生成は止まりません。止める操作を受けたら、サーバー側からAIへの呼び出しもちゃんと打ち切るようにします。ここを省くと、誰も読まない文章のために料金を払い続けることになります。費用の見積もり方はAI APIの料金とレート制限を見積もる|本番前の型にまとめました。
途中で失敗したときの見せ方を決めておく
一括で返す作りなら、失敗は「エラー画面を出す」で済みました。ストリーミングでは、半分書けたところで途切れることが起こります。
- 途中で切れたと利用者に分かるようにする(「応答が途中で終わりました」の一行と、やり直すボタン)。
- 途中までの文章を保存したり、後続処理に渡したりしない。半端な文章が業務データに入るほうが、失敗より厄介です。
- やり直しの動きは先に決めておく。この考え方はAI出力が不安定なときのフォールバック設計|リトライの型がそのまま使えます。
ストリーミングが向かない場面もある
正直に書きます。ストリーミングは万能ではありません。次の場合は、無理に入れないほうが素直です。
- 出力を検証してから使う機能:AIにJSONなどの決まった形で出させて、中身を確かめてから画面や台帳に反映する作り。途中まで届いた時点では形が成立していないので、確かめようがありません。この場合は完成を待つのが正しい。形式を安定させる話はAIの構造化出力(JSON)を安定させる|崩れたときの復旧まで、書き戻す前の確認はAI出力を業務データに書き戻す前のバリデーション設計|守る順番に分けて整理しています。
- 人が読む前に加工が必要なもの:翻訳結果を並べ替える、要約を分類に使うなど、全部そろってから処理するもの。
- そもそも出力が短い機能:2〜3行しか返さないなら、ストリーミングにしても体感はほとんど変わりません。手間のわりに効きません。
- バッチ処理・裏側の処理:見ている人がいないので、体感速度という概念がありません。
「人が読む長い文章か」——これが判断の分かれ目です。当てはまらないなら、次の節の打ち手に進んでください。
③ 待たせ方を変える——出せるものから出す
ストリーミングが使えない、あるいは使ってもまだ長い。そのときは、待ち時間そのものの設計に手を入れます。
- 先に出せるものを先に出す:検索して答える作りなら、参照した資料の一覧はAIの回答より先に確定していることが多いはずです。先に出しておけば、その間、利用者は読むものがあります。
- いま何をしているかを見せる:「資料を探しています」「回答をまとめています」と段階が変わるだけで、止まっていない感じが伝わります。中身のない進捗バーより、具体的な一言のほうが効きます。
- 押した瞬間に反応を返す:ボタンを押した直後にボタンの見た目が変わる、入力欄が確定する。この0.1秒の反応があるかどうかで、印象は変わります。
- 本当に長い処理は、待たせない:数分かかる処理なら、その場で待たせるのをやめる。受け付けだけして、終わったら通知や画面の更新で知らせる形にします。利用者は待つ必要がなくなり、こちらもタイムアウトと戦わずに済みます。
最後の「非同期に逃がす」は、実装は増えますが効果がいちばん確実です。会議で「どうしても3分かかります」と説明するより、「押したら他の作業に戻れます」と言えるほうが、受け入れられやすいものです。
④ 本当に速くする打ち手
体感の手当てをしたうえで、実時間も縮めていきます。効く順に並べます。
- 出力を短くする:いちばん素直に効きます。「簡潔に」「箇条書きで5つまで」と指示する、出力の最大長を設定する。長い前置きや言い訳を書かせないだけでも変わります。頼み方そのものはAIにコードを書かせる前に渡す前提と制約|伝え方の型の考え方が流用できます。
- 同じ問い合わせを繰り返していないか見る:当たれば呼び出しごと消えるので、速度への効果は最大です。効かせ所の見極めはAI応答のキャッシュでコストと速度を改善|効かせ所の見極めに分けて書きました。
- 用途でモデルを使い分ける:分類やタグづけのような軽い仕事に、いちばん賢いモデルを使う必要はありません。画面から呼ぶものは軽いモデル、裏でじっくり動くものは賢いモデル、という分け方は素直に効きます。差し替えを前提にした作りはAIモデル・ベンダーの乗り換えに備える設計|疎結合の作り方を参考にしてください。
- 入力を削る:毎回同じ長い資料を丸ごと送っていないか。必要な部分だけ渡す形にできないか。
- 独立した呼び出しは同時に投げる:3つの分析を順番に行っているなら、同時に投げれば待ち時間は1つ分に近づきます。ただし呼び出し回数の上限には気をつけてください。
- 先に用意しておく:画面を開いた時点で結果が想像できるものは、押される前に取りに行っておく手もあります。使われなかった分が無駄になるので、効くところを選んで。
1と2だけで足りることが、かなりあります。 3以降は、測って必要と分かってからで十分です。
つまずきやすいところ
先に知っておくと避けられるものを挙げます。どれも普通に踏むところで、責める意図はまったくありません。
- ストリーミングにしたのにまとめて届く:手前のバッファリングか圧縮です。まずここを疑います。
- 止めても料金がかかり続ける:画面を閉じただけでは裏の生成は止まりません。サーバー側の打ち切りを忘れずに。
- 半端な文章が保存されている:途中で切れた応答を、正常な結果として扱ってしまう形。分岐を明示的に書いておきます。
- タイムアウトに引っかかる:長い応答を想定していない設定のまま。手前の経路すべてを確認します。
- 平均だけ見て「速い」と結論する:文句が出るのは、遅かった1回です。
- 全部の機能に一律でストリーミングを入れる:短い応答や検証が要る機能では、手間だけ増えて効きません。
- 速くしたのに伝わっていない:改善したら、ひとこと共有する。伝え方は「で、効果あったの?」AI活用の成果を数字で報告するコツが使えます。
明日からやること(まずこの3つ)
大がかりな改修は要りません。この順番で大丈夫です。
- 最初の一文字までの時間と、全部出終わるまでの時間を測る(30分):いちばん遅いと言われている画面ひとつで構いません。2つに分けるだけで、次の打ち手が自分で決まります。
- その画面がストリーミングに向いているか、1問だけ確かめる:「人が読む長い文章か」。はいなら、ストリーミングを入れて、手前のバッファを外して、止めるボタンを付ける。いいえなら、段階表示か非同期化へ。
- 出力の長さに上限をかけてみる:指示に「簡潔に」を足す、最大長を設定する。1行の変更で数秒縮むことがあります。 品質が落ちていないかだけ、一緒に確かめてください。
一度で全部そろえなくて大丈夫です。 今日「最初の一文字まで8秒かかっている」と分かったなら、それはもう改善の入口です。 数字がひとつあるだけで、次の会議の空気は変わります。
AI機能の体感速度チェックリスト
手を入れる前と、入れた後にさっと確認します。全部に○が要るわけではなく、気になる所だけで十分です。
測る
- 最初の一文字が返るまでの時間を記録しているか
- 全部出終わるまでの時間を記録しているか
- 平均だけでなく、遅かったほうの回も見ているか
- 機能ごと・画面ごとに分けて見られるか
ストリーミングを入れる前の見極め
- 人が読む、ある程度の長さの文章を返す機能か
- 出力を検証してから使う機能ではないか(そちらは完成を待つ)
- 入れるだけの効果がある長さか(数行なら見送ってよい)
ストリーミングの実装
- 手前のプロキシ・ロードバランサのバッファリングを外したか
- 圧縮設定で溜め込まれていないか
- 経路のタイムアウトを、想定する最長の応答に合わせたか
- 途中で止めるボタンがあるか
- 止めたとき、サーバー側からAIへの呼び出しも打ち切っているか
- 途中で切れたことが利用者に分かるか
- 途中までの文章を保存・後続処理に渡していないか
待たせ方
- 先に確定するもの(参照資料など)を先に出しているか
- いま何をしているかが分かる表示があるか
- 押した瞬間の反応があるか
- 数分かかる処理を、その場で待たせていないか
実時間を縮める
- 出力の長さに上限や指示をかけたか
- 同じ問い合わせの繰り返しがないか確認したか
- 用途に対してモデルが過剰でないか見直したか
- 毎回送っている入力に、削れる部分がないか
- 独立した呼び出しを順番に投げていないか
この記事のまとめ
「遅い」と言われたのは、あなたの実装が下手だったからではありません。AIに長い文章を書かせている以上、時間がかかるのは仕組みとして自然なことで、まだそこに手当てをしていなかっただけです。
やることは、地味です。待ち時間を2つに分けて測る。人が読む長文ならストリーミングにする。手前のバッファを外す。出力を短くする。 難しい高速化の工夫は、それが必要だと数字で分かってからで、十分に間に合います。
そして覚えておきたいのは、速度の問題の半分は、見せ方の問題だということです。同じ20秒でも、何も起きない20秒と、文字が流れている20秒はまったく違う。技術で殴らなくても変えられる部分が、思っているより残っています。

「AIを活用しろ」と言われる側にいると、新しい機能を足すことばかりが求められがちです。でも、すでに作った機能を少し待ちやすくする——この地味な仕事は、使う人にいちばん早く届きます。
今日、遅いと言われた画面をひとつ開いて時間を測ったなら、それだけで前に進んでいます。数字が思ったより速かったとしても、「速度ではなかった」と分かったこと自体が収穫です。次にどこを見ればいいかが、ひとつ絞れました。