PRODUCT
Realtime API 是 OpenAI 的实时语音交互接口,在 24 年的 DevDay 首次亮相,当时还是 beta,调用贵到离谱,音频输出 200 刀/百万 token:
两个月后新加坡 DevDay,我在现场看了多语言混合输入输出的演示,情绪和语气都非常到位,比 Whisper 链路的效果好了一个量级
之后经历了 WebRTC 支持、SIP 电话接入、图片输入、多轮调价,到 2025 年 8 月正式 GA。现在这套系统服务数亿周活用户,语音 AI 这条线上,目前没有第二家能打的
Realtime API 这个东西,最牛逼的是延迟:从你对着手机说一句话开始,到听到 AI 返回声音为止,只需要不到 0.3 秒
在这个过程中,声音变成数据包,穿过 Wi-Fi、运营商的网络、横跨大半个互联网,到达 OpenAI 的服务器。然后,服务器跑完推理、生成语音,再原路返回。整个过程必须快到让你感觉不到延迟,就像跟一个真人在说话
对于这玩意儿是怎么实现的,OpenAI 今天发了个技术 Blog,来详细介绍了下
![]()
https://openai.com/index/delivering-low-latency-voice-ai-at-scale/
然后...第二作者,是麦当劳
核心信息包括:
→ OpenAI 没有用行业默认方案,自己设计了relay + transceiver两层架构,前者只负责转发数据包,后者负责所有通话状态
→ relay 极其轻量,不解密、不解码、不参与任何协商,只看数据包头部的一小段标记就知道往哪儿转
→ 全球各地部署了相同的 relay 入口,用户的数据包在离自己最近的地方进入 OpenAI 的网络
→ relay 用 Go 语言写的,没有用更底层的高性能方案,因为够用了
→ 整套架构跑在 Kubernetes 上,对外只暴露少量固定端口
技术方案选型
OpenAI 用的实时通信协议叫WebRTC,就是你平时微信视频通话、Google Meet 开会时底层跑的那套技术。它是一个开放标准,能在浏览器、手机和服务器之间传输低延迟的音频和视频
做 WebRTC 服务,行业里有一个默认选择叫SFU(选择性转发单元)。简单说就是一个中转站,每个参与者跟它建一条连接,它负责把声音和画面转发给其他人。多人视频会议用这个方案很合适,音视频编解码、录制、策略控制都集中管理
![]()
SFU 方案:AI 作为 WebRTC 参与者加入,适合多方通话
OpenAI 的场景不一样。绝大多数会话是 1:1,一个用户对一个模型,每一轮对话都对延迟极度敏感。SFU 带来的多方通话基础设施,在这个场景里是多余的
他们还评估过另一个常规方案TURN,这是 WebRTC 穿透防火墙时常用的中继方式。但 TURN 要求中继节点持有客户端的连接分配状态,不够轻量
最后选的方案叫 transceiver 模型:在网络边缘部署一个 WebRTC 服务,负责跟客户端完成连接建立、加密握手这些协议工作,然后把收到的音频转成更简单的内部协议,分别送给后面的推理、转录、语音合成服务。所有通话状态集中在 transceiver 一个地方,后端的 AI 服务可以当普通服务来扩展,完全不需要懂 WebRTC
![]()
transceiver 方案:在边缘终止 WebRTC,转换为后端协议
端口占用问题
选定 transceiver 方案之后,还有一个工程问题要解决:端口占用
传统 WebRTC 部署里,每个通话需要占用一个独立的网络端口。当同时通话的用户有几百万个的时候,端口会不够用。OpenAI 的基础设施跑在容器化平台 Kubernetes 上,没法给每个容器预留几千个公网端口
他们的做法是把数据包的「转发」和「处理」拆成两层
relay是第一层,部署在面向公网的入口。它是一个极轻的 UDP 转发服务:不解密通话内容,不跑任何协议状态机,不参与编解码协商,不知道你在说什么。它只做一件事,读取数据包头部的一小段标记来判断这个包属于哪个会话,然后转发给对应的 transceiver
transceiver是第二层,在 relay 后面。它拥有通话的全部协议状态,包括 ICE 连通性检查、DTLS 加密握手、SRTP 媒体解密,以及会话的整个生命周期。从用户的手机或浏览器来看,通话行为没有任何变化
![]()
relay 只做无状态转发,transceiver 持有完整会话状态
relay 持有的信息极其精简:一条内存中的转发映射(这个客户端的包往哪个 transceiver 送),加几个监控计数器和过期定时器。没有持久化,没有协议参与。如果 relay 重启了,下一个数据包到达时就能自动重建路由
解决首响应问题
Realtime API 最牛逼的地方,是在 0.3 秒内完成首响应,这就需要对首包进行路由管理。用户发出的第一个数据包到达 relay 时,relay 还没有任何关于这个用户的信息,但它必须立刻知道往哪里转发。在这一步中,如果停下来查数据库或者问别的服务都会增加延迟,是不行的
OpenAI 利用了 WebRTC 协议自带的一个机制:ICE ufrag(ICE 用户名片段)。这是在通话建立阶段双方交换的一个短标识符,之后客户端发的每个连通性检查包都会带上它。OpenAI 在服务端生成 ufrag 时,把路由需要的信息编码在了里面
具体流程:通话建立时,transceiver 分配好会话状态,在协商应答(SDP answer)里返回一个共享的 relay 虚拟 IP 和 UDP 端口。客户端看到的是一个固定的目标地址,比如203.0.113.10:3478,背后其实是整个 relay 集群
客户端发出的第一个数据包通常是一个 STUN binding request。relay 只解析这个包头部的 ufrag 字段,解码出路由提示,把包转发给拥有该会话的 transceiver。之后这个客户端的所有后续包都走同一条已建立的路
![]()
从连接建立到媒体传输的完整时序:Client → LB → Relay → Transceiver
容灾方面,Redis 缓存了「客户端 IP:Port → transceiver IP:Port」的映射。relay 重启后可以在下一个 STUN 包到来之前就从 Redis 恢复转发路径,进一步缩短中断窗口
进行全球部署
如果用户在北京说一句话,如果数据包要跑到美国西海岸才开始处理,单程网络延迟就可能超过 150 毫秒,一来一回 300 毫秒。对话体验会明显卡顿。解决办法是让数据包尽早进入 OpenAI 自己的高速网络
relay 的公网暴露面缩到少量固定地址和端口之后,同一套转发逻辑就能在全球各地复制部署。OpenAI 把这个叫Global Relay,一组地理分布式的 relay 入口点,都运行相同的包转发行为
![]()
Global Relay 接收全球客户端的数据包,转发给 transceiver 集群
用户的数据包在离自己最近的入口进入 OpenAI 网络,然后通过内部骨干网到达 transceiver。跟直接穿越公网相比,延迟更低,抖动更小,丢包更少
整套架构跑在 Kubernetes 上不需要暴露成千上万个 UDP 端口。更小且固定的暴露面更容易做安全策略和负载均衡,扩展时也不需要预留大段公网端口范围
底层是 Go 写的
做实时媒体转发,常规选择是 C/C++ 或者 Rust,有些追求极致的团队甚至会上 kernel bypass,绕过操作系统内核让程序直接操作网卡。OpenAI 的 relay 用 Go 写,这在行业里算非常规
他们在 Go 运行时层面做了几个针对性优化:
→SO_REUSEPORT让同一台机器上多个 relay 进程共享同一个 UDP 端口,操作系统内核在它们之间分配数据包,避免单一进程成为瓶颈
→runtime.LockOSThread把每个负责读 UDP 数据的 goroutine 钉在一个固定线程上,配合 SO_REUSEPORT,同一个通话的包倾向于落在同一个 CPU 核心,缓存命中率更高
→ 预分配内存缓冲区,最小化数据拷贝,避免在转发热路径上触发 Go 的垃圾回收
这套实现撑住了全球的实时媒体流量,relay 集群规模相对不大。所以他们没有进一步走 kernel bypass 路线
补充一个细节:OpenAI 使用了Pion,一个 Go 语言的 WebRTC 开源库。Pion 的作者 Sean Der 在 Hacker News 上确认了这一点
三条设计原则
对于这个项目,OpenAI 在总结了三条原则,对任何做实时系统的团队都有参考价值:
→硬性状态集中在一个地方transceiver 拥有 ICE、DTLS、SRTP 和会话生命周期,relay 只转发。状态集中意味着出了问题只查一个地方
→在已有信息上做路由ICE ufrag 是协议自带的标识符,把路由信息编码在里面,首包到达时就能路由,不需要在热路径上加外部查询
→够用就不换Go 配合几个内核级优化对当前负载已经够用,就没有上 kernel bypass。先跑起来,再决定要不要换更重的方案
实时语音 AI 能跑起来,靠的是基础设施让延迟变得感知不到
OpenAI 改变的是 WebRTC 部署的内部形态,但没有改变客户端对 WebRTC 协议的预期
openai.com/index/delivering-low-latency-voice-ai-at-scale
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.