對手機說一句話,AI 在不到一秒內回應。這個過程你已經習以為常,但背後發生的事情,遠比你想像的複雜。

如果你用過 ChatGPT 的語音模式,或透過 Realtime API 開發過語音應用,你大概感受過那種自然的對話感——沒有明顯的延遲,不會覺得對方在等你說完才開始處理。要做到這件事,OpenAI 必須解決一個大多數開發者不會想到的問題:網路架構本身

2026 年 5 月,OpenAI 公開了他們重新設計的 WebRTC 技術棧。這不是一篇公關文章——它詳細說明了他們如何讓全球超過 9 億用戶的語音體驗保持流暢。原文在 HackerNews 上一天之內獲得超過 460 分、136 則討論,社群反應相當熱烈。對於正在開發語音應用的台灣團隊來說,這篇文章的技術含量非常高,值得深入了解。

語音 AI 的三大挑戰

很多人以為「語音 AI 就是模型變快了」,但事實上,用戶體驗的瓶頸往往不在模型推理速度,而在於網路。

OpenAI 明確列出了三個必須同時滿足的條件:

全球覆蓋。 每週超過 9 億活躍用戶,語音功能必須在任何地方都能流暢運作。這不是選擇題——你的用戶在哪,服務就得到哪。亞洲用戶和北美用戶必須獲得接近一致的體驗。

快速連線建立。 使用者按下語音按鈕後,必須在極短時間內建立連線。如果等待超過一秒,對話的自然感就消失了。這不僅影響用戶體驗,也直接影響產品的留存率——沒有人喜歡對著一支會 Lag 的機器說話。

穩定低延遲。 不僅要快,還要穩定。網路抖動(jitter)和封包遺失會讓語音聽起來斷斷續續——用 OpenAI 團隊自己的話來說:「當網路出問題時,人們馬上就會感覺到——尷尬的停頓、被中斷的說話、或是遲來的插話(barge-in)。」

這三個挑戰同時出現時,傳統的 WebRTC 架構就撐不住了。

WebRTC:為什麼是它

WebRTC(Web Real-Time Communication)是一個開放標準,負責在瀏覽器、手機 App 和伺服器之間傳輸低延遲的影音資料。你可能以為它只是拿來做視訊通話的,但事實上,它也是建立客戶端到伺服器即時系統的最佳基礎。

為什麼?因為 WebRTC 已經幫你處理好最麻煩的底層工作:

如果不用 WebRTC,每個客戶端都需要重新實作這些功能。有了它,OpenAI 只需要專注在一個問題上:「如何把即時媒體連接到 AI 模型?」

一個值得注意的細節:OpenAI 在文章中特別感謝了 Justin Uberti(WebRTC 原始架構師之一)和 Sean DuBois(Pion 函式庫的創建者)。這兩位現在都是 OpenAI 的同事。這說明了 OpenAI 在即時通訊技術上的投入——他們不只使用這個技術,還把這個領域最頂尖的人才納入團隊。

語音 AI 最重要的特性:串流處理

對於 AI 來說,WebRTC 最重要的特性不是「通話」,而是 音訊以連續串流抵達

這句話值得仔細咀嚼。當你對 ChatGPT 說話時,它不需要等你完整說完才開始處理。AI 可以在你還在講話的同時,就開始辨識語音、推理意圖、呼叫工具、甚至生成回應。這個機制叫做「barge-in」(打斷),是語音對話自然感的關鍵。

OpenAI 團隊用一句話總結了這個差異:「這就是一個系統感覺像對話,和另一個系統感覺像對講機(push-to-talk)的差別。」

想像一下傳統的 push-to-talk 體驗:你按住按鈕,說話,放開,等待。每一輪都是一個完整的請求-回應循環。但真正的對話不是這樣的——兩個人說話時,回應可以在對方還沒說完時就開始。AI 語音要做到這一點,音訊必須以串流方式送達,而不是整段上傳。

這背後的技術含義是:WebRTC 提供了一個自然的串流管道,讓 AI 的每個處理階段(語音辨識 → 推理 → 工具呼叫 → 語音生成)都可以平行進行,而不是序列等待。OpenAI 把這個叫做「在用戶還在說話時就開始處理」,而這正是即時語音 AI 與傳統語音助理之間最根本的體驗差異。

