文章

LLM 实时语音 Agent 生产实战:用 WebRTC、VAD 与打断恢复稳定对话体验

本文讲解实时语音大模型 Agent 的生产架构,覆盖 WebRTC 音频传输、VAD 端点检测、打断恢复、转写缓冲、工具调用确认、人工接管和上线检查清单,帮助团队从 demo 走向可治理的语音 Agent 系统。

背景问题:语音 Agent 的难点不是”能说话”,而是”能接住真实对话”

文本 Agent 的主要问题通常发生在上下文、工具参数和输出格式上。实时语音 Agent 多了一层更难控制的变量:用户不是按回车提交请求,而是在噪声、停顿、改口、插话、犹豫和情绪中持续说话。

一个演示版语音助手可以只做三件事:录音、发给模型、播放回复。但一旦进入客服、销售、教育、会议、车载或内部运维场景,系统就会遇到更具体的问题:用户还没说完模型就抢答;用户插话后旧回复仍在播放;噪声被当成新问题;工具调用已经开始但用户临时改口;转写和音频回答不一致;通话结束后没有可审计的证据链。

因此,实时语音 Agent 的生产治理重点不是单纯选择一个语音模型,而是围绕 传输、端点检测、打断恢复、转写缓冲、工具调用、人工接管和审计日志 建一条可控链路。

先做架构选择:speech-to-speech 与串联管线

OpenAI 的 Voice Agents 文档把语音 Agent 分成两类:一种是 live audio 的 speech-to-speech 会话,由模型直接处理实时音频输入和输出;另一种是显式串联 speech-to-text、文本 Agent、text-to-speech 的 chained voice pipeline。前者适合自然、低延迟、支持 barge-in 的对话;后者适合需要可见中间文本、审批、策略检查和可替换模块的工作流。

生产选型可以按下面的边界判断:

场景类型推荐架构原因
陪练、导购、问答、轻量客服、语音搜索、低风险助理speech-to-speech低延迟、自然打断、统一会话事件
金融、医疗、政企客服、投诉处理、工单变更、身份核验串联管线可见中间文本、策略检查、审批、审计
混合场景普通问答走 speech-to-speech,高风险动作走文本化确认兼顾体验与安全

WebRTC、WebSocket 与 SIP:不要把传输层混在一起治理

实时语音 Agent 至少有三种常见接入方式:

  • WebRTC:适合浏览器和移动端直接采集、播放音频。OpenAI 的 Realtime WebRTC 文档示例中,浏览器创建 RTCPeerConnection,采集麦克风音轨,建立数据通道,并通过应用服务器完成 SDP 交换。优势是低延迟、天然面向实时媒体、浏览器支持较好。
  • WebSocket:更适合服务端已经拿到原始音频流的场景,比如电话系统、会议录制、边缘网关或媒体 worker。Google Gemini Live API 也使用有状态 WebSocket 连接,支持音频、图像和文本输入。
  • SIP:更适合传统电话网络,通常是呼叫中心、语音网关或云通信平台集成的一部分。

工程上要避免一个误区:不要把 WebRTC、WebSocket、SIP 当成只是”连接方式不同”。它们决定了鉴权边界、日志采集方式、断线恢复策略、媒体质量指标、网络问题定位和安全模型。

VAD 是语音 Agent 的节拍器

VAD(Voice Activity Detection) 用于判断用户何时开始说话、何时结束一轮发言。OpenAI Realtime VAD 文档说明,启用 VAD 后系统会发送 input_audio_buffer.speech_startedinput_audio_buffer.speech_stopped 之类事件,应用可以据此管理会话状态或按片段处理转写。

VAD 不是一个简单开关,而是语音 Agent 的节拍器。它直接影响三件事:

  1. 首包响应延迟:如果系统等待太久才认为用户说完,用户会觉得助手反应慢。
  2. 截断风险:如果系统过早判断结束,用户的后半句话会被切掉,模型容易基于半句话回答。
  3. 打断体验:如果用户插话时系统不能及时识别,旧回复会继续播放,造成”机器不听人说话”的体验。

OpenAI 文档里区分了 server_vadsemantic_vadserver_vad 基于静音片段切分音频,可以调 thresholdprefix_padding_mssilence_duration_mssemantic_vad 则根据用户话语是否语义完成来判断是否结束,有助于减少模型过早打断用户。

生产建议是把 VAD 参数按场景分组,而不是全局固定一套。例如:

