语音在前台连续收发,搜索、工具和深度推理在旁路完成。
假设你对语音助手说:“帮我查明天上海的天气,适合跑步吗?”天气查询需要时间,但一个自然的助手应该先接住对话,查询完成后再继续回答,而不是从你说完开始一直沉默。
OpenAI 公开的 GPT-Live 架构,就是围绕这件事搭起来的:音频有自己的时钟,慢工具有自己的任务时钟。两者共享同一段会话,却不能排在同一条阻塞队列里。
先看旧链路:沉默是怎样累加出来的
常见语音 Agent 把工作串成一条流水线:
这条链路并没有哪一步一定很慢,问题是它们互相等待。只要工具多等一秒,开始播音也跟着晚一秒。对文字聊天,这只是总耗时增加;对语音,它会直接变成一段无反馈的静音。
GPT-Live 怎样让一次提问边说边查
图中天气值、事件 ID 和时间点是用于解释机制的示例;“多次每秒决策”和帧投递对比来自 OpenAI 官方自述。
上图不是两组静态模块,而是同一个请求的执行顺序。沿着编号看,它会经过六步。
第一步:音频以连续帧进入会话
客户端不会等整句话录完再上传,而是通过 WebRTC 持续发送音频。每个 frame 都带着自己的顺序和时间位置。WebRTC 负责处理丢包、时钟漂移和连接变化,让扬声器有音频可按时播放。
这里最重要的对象不是一条完整 user message,而是仍在前进的媒体时钟。用户可能停顿、补充一句,也可能在助手说话时插话;系统都不能因为后台任务尚未完成而停止收音。
第二步:Voice model 一边听,一边做短周期决策
GPT-Live 是 full-duplex voice model:同一个模型持续接收音频,也持续决定继续听、开始说、暂停、被打断或委托工具。OpenAI 的产品说明称,这类决策每秒会发生多次,而不是等一个独立 turn detector 宣布“这一轮结束”后才开始推理。
当模型识别出需要天气数据时,它发出类似 delegate(weather) 的任务意图。图中的 call_id=weather_7 是示例字段,用来说明后台结果必须能回到正确的会话与任务。
第三步:委托任务离开媒体循环
搜索、复杂推理、工具调用和业务逻辑通过异步 RPC 边界交给后台模型与工具运行时。它们可以有队列、超时、重试和降级,但不能占着 WebRTC 收发循环,也不能让 voice model 停止处理新音频。
OpenAI 还会在语音会话开始时预先创建后台 frontier model 的 inference session,提前 prefill 初始上下文;后续委托尽量保持 session affinity 和 prompt cache。这样做不是让工具瞬间完成,而是减少任务真正发生后再冷启动和重读上下文的等待。
第四步:前台可以先给出有意义的反馈
天气查询还在执行时,前台语音可以说“我查一下”。这句话不是伪造最终答案,而是在告诉用户:系统听到了,任务已经开始。与此同时,麦克风仍然开着;如果用户补充“我想早上六点跑”,新音频仍能进入当前会话。
这就是双路径真正改变体验的地方:工具耗时影响最终答案何时回来,不再直接决定对话何时发出第一点反馈。
第五步:结果按 ID 合并回会话
工具完成后,把结果连同任务身份返回。图中的 {temp:31°C, rain:70%} 只是示例数据。运行时需要校验它属于哪个 session_id、哪个 call_id,以及任务是否已超时或被用户取消,再决定是否把结果交给当前对话。
第六步:Voice model 继续说,而不是重开一轮
结果进入共享会话状态后,模型继续生成“降雨概率较高,建议改到室内”。如果用户已经改口、离开或打断了任务,运行时则应丢弃或降级旧结果。所谓“异步”因此不只是开一个线程,还需要身份关联、取消语义和过期判断。
两条路径到底各自负责什么
连续媒体路径负责音频 frame、播放时钟、jitter、丢包、连接和打断。它追求的是每个 frame 按时到达,工作必须小而可预测。
异步智能路径负责搜索、深度推理、工具、CRM 和持久化。它追求的是尽快返回有用结果,可以重试和降级,却不能持有音频循环。
共享会话状态负责把两边重新接起来:当前是谁在说、正在执行哪个任务、结果是否仍有效、哪段文字只是临时视图、哪些事件已经定稿。
OpenAI 称,media frontend 和 inference logic 从 Python asyncio 改写为 Go 后,新系统的 p95 帧投递平滑度达到旧系统 p50 水平。这是官方自报的局部帧投递指标,缺少完整定义与测试分布,不能等同于“端到端响应快了一倍”。它能支持的结论只有一个:媒体路径的尾部抖动值得单独治理。
为什么连续音频还需要“消息”
模型看到的是连续声音,UI、审计和业务系统仍需要一条条消息。两个人又可能同时说话,所以系统不能把刚出现的转写立即当成永久事实。
OpenAI 因此同时维护两种视图:
- 可修订视图:
供 UI 尽快显示,最新文字、时间和说话人可以继续变化; - 权威记录:
归属稳定后再定稿,供分析、审计和业务写入。
实现上,不要只保存一段 transcript。至少要区分 session_id、event_id、speaker、起止时间、revision 和 final 状态。天气任务的结果也必须引用稳定的任务 ID,不能靠“最后一条消息”猜它属于谁。
长会话怎样换实例而不突然静音
旧实例继续服务,新实例并行 prefill;状态版本号为解释切换过程的示例。
语音会话越长,上下文越大;实例也可能因扩缩容、故障或上下文压缩而需要替换。如果在当前实例上暂停、压缩历史、重建 KV cache,再恢复说话,用户就会听到停顿。
OpenAI 披露的做法更像有状态服务的蓝绿切换:
-
旧实例继续收发当前音频; -
新实例在旁边启动,并 prefill 当前或压缩后的上下文; -
两个实例短暂并行,直到新实例追上会话状态; -
在可控边界切到新实例,旧实例再退出。
官方没有公开双实例怎样对齐音频、去重输出或选择切换点。图中的 state_v42、state_v43 是解释版本推进的示意,不是 OpenAI 已公开的协议字段。
后端实现时,先守住四个边界
- 媒体循环不做慢 RPC:
CRM、数据库写入和工具调用都移到有界异步队列,配置超时、取消、背压和降级。 - 所有异步结果带身份:
至少关联 session、task/call、revision;结果返回时检查任务是否仍有效。 - 临时视图与永久记录分开:
UI 可以接收会修订的 transcript,计费、审计和业务系统只消费已定稿事件。 - 容量按会话和帧截止时间衡量:
除 GPU throughput,还要看活跃会话数、帧截止时间违约率、p95/p99 jitter、队列深度、重连和长会话恢复。
如果仍采用可替换的 ASR、LLM 和 TTS,也可以沿用同一原则:adapter 可以换,媒体时钟、任务身份和权威会话记录不能一起交给某个供应商私有 session。
最后把原理压成一句话
GPT-Live 的双路径不是把一张架构图分成上下两层,而是给同一段对话建立两个互不阻塞的时钟:音频按 frame 继续前进,智能任务按 task 异步完成;会话状态负责确认晚到的结果还该不该进入此刻的对话。
这样再看“边说边查”就很具体了:前台守住收音、播音和打断,后台完成搜索与工具,结果用稳定 ID 回到当前会话。真正需要先测的,也不再只是模型快不快,而是哪一个慢任务还占着媒体循环。