架構選擇:為什麼 SFU 不適合 OpenAI

一旦決定用 WebRTC,下一個關鍵問題是:要在哪裡終止(terminate)這些連線?

終止的位置決定了即時會話狀態、媒體傳輸、路由、延遲和故障隔離的處理方式。這不是一個可以隨便決定的架構選項。

最常見的選擇是 SFU(Selective Forwarding Unit)。SFU 是一個媒體伺服器,它接收每個參與者的 WebRTC 串流,然後選擇性地轉發給其他人。你可能用過的 Google Meet、Zoom、Teams 背後就是這種架構。SFU 為每個參與者終止一個 WebRTC 連線,AI 則以另一個參與者的身份加入會話。

SFU 的好處很明顯:它把音訊編解碼、RTCP 訊息、資料通道、錄音、以及每個串流的策略管理都集中在一個地方。對多人會議類產品來說,這是最合理的選擇。OpenAI 也承認:「即使在客戶端對 AI 的產品中,SFU 往往也是預設起點,因為團隊可以重複使用一個已經證明可行的系統來處理信令、媒體路由、錄音、可觀測性以及未來擴展(如人工介入或多參與者加入)。」

但 OpenAI 的場景不一樣。

他們的絕大多數語音會話是 1 對 1 的:一個使用者對一個模型,或一個應用對一個即時代理。 在這種流量形狀下,SFU 的架構反而是多餘的——你不需要一個為多人會議設計的中繼系統來處理單一對話。

於是 OpenAI 選擇了另一條路:收發器(transceiver)模型

收發器架構:專為 AI 語音設計

在收發器模型中,OpenAI 建立了一個 WebRTC 邊緣服務,這個服務負責終止客戶端連線,然後把媒體和事件轉換成更簡單的內部協定,再送到模型推理、語音辨識、語音生成、工具呼叫和編排服務。

關鍵設計決策:收發器是唯一擁有 WebRTC 會話狀態的服務。ICE 連線檢查、DTLS 握手、SRTP 加密金鑰、會話生命週期——全部集中在這個服務裡。

這樣做的好處顯而易見:後端服務不再需要處理 WebRTC 的複雜狀態機器。它們可以像一般服務一樣擴展——水平擴充、滾動更新、容錯轉移——因為它們根本不知道 WebRTC 的存在。這種關注點分離(separation of concerns)是優秀系統設計的標誌。

OpenAI 的第一版實作是用 Go 語言寫的單一服務,建構在 Sean DuBois 的 Pion 函式庫之上。這個服務負責兩件事:

  1. 信令(Signaling):SDP 協商、編解碼器選擇、ICE 憑證、會話建立
  2. 媒體(Media):終止下游的 WebRTC 連線,維護上游到後端服務的連線

到目前為止,這個服務已經在支撐 ChatGPT 語音、Realtime API 的 WebRTC 端點,以及多個研究專案。一個 Go 服務撐起全球數百萬即時會話——這本身也是一個效能證明。

最大挑戰:一個會話一個 Port的噩夢

OpenAI 想要讓這個服務像其他基礎設施一樣,跑在 Kubernetes 上。好處不言而喻:可以根據需求自動擴縮,Pod 可以在不同主機之間移動,發布部署可以滾動更新。

但傳統的 WebRTC 模型在這裡碰到了嚴重的架構阻抗不匹配——一個會話一個 port

在高併發情況下,這意味著你需要暴露和管理非常大量的 UDP port 範圍。OpenAI 的工程團隊指出了三個具體問題:

第一,雲端負載平衡器無法處理大量 UDP Port。 OpenAI 在文章中寫得很直接:「雲端負載平衡器和 Kubernetes Service 不是設計來處理一個服務好幾萬個 UDP port 的。」每增加一個 port 範圍,就意味著負載平衡器設定、健康檢查、防火牆策略和發布安全性都要跟著調整。這不是一個技術問題,而是一個營運噩夢。

第二,安全攻擊面大幅擴大。 大量的 UDP port 範圍會顯著增加外部可觸及的攻擊面。對安全團隊來說,要審計和監控這麼多 port 幾乎是不可能的任務。每次新 Pod 加入時自動註冊一個新 port 範圍,也讓防火牆政策的稽核變得更加困難。