{
  "quiet_office": {
    "type": "server_vad",
    "threshold": 0.45,
    "prefix_padding_ms": 300,
    "silence_duration_ms": 450
  },
  "noisy_call_center": {
    "type": "server_vad",
    "threshold": 0.65,
    "prefix_padding_ms": 400,
    "silence_duration_ms": 700
  },
  "slow_speaker_or_elderly_user": {
    "type": "semantic_vad",
    "eagerness": "low"
  }
}

这只是示例,不应直接照搬上线。真实参数要用实际录音样本、噪声、设备、语言、口音和业务容忍度压测。

打断恢复:barge-in 不是”停止播放”这么简单

实时语音产品经常强调 barge-in,即用户可以在模型说话时打断。Google Gemini Live API 也把 Barge-in 列为 Live API 的关键能力之一。

但工程上,barge-in 至少包含四个状态动作:

  1. 检测用户开始说话:依赖 VAD 或前端音频能量检测。
  2. 停止或淡出当前 TTS/模型音频输出:否则用户会听到旧答案继续播放。
  3. 取消或冻结当前 response:否则旧 response 可能继续生成文本、继续调用工具、继续写入状态。
  4. 恢复上下文:系统要知道哪些内容已经播放给用户、哪些内容只是生成但未播放、哪些工具调用已经执行、哪些工具调用必须撤销或补偿。

一个更稳妥的做法是把每轮语音交互拆成事件日志:

type VoiceTurnEvent =
  | { type: "user_speech_started"; ts: number }
  | { type: "user_speech_stopped"; ts: number; audioSegmentId: string }
  | { type: "transcript_delta"; ts: number; text: string; final: boolean }
  | { type: "assistant_audio_started"; ts: number; responseId: string }
  | { type: "assistant_audio_played"; ts: number; responseId: string; offsetMs: number }
  | { type: "user_barge_in"; ts: number; interruptedResponseId: string }
  | { type: "response_cancelled"; ts: number; responseId: string }
  | { type: "tool_call_requested"; ts: number; tool: string; argsHash: string }
  | { type: "tool_call_confirmed"; ts: number; confirmationText: string }
  | { type: "handoff_to_human"; ts: number; reason: string };

有了事件日志,打断恢复不再依赖”当前内存里是什么状态”,而是可以重建:用户在什么时间插话,助手说到了哪里,哪些内容用户已经听到,哪些动作还不能算完成。

转写缓冲:不要只保存最终文本

很多团队只保存最终转写文本,这在调试语音 Agent 时不够。实时语音系统更需要保存三类材料:

  • 音频片段索引:不一定长期保存原始音频,但至少要能定位片段、时长、采样率、设备信息和噪声指标。
  • 增量转写 delta:保存 partial transcript 与 final transcript 的差异。这样才能排查模型是否在 partial 文本上过早行动。
  • 播放进度:记录助手音频实际播放到哪个 offset。模型生成了 30 秒音频,不代表用户听到了 30 秒。

如果业务涉及争议处理、客服质检或合规审计,转写缓冲还要和用户确认事件、工具调用参数、人工接管记录绑定在一起。否则事后只能看到”系统回答了什么”,看不到”用户当时到底听到了什么、确认了什么”。

工具调用:语音场景更需要确认层

实时语音 Agent 很容易把自然语言直接转成工具调用,例如查订单、改地址、取消服务、创建工单、发送短信或预约时间。问题是语音输入比文本输入更容易有误听、口误和上下文指代。

因此,工具调用建议分成三类治理:

风险等级示例策略
低风险天气查询、知识查询、FAQ 检索直接执行
中风险查询账户、生成报价、创建草稿可执行,但记录参数和来源转写
高风险支付、删除、取消、退款、外呼、修改身份信息必须二次确认,复述关键参数

确认时不要只问”是否确认”,而要复述关键参数,例如:“我将取消 7 月 8 日下午 3 点的预约,是否确认?”

可落地的工具策略可以写成配置:

tools:
  lookup_order:
    risk: low
    require_confirmation: false
    audit: transcript_and_args
  update_shipping_address:
    risk: high
    require_confirmation: true
    confirmation_fields:
      - order_id
      - new_address
    audit: transcript_args_confirmation_audio_offset
  refund_payment:
    risk: critical
    require_confirmation: true
    require_human_review: true
    audit: full_event_log

人工接管:不要等模型完全失败才转人工

语音 Agent 的人工接管要更主动。文本机器人可以让用户慢慢读错误提示,语音场景里用户的耐心更短,情绪变化更快。

