构建语音控制的AI代理

💡 原文英文,约4000词,阅读约需15分钟。
📝

内容提要

构建语音代理的核心挑战在于编排,而非简单的STT-LLM-TTS串联。顺序模式延迟高,生产需采用流式处理:流式语音识别输出部分与最终转录,独立调优的轮次检测(静音阈值600-1500毫秒),句子级流式生成至TTS,结合能量、语音分类和持续时间的打断检测,以及工具调用时的缓冲与结果丢弃。理解各组件职责是调试和优化自然对话体验的关键。

🔎

延伸解读

延迟预算决定架构选择

文章指出,顺序模式因各阶段串行等待而延迟高,生产环境必须采用流式处理。人类对话的自然间隔为200-300毫秒,超过500毫秒就会感觉明显迟缓,超过3秒用户可能挂断。当前主流语音到语音系统首字延迟在0.8-3秒之间,因此架构选择直接决定体验是否自然。理解这一预算有助于在技术选型时优先考虑流式方案,而非简单串联STT、LLM和TTS。

轮次检测是可调策略而非固定值

轮次检测独立于STT,基于音频静音模式而非文本内容。生产系统使用两个阈值:最小静音时长(约600ms)在语义完整时触发结束,最大静音上限(约1500ms)强制结束以避免死寂。针对不同场景可调整:如老年护理或医疗对话可提高上限至2500ms,快节奏对话可降低下限至300ms。这种双阈值设计使系统能区分思考停顿和真正结束,避免误打断或延迟响应。

打断检测需多信号融合防误触发

误打断是语音代理常见问题,背景噪音、咳嗽或旁话可能被误判为打断。可靠检测需结合三个信号:能量阈值(-45至-35 dBFS)、语音分类器(如Silero VAD)和持续时长(200-300ms)。单一信号不足,例如高能量噪音可能通过能量检测但被语音分类器过滤。理解这些信号组合有助于调试误打断问题,避免代理无故中断。

工具调用需缓冲结果并处理中断

语音场景中工具调用存在可闻延迟,死寂会让用户误以为断线。解决方法是使用“前言”技术,让模型在调用前说出“让我查一下”等话语,保持对话活跃。同时,工具结果需缓冲,仅在当前轮次干净完成时发送;若用户中途打断,则丢弃结果,避免将过时信息注入已转移的对话。这一模式对并行工具调用同样适用,确保状态一致性。

Q&A

为什么顺序的STT-LLM-TTS模式不适合生产环境?

顺序模式中每个阶段必须等待前一个阶段完全结束后才能开始,导致延迟叠加,响应时间过长,无法满足自然对话的延迟预算(200-300毫秒自然间隙,超过500毫秒感觉明显缓慢)。生产环境应采用流式处理,各阶段增量输出,以降低延迟。

流式语音识别中,partial和final事件有什么区别?下游代码应该如何处理?

partial事件是实时更新的临时转录,会随着更多音频输入而改变;final事件是确认后的最终转录,不再变化。下游代码只应基于final事件执行操作,partial事件仅用于实时反馈显示。

轮次检测中,min_silence_ms和max_silence_ms分别起什么作用?如何调整?

min_silence_ms是结束轮次所需的最短静音时长(通常600ms),仅在转录内容听起来完整时才触发;max_silence_ms是强制结束轮次的最大静音时长(通常1500ms),无论内容是否完整都会触发。在语速慢的场景(如老年护理)可提高上限至2500ms,在快节奏对话中可降低下限至300ms。

在流式生成响应时,LLM到TTS的交接单位是什么?为什么这样设计?

交接单位是完整的句子,而不是单个token或整个响应。这样TTS可以在LLM还在生成后续内容时就开始合成并播放第一个完整句子,从而显著降低用户感知的响应延迟,提升对话的自然感。

如何防止误触发barge-in(如咳嗽或背景噪音被误认为打断)?

通过结合三个信号来防止误触发:能量阈值(通常-45到-35 dBFS)、语音分类器(如Silero VAD)区分真实语音与噪音,以及持续时长保护(要求200-300毫秒的持续语音)。只有三个条件同时满足才触发barge-in。

在语音代理中,工具调用时为什么需要preamble技术?

因为工具调用和结果返回之间存在可听见的延迟,静默会让用户误以为通话中断而开始说话,从而打断工具调用。preamble技术让模型在工具调用前和调用过程中说出如“让我查一下”之类的话,保持对话的听觉活跃,避免用户因等待而打断。

如果用户打断了工具调用,工具结果应该如何处理?

工具结果应该被缓冲,只有在当前轮次正常完成时才发送给用户;如果轮次被中断,则丢弃所有待处理的结果。因为用户已经转移话题,发送过时的结果会造成状态混乱。

🏷️

标签

➡️

继续阅读