SSEによるAIレイテンシの制御
AIのオートコンプリート機能を構築しましたが、ユーザーからは不評でした。
キー入力のたびにAIリクエストが発生し、ユーザーは完全なJSONレスポンスが返ってくるまで2〜3秒待たされることになりました。UIは壊れているように感じられました。デバウンス(debouncing)やキャッシュも試しましたが、効果はありませんでした。根本的な問題は変わっていませんでした。つまり、回答がすべて届くまでユーザーには何も表示されないということでした。
私は、Server-Sent Events (SSE) を使用してレスポンスを少しずつストリーミングすることで、この問題を解決しました。
以前のフローは以下の通りでした:
- ユーザーが入力
- 300msのデバウンス
- HTTP POSTリクエスト
- AIが処理 (1〜2秒)
- サーバーが完全なレスポンスを返却
- クライアントがレンダリング
ユーザーは何秒間も空白の画面を見つめることになります。ローディングスピナーを表示していても、遅く感じられました。
ポーリング(polling)やWebSocketsも検討しました。ポーリングはオーバーヘッドが大きすぎます。WebSocketsは、一方向のストリームには重すぎます。
SSEを選んだ理由は以下の通りです:
- サーバーからクライアントへの一方向通信である
- シンプルなテキストとJSONチャンクを使用する
- 接続が切れても自動的に再接続される
- サーバー側に追加のライブラリを必要としない
結果は劇的なものでした:
- 初回視覚的レスポンスまでの時間:2.1秒から0.3秒に短縮
- ユーザーエンゲージメント:40%向上
- ユーザーからの苦情:ゼロ
ストリーミングの本質は「知覚」にあります。プログレッシブなUIは、静的なUIよりも速く感じられます。ユーザーは、テキストの塊を待つよりも、言葉が一つずつ現れるのを見る方を好みます。
AIのレスポンスが非常に短い場合は、標準的なリクエストのままで構いません。双方向のやり取りが必要な場合は、WebSocketsを使用してください。しかし、ほとんどのAIストリーミングのニーズにおいて、SSEは最良の選択肢です。
あなたのアプリでは、AIのレイテンシをどのように処理していますか?ストリーミングを使用していますか、それとも完全なレスポンスを待っていますか?