- OpenAIはWebRTCセッション管理を「リレー(パケット転送)」と「トランシーバー(WebRTC状態管理)」に分離することで、Kubernetesでの大規模運用と低遅延配信を両立する新アーキテクチャを実現した
- ICEのufrag(username fragment)にルーティングメタデータを埋め込む手法で、外部サービスへの問い合わせなしに最初のパケットから正確に宛先トランシーバーへ転送できる仕組みを構築した
- Goで実装したリレーはSO_RUSEPORTとスレッドピニングを活用し、カーネルバイパス不要のまま全グローバルリアルタイムトラフィックを少数のインスタンスで処理することを実証した
音声AIにおけるWebRTCの意義
OpenAIは2026年5月4日、リアルタイム音声AI製品のWebRTCインフラを刷新した技術詳細を公式ブログで公開しました。ChatGPTの音声機能やRealtime APIを支えるこのスタックは、週間アクティブユーザー9億人超を対象に、「話し言葉の速度で会話が成立する」レベルの低遅延を実現しなければなりません。具体的には、グローバルな接続到達性、セッション開始直後から発話できる高速なコネクション確立、そして自然なターンテイキング(会話の交代)を支える安定したメディア往復遅延が求められます。
WebRTCはブラウザやモバイルアプリとサーバーの間で低遅延なオーディオ・ビデオ・データをやり取りするためのオープン標準です。ICE(Interactive Connectivity Establishment)によるNAT越え、DTLSとSRTPによる暗号化、コーデック交渉、RTCP品質制御まで、リアルタイム通信の難所を標準化しています。OpenAIがWebRTCを採用した最大の利点は、音声を連続ストリームとして受け取ることで、ユーザーが話し終わる前からモデルが文字起こし・推論・ツール呼び出しを開始できる点にあります。これがプッシュトゥトーク型との決定的な差であり、「会話が自然に感じられる」かどうかを左右します。
SFUではなくトランシーバー方式
WebRTCの採用を決めた後、次の設計判断は「どこで接続を終端するか」でした。検討されたSFU(Selective Forwarding Unit)はグループ通話や教室型サービスに適した構成で、複数参加者のメディアを一元管理できます。しかしOpenAIのセッションの大半は1対1の対話であり、推論バックエンドがWebRTCのピアとして振る舞う必要がないため、トランシーバー方式が採用されました。
トランシーバーはICE・DTLS・SRTPの全状態を一箇所で管理し、バックエンドサービスには内部プロトコルに変換してから渡します。これによってバックエンドは通常のサービスとしてスケールでき、WebRTCのピアとして動作する必要がなくなります。
Kubernetesとの技術的衝突
初期の実装はPion(GoのWebRTCライブラリ)を使った単一サービスで、シグナリングとメディア終端を担っていました。問題はKubernetes環境との相性です。従来のWebRTCは1セッション1ポートモデルを前提としており、同時接続数が増えると大量のUDPポートをパブリックに開放しなければなりません。
クラウドのロードバランサーやKubernetes Serviceは数万ポートものUDP開放を想定しておらず、設定・ヘルスチェック・ファイアウォールポリシーがいずれも複雑化します。また、Podが追加・削除・再スケジュールされるKubernetes環境では、ICEとDTLSの「セッション固定所有権」を保つことも難しく、パケットが別プロセスに届くとセットアップ失敗やメディア断の原因になります。
リレーとトランシーバーの分割構成
これらの問題を解決するために設計されたのが「リレー+トランシーバー」アーキテクチャです。リレーは軽量なUDPフォワーディング層で、パブリック向けのUDPポートはごく少数の固定アドレスに限定されています。トランシーバーはその背後に置かれ、ICE・DTLS・SRTPといったWebRTCの全状態を保持します。クライアントから見れば、通常のWebRTCセッションと変わりありません。

リレーはSTUNパケットのヘッダーのみを読み取り、DTLS・RTP・RTCPパケットはキャッシュされた転送先情報を使ってそのまま転送します。プロトコルを終端しないためセッション状態は極小であり、リレーが再起動してセッション情報を失っても、次のSTUNパケットが到着すれば転送先を再構築できます。さらにRedisキャッシュにクライアントアドレスとトランシーバーのマッピングを保持しておくことで、STUNパケットを待たずに早期回復が可能です。
ICE認証情報によるルーティング
リレーが初めてパケットを受け取った時点では、転送先のセッション情報がありません。このゼロ状態での最初のパケット転送を実現するために、OpenAIはICEのufrag(username fragment)を活用しました。ufragはSDPでやり取りされる識別子で、STUNの接続確認リクエストに毎回付加されます。
OpenAIではサーバー側のufragを生成する際、宛先クラスターとトランシーバーを特定するルーティングメタデータを埋め込みます。リレーは最初のSTUNパケットからufragを読み取るだけで転送先を決定でき、外部のルックアップサービスへのホットパス依存を排除しています。SDPアンサーにはリレーの仮想IP(VIP)と単一UDPポートが記載され、クライアントには安定した単一の接続先が提示されます。
グローバルリレーの展開
公開UDPフットプリントが少数の安定したアドレスとポートに集約されたことで、同じリレーパターンを世界各地に展開できるようになりました。Cloudflareのジオ・近接ステアリングを利用したシグナリングにより、最初のHTTPリクエストは近隣のトランシーバークラスターへ誘導されます。メディアトラフィックも地理的に近いグローバルリレーの入口からOpenAIのバックボーンへ入り、トランシーバーへ転送されます。この構成により、ユーザーが最初の一声を発するまでの待ち時間とICE接続確認の往復遅延が共に短縮されます。
Go実装と最適化の詳細
リレーはGoで実装され、意図的にシンプルさを維持しています。主な最適化は3点です。
- SO_REUSEPORT: 同一マシン上の複数リレーワーカーが同じUDPポートをバインドでき、カーネルがパケットを分散する。単一読み取りループのボトルネックを回避する
- スレッドピニング:
runtime.LockOSThreadでUDP読み取りゴルーチンを特定OSスレッドに固定し、同一フローのパケットを同じCPUコアで処理してキャッシュ局所性を高める - 事前割り当てバッファ: 低アロケーションパースでGoのガベージコレクション負荷を最小化する
これらの工夫により、カーネルバイパス(DPDKなど)を使わずにグローバルなリアルタイムメディアトラフィックを少数のインスタンスで処理できることが実証されました。モデル側での全二重リアルタイム処理を追求するMiniCPM-o 4.5のようなアプローチもありますが、OpenAIはインフラ層の再設計によって音声AIの体験向上を図った形です。
設計から得られた教訓
このアーキテクチャによってOpenAIは、大量のUDPポートを公開することなくKubernetes上でWebRTCを動かすことに成功しました。公開するUDPのフットプリントが小さく固定されることで、セキュリティの確保とロードバランサーの管理が容易になり、大規模なポート範囲の予約なしにオートスケールが可能になっています。
設計上特に重要だった選択は3点です。第1に、クライアントは標準のWebRTCをそのまま使い続けることでブラウザ・モバイルの互換性を保ちました。第2に、ICE・DTLS・SRTPの状態はトランシーバーのみが管理し、リレーはパケット転送に徹しました。第3に、プロトコル内にすでに存在するICEのufragをルーティングフックとして利用することで、ホットパスの外部依存を排除しました。複雑さを「薄いルーティング層」に集中させ、バックエンドサービスやクライアントには変更を求めないというこの方針は、大規模なリアルタイムAIインフラ設計において広く参考になる指針です。