建议设置几个硬触发条件:

  • 连续两次 VAD 截断
  • 连续两次 ASR 低置信
  • 用户明确表达投诉、退款、紧急、风险、法律、医疗或身份相关问题
  • 工具调用参数无法确认
  • 模型两次要求用户重复同一信息
  • 用户打断频率过高

人工接管不应只是”转客服”。更好的做法是把上下文包给人工坐席:最近 N 轮转写、用户确认过的参数、未完成工具调用、模型建议摘要、风险标签、音频片段索引。这样坐席接入时可以直接继续,而不是让用户重新说一遍。

适用场景

实时语音 Agent 适合对低延迟和自然交互有要求的场景,例如语音客服、售前导购、口语陪练、车载助手、会议助手、游戏 NPC、智能硬件、实时翻译和内部运维助手。

但它不适合一开始就覆盖所有复杂业务。涉及高价值交易、严格身份核验、医疗建议、法律判断、金融承诺和不可逆操作时,应保留文本化确认、人工审批或降级到传统流程。

常见误区

  1. 只压测模型延迟,不压测端到端对话延迟:用户感知的是麦克风采集、网络传输、VAD 等待、模型推理、TTS 生成和播放缓冲的总和。
  2. 把 VAD 当默认参数使用:不同噪声、设备、口音、语速和业务场景对阈值的要求完全不同。
  3. 只记录最终文本:实时系统要保存事件流、转写 delta、播放进度、打断点和工具参数,否则很难定位线上问题。
  4. 把 barge-in 当成 UI 功能:它本质上是会话状态机能力,需要取消旧响应、停止播放、冻结工具调用并恢复上下文。
  5. 语音工具调用不做确认:语音误听和指代错误会放大副作用风险,尤其是订单、支付、删除、退款和外呼类动作。

上线检查清单

上线前至少检查以下项目:

层级检查项
传输层接入方式是否清晰;浏览器端是否只使用临时凭证;服务端是否保存安全标识;断线重连是否会造成重复回复或重复工具调用
音频层是否覆盖不同设备、噪声、口音、语速;是否记录采样率、编码、丢包、首音频延迟和播放中断
VAD 层是否按场景配置阈值;是否有误截断、迟迟不结束、噪声误触发和用户插话测试集
会话层是否能取消旧 response;是否记录用户已听到的音频 offset;是否区分”生成完成”和”播放完成”
工具层是否按风险分级;是否有二次确认;是否记录确认文本、参数 hash 和工具结果;失败后是否能补偿或回滚
人工接管是否有明确触发条件;是否把转写、风险标签、未完成动作和上下文摘要传给人工
观测层是否有 VAD 误触发率、barge-in 成功率、首音频延迟、转写修正率、工具确认失败率、人工接管率、用户重复率和通话放弃率

FAQ

实时语音 Agent 是否一定要用 WebRTC?

不一定。浏览器和移动端直接采集播放音频时,WebRTC 通常更合适;服务器已经拿到音频流、电话系统或媒体 worker 场景,WebSocket 或 SIP 可能更自然。关键是把传输方式和鉴权、日志、重连、观测一起设计。

semantic VAD 能否完全解决抢答问题?

不能。semantic VAD 可以降低过早切分的概率,但真实对话中的停顿、犹豫、口音、噪声和多人说话仍然会造成误判。它应该和业务状态机、打断恢复、人工接管阈值一起使用。

语音 Agent 是否需要保存原始音频?

不一定。隐私要求高的场景可以只保存片段索引、转写、事件日志和必要的短期缓存。但如果涉及质检、争议处理或合规复核,就要明确音频保存范围、保留周期、访问权限和脱敏策略。

参考资料

常见问题

实时语音 Agent 应该选择 speech-to-speech 还是 ASR-LLM-TTS 串联架构?
如果目标是低延迟、自然打断和实时工具调用,优先选择 speech-to-speech;如果业务需要强审计、可替换转写或在回复前执行严格审批,串联架构更容易治理。
VAD 参数是不是越激进越好?
不是。更短的静音阈值能降低等待时间,但会增加截断、误打断和半句话提交风险。生产环境应按噪声、口音、语速和业务容忍度分场景压测。
语音 Agent 调用工具时需要用户二次确认吗?
涉及订单、支付、身份、隐私、退订、删除、外呼等有副作用操作时,应在语音层或文本层做明确确认,并保留转写、工具参数和确认事件。