OpenAIのWebRTC問題
(moq.dev)- WebRTCは会議通話のように低遅延を優先するため、ネットワークが悪いときには音声パケットを積極的に破棄するが、Voice AIでは遅い応答よりも音声プロンプトの損傷のほうが応答品質を大きく損なう可能性がある
- TTSはリアルタイムより速く音声を生成できるため、クライアント側のバッファリングで短いネットワーク障害を隠せるが、WebRTCは到着時刻基準のレンダリングと小さなジッタバッファのため、パケットを間に合うように送るために人工的に待機する必要がある
- WebRTCは一時ポート、ICE、DTLS、SCTPなどにより接続設定と運用が複雑で、単一ポート多重化ではSTUN、SRTP/SRTCP、DTLS、TURNパケットを各接続へルーティングしにくい
- OpenAIが高速な接続確立を求めても、WebRTCはシグナリングとメディアサーバーの手順を合わせると最低でも 8 RTT かかる可能性があり、P2P対応の構造のためサーバーが固定IPを持っていても同じ手順を踏まなければならない
- 代替として WebSockets と QUIC/WebTransport が挙げられ、QUICは
CONNECTION_ID、QUIC-LB、preferred_addressによって、単一ポート、アドレス変更、ステートレスなロードバランシング、anycastとunicastの組み合わせをよりシンプルにサポートする
WebRTCがVoice AIに向かない理由
- WebRTCは会議通話のような高速な往復会話に合わせて設計されており、ネットワーク状態が悪いときに 低遅延を維持するため音声パケットを積極的に破棄する
- Voice AIでは、ユーザーが少し遅い応答を待つとしても、プロンプトが正確に伝わることのほうが重要である
- たとえば「洗車場まで歩いて行くか運転して行くか」のような音声プロンプトが損傷すると、その後の応答品質も悪化しうる
- ブラウザのWebRTC音声実装はリアルタイム遅延を強く前提としており、Discordで試した際にはWebRTC音声パケットの再送は不可能だったという
- 更新として、一部のWebRTC関係者は音声NACKの有効化が可能かもしれないと見ていたが、Discordでは正しいSDP操作方法を見つけられず、WebRTCのジッタバッファが非常に小さいという制約も残る
- Voice AIエージェントがいつか会話レベルの遅延時間に到達したとしても、遅延削減には トレードオフ があり、音声プロンプトを意図的に劣化させる選択に価値があるかは不確かである
TTSとWebRTCのバッファリング問題
- テキスト音声変換(TTS)はリアルタイムより速く音声を生成できる
- たとえばGPUが2秒で8秒分の音声を生成するなら、理想的には生成中の2秒のあいだ音声をストリーミングし、クライアントは8秒かけて再生しながらローカルバッファを確保できる
- こうすれば短いネットワーク障害があっても、ユーザーが気付かない可能性がある
- WebRTCはこの方式と噛み合わない
- WebRTCは バッファリングを持たず、到着時刻基準でレンダリング し、タイムスタンプは強い再生基準にはならないとみなす
- ビデオまで含まれると問題はさらに厄介になる
- OpenAIのようなサービスは、各音声パケットの送信前に人工的に待機し、パケットが再生されるべき正確な時刻に到着するようにしなければならない
- ネットワーク輻輳が起きると、その音声パケットは失われ、再送されない
- 結果として、人工的な遅延を入れたうえで「低遅延」のためにパケットを積極的に破棄する構造になり、これはYouTube動画をバッファリングせず画面共有で見せるのに近い
- WebRTCは音声に対して20msから200msまで動的に調整されるジッタバッファを持つが、これはネットワークジッタを和らげるためのものであり、リアルタイムより速く送れるなら不要だと考えられる
ポートと接続識別の限界
- TCPサーバーは通常
443のようなポートを開いて接続を受け付け、接続は送信元・宛先IPとポートの組み合わせで識別される- 例:
123.45.67.89:54321 -> 192.168.1.2:443
- 例:
- 携帯電話がWiFiからセルラーに切り替わったり、NATが送信元IP・ポートを変更したりすると、TCP接続は切れて新しい接続を張り直す必要がある
- TCPとTLSのハンドシェイクには最低2〜3 RTTがかかり、ライブストリーミングではユーザーがネットワーク切断を感じる可能性がある
- WebRTCはこの問題を解くため、各接続ごとに一時的な宛先ポートを割り当てる方式を前提としている
- セッションを宛先IP・ポートだけで識別すれば、送信元IP・ポートが変わっても同じユーザーとして認識できる
- しかしOpenAIの構成と組み合わさると、この方式は大規模運用で問題になる
- サーバーが利用できるポート数には限りがある
- ファイアウォールは一時ポートを頻繁に遮断する
- Kubernetes環境とも相性がよくない
WebRTCサービスが単一ポート多重化へ向かう理由
- 多くのサービスはWebRTC仕様をそのまま使わず、複数の接続を 単一ポートに多重化 している
- TwitchではWebRTCサーバーを
UDP:443で運用していた- 本来
443はHTTPS/QUICのポートだが、こうすることでより多くのファイアウォールを通過できた - Amazon社内ネットワークではおよそ30個のポートしか許可されていなかったという
- 本来
- DiscordはCPUコアごとに1つ、
50000-50032のポートを使用している- この方式は、より多くの社内ネットワークで遮断されうる
- 単一ポート多重化の大きな問題は、WebRTCが複数の標準を束ねた構造だという点にある
- UDP上に直接載るプロトコルが5つあり、パケットがどのプロトコルかを見分けること自体は難しくないが、各パケットをどの接続へルーティングするかが難しい
-
プロトコルごとのルーティング上の難点
- STUN
- 固有の
ufragを選び、それを基準にルーティングできる
- 固有の
- SRTP/SRTCP
- ブラウザが任意の
ssrc値を選び、通常はそれに基づいてルーティングできる
- ブラウザが任意の
- DTLS
- RFC9146 の広範なサポートを期待しなければならない状況である
- TURN
- 実装経験はないと述べている
- OpenAIはSTUNだけをパースし、その後のDTLS、RTP、RTCPはキャッシュ済み状態を使って不透明に処理すると述べている
- これはユーザーの送信元IP・ポートが変わらないことを期待する構造だと解釈できる
- ブラウザが同じ
ssrcを偶然生成する可能性もある - 衝突が起き、送信元IP・ポートのマッピングもない場合、Discordは利用可能な各復号鍵でパケットの復号を試し、合う鍵を見つけることで接続を識別するとされる
- STUN
WebRTC接続確立の往復遅延
- OpenAIは「セッション開始直後からユーザーが話せる高速な接続確立」を要件の1つに挙げていたが、WebRTCの接続確立には最低でも 8 RTT かかると見ている
-
シグナリングサーバーの例
- WHIP のようなシグナリングサーバーを前提にすると、次の往復が必要になる
- TCPに1 RTT
- TLS 1.3に1 RTT
- HTTPに1 RTT
- WHIP のようなシグナリングサーバーを前提にすると、次の往復が必要になる
-
メディアサーバー
- ICEに1 RTT
- DTLS 1.2に2 RTT
- SCTPに2 RTT
- 一部のプロトコルではパイプライニングにより0.5 RTTを節約できるため厳密な計算は複雑だが、全体として多くの往復が必要になる
- この手順はWebRTCがP2Pをサポートしなければならないために生じるもので、サーバーが固定IPを持っていても同じ過程を踏まねばならない
- シグナリングサーバーとメディアサーバーが同じホストやプロセスで動く場合、重複して高コストなハンドシェイクが2回起きることになる
WebRTCをフォークする方向へ向かう構造
- WebRTCは多くの制約のため、事実上プロトコルのフォークを誘発すると見ている
- WebRTCは約45本のRFCと、TWCCやREMBのような事実上の標準ドラフトで構成されており、実装負荷が大きい
- ブラウザ実装はGoogleが主導しGoogle Meetに最適化されているため、会議アプリにとって存在論的な脅威だと見ている
- Google Meet以外の会議アプリがネイティブアプリのインストールを促す理由も、WebRTC利用を避けるためだと見ている
- DiscordはネイティブクライアントでWebRTCを大きくフォークしており、SDP、ICE、STUN、TURN、DTLS、SCTP、SRTPなどの大半を実装していないが、Webクライアント向けには依然として全体を実装しなければならない
- OpenAIも資金は十分あるだろうが、WebRTCをフォークするより、ブラウザ対応のある別方式に置き換えるほうがよいと見ている
代替案: WebSocketsとQUIC
- Voice AIでWebRTCの代わりに出発点となる代替案として WebSockets が挙げられる
- 既存のTCP/HTTPインフラを活用できる
- カスタムのWebRTCロードバランサーを作る必要がない
- Kubernetesと相性がよく、スケールしやすいと考えられる
- Head-of-line blockingはこの文脈では欠点ではなく、むしろ望ましいユーザー体験かもしれないと見ている
- 音声プロンプトの一部が欠けるより、順序どおりに届くほうがよいという前提である
- 将来、一部パケットのドロップや優先順位付けが必要になる段階が来たら、OpenAIはMoQのように WebTransport を活用すべきだとしている
- QUICの接続確立は QUIC+TLSで1 RTT で済み、WebRTCの多重ハンドシェイクよりシンプルである
QUIC Connection IDの利点
- QUICは送信元IP・ポートベースのルーティングを捨て、すべてのパケットに
CONNECTION_IDを含めるCONNECTION_IDは0〜20バイト長にできる- 重要なのは、この値を受信側が選ぶ点である
- QUICサーバーは各接続ごとに固有の
CONNECTION_IDを生成できる- 単一ポートを使いながら、送信元IP・ポートが変わった接続も識別できる
- 送信元アドレスが変わってもTCPのように接続を切らず、QUICが自動で新しいアドレスへ切り替える
- RFC9146 の発想はQUICから持ってきたものだと見ている
ステートレスなロードバランシング
- OpenAIのロードバランサーは、多くのロードバランサーと同様に 共有状態 に依存している
- 送信元IP・ポートからバックエンドサーバーへのマッピングを保存しなければならない
- ロードバランサーが再起動・クラッシュする可能性があるため、このマッピング保存先が必要になる
- OpenAIはRedisインスタンスを使って送信元IP・ポートとバックエンドサーバーのマッピングを保存している
- シンプルでわかりやすい方式と評価している
- QUIC-LB は、データベースなしでよりシンプルな方法を提供する
- クライアントがQUIC接続を開始すると、ロードバランサーがパケットを正常なバックエンドサーバーへ転送する
- バックエンドサーバーはハンドシェイク完了時に、自分のIDを
CONNECTION_IDにエンコードする - その後のすべてのQUICパケットにはバックエンドサーバーIDが含まれる
- ロードバランサーは暗号鍵やルーティングテーブルなしに、先頭数バイトをデコードして該当サーバーへ転送するだけでよい
- サーバーが再起動してもこの方式は維持できる
- ステートレスであることは、グローバル状態も不要だということを意味する
- ロードバランサーがグローバルanycastアドレスで受信し、示されたバックエンドサーバーへグローバルに転送できる
- Cloudflareはこれを広く使っているという
- AWS NLB はQUIC-LBを使うQUICロードバランシングを提供している
AnycastとUnicastの組み合わせ
- OpenAIのケースでは接続を地域ロードバランサーに割り当てる構造に見えるが、機能的には動作しても、よりよいアプローチとしてAnycastが挙げられる
- QUICの
preferred_addressはロードバランシングに重要な機能と評価されている -
動作方式
- 世界中の複数のバックエンドサーバーが同じanycastアドレス
1.2.3.4を広告する - クライアントが
1.2.3.4へ接続を試みると、インターネットルーターがパケットをいずれかのサーバーへ配送する - 各QUICサーバーは固有のunicastアドレス
5.6.7.8も持てる - anycastはハンドシェイクに使い、状態を持つ接続はunicastで維持する
- 世界中の複数のバックエンドサーバーが同じanycastアドレス
-
例の流れ
- サーバーは
1.2.3.4と5.6.7.8でQUICパケットを受信する - クライアントは
1.2.3.4にQUICハンドシェイクパケットを送る - サーバーはQUIC接続を作成し、
preferred_address=5.6.7.8を通知する - クライアントは以後のパケットを
5.6.7.8に送る - サーバーが過負荷で新規接続を受けたくない場合は、
1.2.3.4の広告をやめればよい - 既存接続はunicast側にあるため切断されない
- anycastアドレスは事実上ヘルスチェックのように機能する
- この構成では別個のロードバランサーは不要だと考えられる
- サーバーは
限界と結論
- OpenAIのエンジニアたちは非常に優秀で、直ちに大規模拡張しなければならない圧力を受けていることは認めている
- ただしVoice AIにおいてWebRTCは明白な選択肢に見えても、製品適合性が低く、スケーリングも難しいと見ている
- MoQもVoice AIに完全に適しているわけではない
- 1対1音声ではキャッシュやファンアウトの意味論の多くが役に立たない
- それでもQUICは使うべきだという結論である
1件のコメント
Hacker Newsの意見
全部読み切ったわけではないが、筆者はWebRTCの目的を根本的には理解していると思う。本人が専門家だと言っていて、Go/RustでSFUを複数の会社で作ってきたのも事実なのだろうが、技術的な経歴がそのまま結論の正当性を保証するわけではない
自分の読み違いかもしれないが、STUNとDTLSを往復時間の問題における相互に関連した累積要因のように扱っているように見える一方、実際にはかなり直交した要素だ。また、パケット再送ができないという話に時間をかけすぎていて、Discordで非常に努力したというような点を繰り返すところで、論旨を見失っているように感じた
WebRTCのRTCはリアルタイム通信であり、人は時に、パケットが抜けた音よりも、遅れた音声や速度が不安定な音声のほうを嫌う。ここでは人の話し声のことを言っている
パケットロスを許容したくないなら、UDPの代わりにTCPベースのプロトコルを使えばいい。しかし、悪いネットワーク環境でTCPで音声を送ると、受信側は次の正しいパケットを待つために停止が発生する。数秒遅れて再びパケットが来たら、滞留した音声を通常速度で再生するのか、別のチャネルに追いつくために早送り再生するのかを決めなければならず、普通の人はそういう体験を好まない
WebRTCを少し忘れて、音声におけるTCPとUDPを考えれば、VoIPが90年代からUDPベースだったのには理由がある
まず技術的な点に答えると、WebRTCではない未来はあると思う。ただし、その方向がWebTransport+WebCodecsなどの向かう先と一致するかは分からない
ユーザーが、遅い・高価なプロンプトの精度を上げるために200ms余計に待つことを望んでいるという話は、自分が受けているフィードバックとは正反対だ。ユーザーは即時の応答を求めている。応答生成や割り込み処理に遅延があると、魔法のような感覚が失われる。また、リアルタイムより速く送ってほしいとも思っていない。ユーザーがモデルを途中で遮ったら、10秒しか再生されない3分の音声を送るために帯域を無駄にしたことになる
TTSがリアルタイムより速いという主張については、最新の、あるいは目指されている音声AIは、筆者の説明する方式から外れつつある: https://research.nvidia.com/labs/adlr/personaplex/ のように20ms単位で少しずつ入出力する方向だ
ユーザーの元のIP/ポートが変わらないことを望むという部分はサポートされている。ufragに対して新しいIPが来れば処理できる
最低8往復時間かかるという話も誤りだ: https://datatracker.ietf.org/doc/draft-hancke-webrtc-sped/
音声をWebSocketでストリーミングするという選択は、AECのような機能を失い、複雑さをクライアント側へ押しつける。WebRTCの単純さ、つまりcreateOffer -> setRemoteDescriptionの流れがあるからこそ、人は簡単に始められる。Realtime API + WebSocketでは、多くの開発者がコード量の多さや自分で処理しなければならない部分の多さで苦労していた
個人的に選ぶなら、Offer/Answerモデルは維持しつつ、DTLS+SCTPの代わりにQUICを使いたい。もしかするとQUIC上でRTPをやるかもしれない。プロトコル自体に強い好みはないが、はるかに大きいコードフットプリントで複数のクライアントと顧客側クライアントにコードを配布する方法はよく分からない
TTSの専門家ではないが、結果を少しずつ流す利点が何なのか分からない。シリコンは時間の数値がどれだけ速く増えるかなど気にしない
クライアントが自分のIP変更を把握してICE再ネゴシエーションできる場合もあるが、分からないことが多く、通常はサーバーが変更を検知することを期待する。ところが今のロードバランサー構成ではそれが不可能だ。大きな問題ではないが、すでに越えるべき手順が多い状況では残念だ
そのドラフトが8 RTTではなく7 RTTという意味なら、一部はパイプライン化できるので実際の数値はさらに低くなるかもしれない。しかし本当の問題は、P2Pが使われる可能性があるというだけで、必須のシグナリングサーバーと二重のTLSハンドシェイクが生まれる点だ
WebRTCが新規開発者にとって簡単なのは、ブラックボックスの会議アプリだからだ。しかしOpenAIのような大企業では、そのブラックボックスが、より低レベルのプリミティブで修正できる問題を生み始める
RTP over QUICはぜひ試してみるといいし、手伝う意思もある。コードサイズが心配なら、ブラウザや、いずれはOSがQUICライブラリを提供する。MoQに近い方向へ変えれば、QUICがフラグメンテーション、再送、輻輳制御などを処理するため、アプリケーションは驚くほど小さくなる
RoQ/MoQの大きな制約は、QUICがデータグラムまで含めて輻輳制御を行うため、GCCを実装できないことだ。ブラウザから送る場合、しばらくはcubic/BBRに縛られることになる
今やっている仕事は音声/ビデオ会議と1対1通話だが、WebRTCの複雑さはとてつもない。製品を素早く立ち上げる助けにはなったが、変わったことをしようとすると直しにくく、クライアント向けにフォークしていても同じだ
TURNについては長い愚痴を書ける。実際、WebRTCのプロトコル一式全体が、存在しないインターネット向けに設計されたように見える
TURNは、クライアントが割り当てを要求するとき、一時ポートではなくrendezvous idを割り当てるべきだ。そうすればピアはサービス用ポートでTURNサーバーに接続し、そのrendezvous idに対する接続を要求でき、クライアントがピアのアドレスを知ってpermissionを追加する必要もない。エンドツーエンドのリレー接続までに必要な通信が減る。高度なクラスターなら、idに情報をエンコードして、クライアントとピアがそれぞれ自分に近いTURNサーバーに接続し、サーバー同士を接続させることもできる。そこまで高度でないクラスターなら、idとともにTURNサーバーのIPとサービス用ポートを共有する必要がある
実際の表示タイムスタンプと、それが現実の時間にどう対応するかを知る必要がなぜあるのか、というくだりは痛いほど共感できる。WebRTCを作った人たちの誰も、異なる出所のデータストリームをミリ秒精度で同期したことがないように見える
ブラウザでWebカメラとIMUモジュールを使った映像安定化デモを作ったのだが、video->rtc->browser経路とsensor->websocket->browser経路の遅延が大きく異なり、しかも一定ではなかった。当然の解決策は、センサーデータにUTCタイムスタンプを付けて送り、ブラウザ側で同期することだが、映像にはUTCタイムスタンプの基準がないため不可能だった
WebRTCパイプの両端を完全に制御できるなら、ストリーム開始時点のUTCタイムスタンプを送るような面白いことはできるが、ブラウザのジッタは解決できない。概念実証としては十分に動いたが、全体的な解法は作り直す必要があった
この分野での経験は多く、特許出願もいくつかある。Alexaでは、デバイスがサーバーへ接続を張って維持し、wake wordを検知すると、その接続上に実質的にHTTP2/SPDYのようなものを流していた。だからユーザーが話し終える前にSTT処理を始めることができ、最後の数片の処理遅延だけが残った
返答も同じ接続で返ってきた
OpenAIの場合、Alexaのように常時接続を開きっぱなしにするのは難しいが、スマートフォンでHTTP2を使えば、iOSとAndroidがその接続をほぼ面倒見てくれる
筆者の言う通りだ。リアルタイムプロトコルは必須ではなく、すべてのデータを受け取ることのほうが重要だ。ユーザーは遅延が500msを超えるまではほとんど気づかない。特にモバイル時代では、ほとんどの人が人間同士のリアルタイム通信でさえ遅延があることに慣れている
OpenAIやAnthropicで働いているなら、連絡してくれて構わない。もっと詳しく話せる
転送遅延は、すでに大きい他のすべての遅延の上にさらに加わる
だからこそ、パイプライン全体のエンドツーエンド遅延を減らすために、可能な限り最低遅延の解法を選んだのだと思う
人間同士の音声遅延との類推は当てはまらない。その場合は人間を遅延のない存在として扱っているからだ
500msは、最近の最先端の音声実装において、運が良く、費用を惜しまず、speculative decodingやreasoningのような高価な技法まで使ったときの下限に近い。LLM段階だけで450msかかる。商用音声AIではすべてのmsが重要で、200〜300ms追加されるだけでも会話品質は大きく悪化する
うちの事業は主に非技術系ユーザー向けの音声を多く扱っている。昨年、ターン間遅延が1200〜1500msだったときは、ユーザーの混乱、割り込み、会話離脱、全体的に不快な体験が多かった。今は必要なツール使用に応じて約700msまで来ており、実際の人間とのやり取りに近い、かなり良い体験になりつつある。ここからさらに100ms削るために、かなりのコストを払っている
speculative LLM passやspeculative tool executionのような高コストで無駄も多いことまでしている。ユーザーが話している間に複数のLLM推論を走らせつつ、そのpassが使えること、そしてユーザーが文末で重要なことを言っていないと分かるまでは、非冪等なツール呼び出しを実行しない、といった形で100〜200msを削っている。500msは関係ないという話は、人間対AIの音声インタラクションではない別の事例を指しているのだと思う
音声AIで本当に難しい問題は、たまに落ちるWebRTCパケットではなく、強い背景雑音、エコー、アクセントだ。WebRTCのよく磨かれたAEC実装は、少なくともエコーにはかなり効く。OpenAI規模で実装するには非常に面倒なプロトコルだとは分かるが、超大規模でないアプリケーションにはDailyのような商用プロバイダーや妥当な解法が多い。本当に解くべき問題は別のところにある。それでも、自分の遅延予算に500ms加わればアプリケーションは死ぬ
残念ながら、WebRTCほど実装したくないプロトコルはそう多くない。単純なクライアントを1つ立ち上げるだけでも、SDP、TURN/STUN、ICE candidates、offer、P2Pプロトコル、毎回最初から実装する複雑なハンドシェイクにすぐ適応しなければならない
プロトコルと意図しない「ベストプラクティス」が何層にも入ったそのトレンチコートを、まるごと書き直すことなど想像もしたくない
教材やライブラリが増えて改善していることを願う。Codexのようなツールが今ではこういう部分をかなりうまく押し進めてくれるのも驚きだ
ブラウザAPIの安定性全般には文書化されていないエッジケースが多く、WebRTCだけの問題ではない
いら立つほど一方に偏った記事だ。WebRTCに限界があるのは事実だが、標準に乗ることで多くの正確性を得られ、長期的なエンジニアリングコストも下げられる。WebRTCが複雑だという事実は、間違っていることを意味するのではなく、公開インターネット上のリアルタイムメディアが複雑だという意味だ
ネットワーキングは本質的に状態を持つ。NAT traversal、ジッタバッファ、輻輳制御、パケットロス、コーデック状態、暗号化、セッションルーティングは、音声をTCPやWebSocketに載せたからといって消えない。そうではないふりをするのは、アーキテクチャ上の明快さではなく、複雑さを見えにくい場所へ移すだけだ
1年前にはDiscordでRustでWebRTC SFUを書き直しており、繰り返されるパターンが見えるはずだ
WebRTCは、2000年代初頭から続く約45本のRFCと、TWCCやREMBのような、技術的にはドラフトだが事実上の標準であるものから成る。これを全部実装しなければならないとき、まったく楽しくない
本人は公認のWebRTC専門家と見て差し支えなく、だからこそ二度とWebRTCを使いたくないと言っている
一般的なやり方で十分すぎるほど試してきたのだから、反対側の見解を持つ資格は十分あるのではないかと思う
主題そのものへの立場はないが、文章に明らかに人間らしい手触りがあってよかった
もしAIが書いた文章なら本当に大変だ
2026年になってもリモート会議は相変わらずひどい。何十億ドルもかかっていて、Zoomですらよくて並、Microsoftのあれくらい悪いこともある。リモート会議が不器用で荒っぽい混乱でないのを見たことがない
素晴らしい記事だ。筆者がその分野の専門家であるとき、ブログ記事に賞を贈れたらいいのにと思う
「WebRTCは悪いネットワーク状況で私のプロンプトを劣化させ、落とすよう設計されている」という話については、リアルタイムを望むなら受け入れるしかない。リアルタイムを望まず、すべてをSTT -> Prompt -> TTSとして考えるなら、そもそも音声をネットワークで送る必要がないかもしれない
すべての低遅延アプリケーションは、品質と遅延時間の間でユーザー体験上のトレードオフを決めなければならない。輻輳はキューイング、つまり遅延を生み、それを避けるには何かをスキップする必要があるため品質が下がる
WebRTCの遅延時間対品質の調整ノブは固定されている。遅延最小化には優れているが、柔軟性に欠ける。それでもブラウザ対応のおかげで、事実上数少ない選択肢なので、いまだにWebRTCを使おうとしている
しかし今はWebTransportがある。汎用プロトコルとしてWebRTCに似た動作を作れる。ストリームをdrop/resetする前にどれだけ待つかをアプリケーションが選べるので、その判断を代わりに押しつけられない
記事の要点は、ユーザーはたいていストリーミングは望むが、ドロップは望まないということだ。音声入出力のストリーミング自体はWebRTCなしでも当然できる。音声パケットが永遠に失われたと見なす時点をアプリケーションが決められるべきだ。50msなのか500msなのか5000msなのか、という話だ。音声AIが50msオプションを選ぶべきではない、という主張である
OpenAIが応答するとき、ユーザーが聞くべき時点より前に音声の大半をすでに持っている。リアルタイムより速く音声を生成するので、リアルタイムプロトコルは適した選択ではない
Gemini Live APIを管理型WebRTCクラウドメッシュ上で動かしているが、とてもよく機能していて、2年間運用している。WebSocketを試し、一時キーなどを自前で扱うこともできるが、この領域で大規模な音声エージェントを運用している人たちと話すと、WebRTCとPipecat、そしてすでに解決済みの問題に投入された多くのリソースによって、かなりの部分が解かれている
明らかにやりすぎに見えるし、実際そうかもしれないが、接続が張られたあとはかなり魔法のようだ。起動時間とバッファリングも、より高速な音声接続のために解決済みだ: https://github.com/pipecat-ai/pipecat-examples/tree/main/ins... 映像はさらに難しい