文章

Voice Agent 生产实战:用流式 ASR、VAD 与分段上下文稳定语音大模型体验

从工程视角拆解语音大模型应用的实时链路,详解如何用流式 ASR、语音活动检测、分段上下文、LLM 推理和 TTS 协调来降低端到端体感延迟,稳定长对话中的语义边界与用户体验。

背景问题:语音 Agent 的难点不只是”会说话”

文本大模型应用的链路通常是”用户输入文本 → 模型生成文本 → 前端展示结果”。语音 Agent 的链路复杂得多:用户说话时,系统要实时接收音频、判断是否有人声、把语音转成文本、识别用户是否说完、把片段送给 LLM 推理,再把回复转成语音并播放出来。

如果每个步骤都等上一步完全结束,用户会明显感觉”慢半拍”。如果过早触发,系统又可能在用户还没说完时抢答,或者把半句话当成完整意图。语音大模型体验的核心,不是单点模型能力,而是流式 ASR、VAD、上下文分段、LLM 推理和 TTS 播放之间的协调。

OpenAI Realtime 文档将实时音频场景分为 Voice Agent、实时翻译、实时转写、语音生成等不同路径,并指出实时会话适合低延迟 live audio,文件型或有界音频更适合请求式 API。对生产系统来说,这个区分很关键:实时对话要优化的是用户体感,而不是单次离线转写准确率。

核心原理:级联流式架构仍是生产主流

端到端 speech-to-speech 模型可以直接接收音频并输出音频,但企业级语音 Agent 仍经常采用级联流式架构:

Audio Input → VAD → Streaming ASR → Segment Buffer → LLM → Streaming TTS → Audio Output

这种架构的优势是可控。ASR 可以独立优化识别准确率,LLM 可以复用文本 Agent 的工具调用、权限控制和业务状态,TTS 可以独立选择声音、语速和播放策略。缺点是链路更长,如果没有流式和并行处理,端到端延迟会迅速累积。

Whisper 论文表明,大规模弱监督训练能够提升多语言、多任务语音识别的泛化能力;但生产语音 Agent 不能只看 ASR 模型本身,还要处理噪声、口音、打断、停顿、长句、重复和转写不稳定等工程问题。对用户而言,最终体验取决于”听、想、说”整个链路是否自然。

工程落地:把语音链路拆成五个控制点

1. 音频入口:不要把所有音频都送进模型

音频入口首先要解决采样、编码、降噪、断线重连和客户端缓冲问题。浏览器和移动端通常更适合使用 WebRTC;服务端已经收到媒体流、电话流或 worker 音频时,可以使用 WebSocket 或其他服务端流式链路。

入口层还应该打上稳定的会话 ID、用户 ID、设备信息、采样率、语言偏好和业务场景。后续排查延迟、噪声和误识别时,这些字段比单纯的转写文本更有价值。

2. VAD:决定什么时候开始听、什么时候提交

VAD(Voice Activity Detection) 表面上是在判断有没有人声,但在语音 Agent 中,它同时影响四件事:

影响维度说明
是否开始转写检测到人声后启动 ASR 流
是否继续等待静音期间是暂停还是继续等待
是否提交片段判断当前片段是否可以提交
是否触发响应决定 LLM 开始推理的时机

VAD 太敏感,背景噪声会被当成用户输入;VAD 太迟钝,用户说完后系统迟迟不响应。更常见的问题是,VAD 只按静音时间切段,结果把一句完整意图切成多个碎片,或者在用户短暂停顿时提前触发回复。

生产系统通常需要组合三类信号:声音活动、静音持续时间、语义完整度。也就是说,用户停顿 300 毫秒不一定等于说完;但如果当前片段已经形成完整意图,并且后续静音超过阈值,就可以触发下一步。

3. Streaming ASR:区分临时转写和确认转写

流式 ASR 会持续输出 partial transcript,但这些中间结果可能回滚、改写或补全。如果系统把每个 partial 都直接写入长期上下文,后续 LLM 会看到大量重复和错误片段。

更稳妥的做法是区分两类文本:

{
  "transcript_buffer": {
    "partial": "用户正在说的临时文本,可被更新或覆盖",
    "committed": "已经确认的语义片段,可进入对话上下文",
    "confidence": "转写置信度或质量信号",
    "segment_id": "用于追踪和回放的片段编号"
  }
}

临时转写用于实时字幕、意图预判和提前准备;确认转写才进入正式上下文。对于客服、保险、金融、医疗等高准确率场景,还可以在关键实体上做二次确认,例如金额、日期、人名、证件号、地址和产品名称。

