2026-07
实时语音延迟优化Voice Agent

AI 为什么迟迟不开口:实时语音的延迟排查

等待来自判停、模型响应、语音合成和播放链路。我把这些环节分开检查,也区分“已经发出承接声”和“真正开始回答”,避免用一个首响数字掩盖体验问题。


语音对话里,等待会直接影响交流。用户说完话后没有回应,很难判断系统是在思考、没有听清,还是已经断开。

排查自己的语音系统时,我把耗时拆到判停、模型首字、合成首音和实际播放。只看端到端总耗时,很容易改错环节。

确认用户说完,也需要时间

系统通常会等待一段静音,再提交用户的话。窗口过长会拖慢回答,过短又可能截断句子。我调整静音窗口,并加入语义判停,根据句子是否完整辅助判断。

这项取舍要结合实际说话方式验证。孩子的停顿、重复和半句改口,都可能让一个看似更快的配置变得难用。

模型响应要看慢的时候

模型首字时间会随网络和服务负载变化。我尝试了模型赛马:并发请求候选模型,采用先返回的可用响应,取消其他请求。它能降低对单一路径的依赖,也增加请求成本和取消处理的复杂度。

思考模式也会影响开口时间。即时闲聊需要较快接话,复杂分析可以允许更长等待;选型时应分别测试,不能照搬写代码时的配置。

连接和音频处理也会吃掉开头

语音合成前临时建连,会增加一次等待。连接复用可以减少这部分开销,但要处理失效连接和重连。回声消除的冷启动也可能影响首句,需要从采集、传输到播放逐段检查。

目前 MyJavis 与小可共用基于 Rust 重写的实时双向全双工语音引擎。Tokio 管理异步任务,LiveKit/WebRTC 传输音频,语音识别、模型生成和语音合成流式衔接,并处理判停与打断。低延时需要这些环节共同优化,采用 Rust 本身不能证明性能提升。

承接语不能冒充答案

完整回答尚未就绪时,可以根据用户话语播放一句自然的承接,减少没有反馈的空白。承接内容要合适,也要与正文衔接;垫一句之后继续冷场,仍然是体验问题。

因此我把承接首响和正文首响分开看,同时检查首句是否完整、用户能否插话、打断后有没有旧回答继续播放。本文保留优化方法,不把不同设备、网络和版本的历史测量合并成一个性能承诺。