第三,完全無法自動擴縮。 這可能是最致命的問題。Kubernetes 的 Pod 隨時在新增、刪除、重新排程,這是容器化部署的基本操作。但如果每個 Pod 都需要預留一個大型穩定的 UDP port 範圍,那自動擴縮就會變得非常脆弱——你要怎麼確保新加入的 Pod 有足夠的 port 可用?當 Pod 被排程到不同節點時,port 範圍要如何重新配置?

解決方案:Split Relay + 單一 UDP Port

OpenAI 最終採用的方案叫做 split relay plus transceiver。核心思想非常簡單:每個伺服器只暴露一個 UDP port

但事情沒有那麼簡單——當你只有一個 port 時,要把每個封包正確送到擁有那個會話的收發器,是一個非常困難的路由問題。

為什麼?因為 ICE 和 DTLS 都是有狀態的協定。建立一個會話的 process 必須持續接收那個會話的封包,才能驗證連線檢查、完成 DTLS 握手、解密 SRTP 內容。如果同一個會話的封包落在不同的 process 上,連線就會失敗。

OpenAI 評估了多種方案後,製作了一張完整的對照表。這張表在 HackerNews 上引起了不少討論:

OpenAI 選擇的第四個方案,核心是把封包路由和協定終止完全分開。

關鍵技術:ICE ufrag 路由

最終的架構是這樣的:信令(signaling)仍然直接到達收發器進行會話建立,但媒體進入 relay 作為第一站。

Relay 是一個輕量級的 UDP 轉發層,只有極小的對外 footprint。它不解密媒體,不執行 ICE 狀態機,也不參與編解碼器協商——它只做一件事:讀取夠多的封包元資料來決定目的地,然後轉發。OpenAI 確保了 relay 的會話狀態最小化,只有記憶體中的 session 用於轉發、必要的計數器用於監控、以及計時器用於 session 過期和清理。

這裡有一個非常巧妙的設計。

每個 WebRTC 會話已經有一個協定原生的路由標記:ICE username fragment(ufrag)——一個在會話建立期間交換的短識別碼,會在 STUN 連線檢查中自動帶回。

OpenAI 在伺服器端生成 ufrag 時,把路由元資料直接編碼進去。Relay 收到第一個封包(通常是 STUN binding request)時,只解析 STUN 封包的前面幾個位元組,讀取 ufrag 中的路由提示,就知道要把這個封包送往哪個集群、哪個收發器。

這個設計最精彩的地方:Relay 不需要查詢任何外部服務來做第一次封包路由。 路由資訊已經在封包本身裡了。

建立路由後,Relay 會記憶客戶端 IP:port 到收發器目標的映射,後續的 DTLS、RTP、RTCP 封包就直接在會話內流動,不需要重新解碼 ufrag。如果 Relay 重啟並丟失了會話狀態,下一個 STUN 封包會自動重建路由。

為了更可靠,OpenAI 還用了一個 Redis 快取來儲存已經建立好的路由映射——當 Relay 重啟時,可以從 Redis 恢復 <客戶端 IP + Port, 收發器 IP + Port> 的映射,比等待下一個 STUN 封包更快恢復服務。

全球部署:縮短用戶的第一跳

一旦把對外 UDP footprint 縮小到少數穩定位址和 port,OpenAI 就可以在全球部署相同的 relay 模式。

Global Relay 是他們的全球分散式 relay 進入點網路,所有進入點都實現相同的封包轉發行為。這意味著用戶的封包可以從最近的 relay 進入 OpenAI 的網路,而不是繞過大半個地球才到達最近的資料中心。

實際上,這意味著更低的延遲、更少的抖動、以及更少的可避免封包遺失——這些都直接改善了語音品質。

在信令層面,OpenAI 使用 Cloudflare 的地理和鄰近路由,讓初始 HTTP 或 WebSocket 請求到達最近的收發器集群。信令請求攜帶了會話位置的上下文,SDP 回應中提供了 Global Relay 的位址,而 ufrag 中包含了足夠的資訊讓 Global Relay 把媒體路由到正確的集群。

關鍵在於 SDP 回應中提供的是一個共享的 relay VIP(虛擬 IP)和 UDP port——例如 203.0.113.10:3478——即使背後有許多 relay instances,客戶端看到的只是一個穩定的目的地。