4. 分段上下文:不要把原始语音转写直接塞满窗口

语音输入天然包含口头语、重复、自我纠正和无意义停顿。例如用户可能说:“我想查一下,嗯,不是上个月,是这个月的账单。“如果系统直接把所有原始转写加入上下文,LLM 可能会误解用户意图。

分段上下文建议分成四层

层级内容用途
Raw Transcript原始转写全文审计、回放、问题排查
Committed Segment确认后的语义片段LLM 对话上下文
Dialogue State当前任务状态跟踪业务流程进度
Rolling Summary历史意图与已确认事实长会话压缩、跨轮记忆

这样做的好处是,LLM 看到的是”可推理上下文”,不是噪声堆积。

5. TTS 与打断:回复不是生成完才播放

语音回复也要流式化。LLM 生成文本后,TTS 如果等待完整答案再合成,用户会感到延迟明显。更好的方式是让 LLM 按短句、语义块或标点边界流式输出,TTS 边接收边合成,播放器边收到边播放。

同时必须支持用户打断。 用户一旦开始说话,系统应暂停或停止当前播放,并决定是否保留未播放内容。如果没有打断控制,语音 Agent 会像录音电话一样持续念完,体验很差。

常见误区

误区一:只优化 ASR 准确率

ASR 准确率重要,但语音 Agent 的体感还取决于首字转写延迟、提交延迟、LLM 首 token 延迟、TTS 首音频延迟和播放缓冲。单点准确率提升,未必能改善整体体验。 端到端延迟分解如下:

延迟指标说明
ASR 首段延迟音频输入到首个 partial transcript
ASR 提交延迟音频输入到 committed segment 确认
LLM 首 token 延迟上下文送入 LLM 到首个 token 生成
TTS 首音频延迟LLM 输出到首个音频帧合成
播放开始时间首个音频帧到用户听到声音

误区二:把静音当成语义结束

用户说话时经常停顿、思考、改口。只用静音阈值判断结束,会导致抢答或误分段。生产系统应结合语义完整度、业务状态和打断策略。

误区三:把 partial transcript 当成最终事实

流式转写的中间结果可能变化。把 partial 直接写入上下文,会造成重复、误识别和状态污染。应只把 committed segment 写入正式上下文。

误区四:忽略端到端观测

只监控模型耗时是不够的。语音 Agent 需要记录音频入口延迟、VAD 判定时间、ASR partial 延迟、ASR commit 延迟、LLM 首 token、TTS 首音频、播放开始时间和用户打断事件。

上线检查清单

上线前建议逐项检查以下内容:

  1. 是否区分实时会话、请求式转写和文件转写三种路径。
  2. 是否为 VAD 设置灵敏度、静音阈值和最大等待时间
  3. 是否区分 partial transcript 与 committed transcript
  4. 是否保存 segment_id,便于排查转写和上下文问题。
  5. 是否对关键实体做确认或二次校验。
  6. 是否把原始转写、确认片段、业务状态和摘要状态分层管理。
  7. 是否支持用户打断当前 TTS 播放
  8. 是否记录端到端延迟分解,而不是只看模型响应时间。
  9. 是否针对真实噪声、口音、弱网、长句和多轮打断做测试。
  10. 是否设置音频 token、会话时长和并发上限,避免成本失控。

适用场景

这套方案适合电话客服、智能外呼、会议助手、车载助手、语音搜索、实时翻译、保险理赔咨询、金融客服、医疗导诊和企业内部语音助理。

如果业务只是离线会议转写,不需要复杂的 Voice Agent 架构;请求式转写和后处理摘要可能更简单。如果业务要求实时问答、打断、工具调用和状态跟踪,则应优先考虑流式语音链路。

参考资料

常见问题

Voice Agent 一定要使用端到端语音大模型吗?
不一定。复杂业务通常仍采用 ASR、LLM、TTS 的级联流式架构,因为它便于接入工具、控制上下文、复用文本模型能力并独立优化各阶段延迟。
VAD 只负责判断用户有没有说话吗?
不只是。生产系统还会用 VAD 影响分段、打断、静音处理、转写提交时机和响应触发策略,它会直接影响端到端延迟和误触发率。
语音 Agent 的上下文为什么不能简单保存完整转写文本?
完整转写容易引入噪声、重复、口头语和错误片段。更稳妥的做法是把实时片段、确认片段、业务状态和摘要状态分层管理。