這樣一來,連線建立和媒體傳輸都從最近的進入點開始,同時會話仍然錨定在同一個收發器上。這直接縮短了使用者等待語音開始之前的時間。

Relay 的實作細節

OpenAI 用 Go 語言寫了 relay 服務,刻意保持實作的狹窄範圍。

在 Linux 上,核心的網路棧從網路介面接收 UDP 封包,並傳遞給 socket。Relay 在 userspace 執行,一個普通的 Go process 從 socket 讀取封包標頭,更新少量的流狀態,然後轉發封包——不終止 WebRTC。

他們特別提到:「我們不需要任何 kernel-bypass 技術。」這句話在 HackerNews 上引起了技術社群的共鳴。在超大規模系統中,很多公司會選擇 DPDK、XDP 等技術來繞過核心網路棧以獲得更好的效能。但 OpenAI 的 relay 用普通的 Linux 網路棧就夠了,因為它的工作非常單純——如果一個服務只需要解析封包標頭和轉發,Linux 核心的 UDP 棧已經夠快了。

這種務實的態度也反映在 relay 的會話管理上:如果 relay 重啟,路由資訊可以從 ufrag 恢復,或從 Redis 快取中快速重建。不需要複雜的狀態複製機制。

對開發者的實際意義

如果你只是 ChatGPT 的一般用戶,你可能不會感覺到任何變化——你的語音會話依然流暢,只是背後的技術不一樣了。

但如果你是用 Realtime API 開發語音應用的開發者,這件事情對你有直接影響:

更低的延遲,更好的體驗。 新的架構讓邊緣節點更接近用戶,第一跳延遲降低,意味著你的應用反應更快。對語音應用來說,少 50 毫秒的延遲就可能是「自然」和「卡卡」的差別。你的終端用戶會直接受益。

更高的可靠性。 單一 UDP port 加上 Kubernetes 原生部署,讓 OpenAI 可以更快地擴展和修復。Relay 重啟時路由可以自動恢復——這對生產環境的 SLA 有直接幫助。

標準 WebRTC 客戶端不需改動。 所有底層優化都在 OpenAI 的基礎設施端完成。你的客戶端程式碼不需要任何修改,因為從客戶端的角度來看,WebRTC 會話完全沒有變化。

對於正在開發語音應用的台灣團隊來說,這個案例最值得學習的可能不是 OpenAI 做了什麼,而是他們為什麼這樣做。當你的語音 AI 產品成長到一定程度時,你很快就會碰到類似的瓶頸——不是模型不夠好,而是音訊從用戶端到模型的這條路徑不夠順暢。你可以用同樣的 WebRTC 技術去建立自己的媒體路由層,而不需要被綁死在任何一個雲端服務上。

從更廣的視角來看

OpenAI 這篇文章算是近期少見的技術透明案例。過去他們對於基礎設施細節相當保留,這次把 WebRTC 架構的設計思路公開,某種程度上反映了他們對這個領域的自信——畢竟 Justin Uberti 和 Sean DuBois 都在他們團隊,這是全世界少有的即時通訊技術豪華陣容。

但反過來說,這也說明了語音 AI 的競爭還沒有結束。如果技術已經成熟到像 API 呼叫一樣簡單,OpenAI 根本不需要特別寫一篇文章來解釋他們怎麼做的。正因為這個領域還在快速演化,架構設計本身還是競爭優勢。

對開發者來說,這是好事——標準 WebRTC 意味著你不會被綁死在 OpenAI 生態系。不管你今天用的是 OpenAI、Google、還是哪家公司的語音 API,背後的 WebRTC 基礎是一樣的。知識是可轉移的。

這個案例也提醒了我們一件事:在 AI 領域,真正決定用戶體驗的往往不是模型本身,而是那些看不見的基礎設施。OpenAI 花了大量心力在「音訊從用戶端到模型的這條路徑」上,因為他們知道,再好的模型如果網路不行,用戶體驗就是零。

未來幾年,我們會看到語音 AI 成為更多應用的預設互動方式。但真正的變化,或許不是模型變得多聰明,而是從你開口說話到 AI 回應之間的那段時間,縮短到讓你不會再意識到它的存在。就像呼吸一樣——當你不需要想它的時候,它才算真正成功了。