实时语音与视频Agent实践
面试定位:当面试官问“实时语音助手怎么做、延迟从哪来、Key 怎么不泄露、怎么打断”,本篇给你:端到端 vs 级联两种架构对比 → WebRTC 接入与 ephemeral key 签发 → ASR 选型 → VAD/turn detection/barge-in/音频内 function calling → 视频 Agent → 前端实现栈。
目录
场景定义
典型场景包括实时客服、语音陪练/口语老师、远程协作助手、会议摘要助手、带屏幕共享的可视化助手。共同特点是对低延迟和连续交互稳定性要求高,且需要处理不完整输入和频繁打断(barge-in)。
系统架构
两种语音架构对比(核心)
| 维度 | 端到端语音(Speech-to-Speech) | 级联(ASR→LLM→TTS) |
|---|---|---|
| 代表 | OpenAI Realtime API(GPT Realtime)、Gemini Live API | Whisper/gpt-4o-transcribe → LLM → gpt-4o-mini-tts |
| 延迟 | ~300ms,接近真人对话 | ~1-2s(三段串联累加) |
| 打断(barge-in) | 原生支持,自然 | 需自己实现,体验略逊 |
| 情感/语气/副语言 | 保留语气、语速、情绪,最自然 | ASR 丢失副语言信息 |
| 可控性 | 较弱(中间状态不可见) | 强:可在 LLM 层插 RAG、工具、审核、改写 |
| RAG / 复杂业务逻辑 | 较难深度定制 | 天然适合接知识库与业务流程 |
| 可观测/审计 | 难拿到中间文本 | 有清晰文本链路,易审计/脱敏 |
| 成本 | 音频 token 计价,较高 | 可按段计价,相对可控 |
| 适用 | 闲聊、陪练、低延迟自然对话 | 客服、强业务、需 RAG/合规审计 |
面试一句话:要“自然 + 低延迟”选端到端 Realtime;要“可控 + 接 RAG + 可审计合规”选级联;很多生产系统是混合——用端到端做交互层,关键业务走级联式工具/RAG 校验。
端到端 WebRTC 接入总架构
建议将“模型层”和“工具层”分离,避免复杂逻辑都堆在单个 Agent 内。
关键实现要点
音视频采集与传输
WebRTC 接入与信令
- 信令(Signaling):交换 SDP(媒体能力协商)与 ICE candidate(网络路径)。浏览器直连语音模型时,常用一次 HTTP POST 把本地 SDP offer 发给模型端点,拿回 answer。
- STUN/TURN:STUN 帮客户端发现自己的公网地址做 NAT 穿透;穿透失败时用 TURN 中继兜底(企业网/对称 NAT 必备)。
- 音频走媒体轨(media track)、控制/事件走 DataChannel:低延迟音频通过 RTP 媒体轨传输;会话配置、function call、转写文本、打断信号等通过 DataChannel 的事件消息收发。
临时密钥(ephemeral key)服务端签发(绝不暴露真实 Key)
核心安全原则:真实 API Key 只存后端,前端只拿短时有效的 ephemeral token。
// 后端:用真实 Key 换取短时 ephemeral token 下发给前端
// (绝不把 OPENAI_API_KEY 发到浏览器)
app.get("/api/realtime-token", async (req, res) => {
const r = await fetch("https://api.openai.com/v1/realtime/client_secrets", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, // 真实 Key 仅在服务端
"Content-Type": "application/json",
},
body: JSON.stringify({
session: {
type: "realtime",
model: "gpt-realtime",
},
}),
});
const data = await r.json();
res.json(data); // 返回短时 client_secret(数分钟有效)
});
// 前端:用 ephemeral token 建立 WebRTC 连接
const tokenResp = await fetch("/api/realtime-token");
const { value: EPHEMERAL_KEY } = (await tokenResp.json()).client_secret;
const pc = new RTCPeerConnection();
pc.ontrack = (e) => (audioEl.srcObject = e.streams[0]); // 远端语音播放
const mic = await navigator.mediaDevices.getUserMedia({ audio: true });
pc.addTrack(mic.getTracks()[0]); // 本地麦克风走媒体轨
const dc = pc.createDataChannel("oai-events"); // 事件/控制通道
dc.onmessage = (e) => handleServerEvent(JSON.parse(e.data));
const offer = await pc.createOffer();
await pc.setLocalDescription(offer);
const sdpResp = await fetch("https://api.openai.com/v1/realtime/calls?model=gpt-realtime", {
method: "POST",
body: offer.sdp,
headers: { Authorization: `Bearer ${EPHEMERAL_KEY}`, "Content-Type": "application/sdp" },
});
await pc.setRemoteDescription({ type: "answer", sdp: await sdpResp.text() });
- 弱网环境下优先保证音频流稳定,再考虑视频质量;音频采样率常用 16kHz(识别)或 24kHz(更自然)。
实时转写与语义理解
ASR 选型
| 方案 | 特点 | 适用 |
|---|---|---|
| Whisper API(openai) | 整段转写,准确率高,非流式(批) | 录音转写、会议事后摘要 |
| gpt-4o-transcribe / gpt-4o-mini-transcribe | 比 Whisper 更准、支持流式,适合实时 | 实时语音输入转写 |
| Deepgram | 低延迟流式 ASR,性价比高,支持实时关键词/分词 | 高并发实时客服 |
| AssemblyAI(streaming) | 流式转写 + 说话人分离、情感、话题等增值能力 | 会议/通话分析 |
- 采用增量转写,避免整段结束后才返回结果;对转写结果加时间戳,便于回放和纠错。
- 级联架构里 ASR 之后即可插入 PII 脱敏与内容审核。
对话控制:VAD / turn detection / barge-in / 音频内 function calling
- VAD(语音活动检测):判断“用户在不在说话”,区分语音与静音/噪声,决定何时开始/结束一段语音。
- Turn detection(轮次检测):判断“用户说完了没”,决定何时让模型开口。服务端 VAD(如
server_vad)或语义化 turn detection 可自动断句;也可手动(push-to-talk)控制。 - Barge-in(打断):用户开口时立即停止模型当前播报并清空已排队音频,模型转入聆听。端到端模型原生支持,级联需自行实现“检测到用户语音 → cancel 当前 TTS 播放”。
- 音频会话中的 function calling:在 Realtime 会话用
session.update事件声明可用工具(tools/JSON schema);模型在对话中触发 function call,后端执行(查库、RAG、下单)后把结果回灌会话,模型继续口头作答。
// 在音频会话中声明工具 + 配置 turn detection(通过 DataChannel 发事件)
dc.send(JSON.stringify({
type: "session.update",
session: {
turn_detection: { type: "server_vad", threshold: 0.5, silence_duration_ms: 500 },
tools: [{
type: "function",
name: "get_order_status",
description: "查询订单状态",
parameters: {
type: "object",
properties: { orderId: { type: "string" } },
required: ["orderId"],
},
}],
},
}));
Agent任务编排
- 把任务拆为“理解 → 决策 → 执行 → 回答”四步。
- 对外部工具调用建立超时与重试策略;高风险工具走 allowlist + schema 校验 + HITL(见 AI安全风险与防护策略)。
- 长会话用滚动摘要压缩历史,控制上下文与音频 token 成本。
视频 Agent
- 屏幕共享 / 摄像头帧推送:通过 WebRTC 视频轨或定时截帧上传,让模型“看到”屏幕/画面。
- Gemini Live video:Gemini Live API 支持实时视频输入,可做“边看边聊”的可视化助手。
- Realtime vision:在 Realtime 会话中以图像帧作为输入,结合语音做多模态实时问答。
- 帧采样策略(关键省钱点):不要逐帧送(成本爆炸)。按需采样——固定间隔(如 1fps)、场景变化触发(帧差/SSIM)、或用户提问时抓当前帧。长视频离线分析走 Gemini Files API + 关键帧 + 转写做“视频 RAG”。
中断恢复与降级
- 用户打断时保留上下文快照,快速恢复会话状态。
- 网络抖动:DataChannel 断线重连、ICE restart;TURN 兜底。
- 当高能力模型超时,自动降级到轻量模型或切换到“级联 + 文本兜底”给出临时答复。
- 端到端不可用时回退到级联架构(同一套工具/RAG 复用)。
前端实现栈
| 栈 | 说明 | 适用 |
|---|---|---|
| @openai/agents-realtime | OpenAI 官方 Realtime Agents SDK(JS/TS),封装 WebRTC 连接、工具、事件、打断 | 浏览器/Node 快速接 OpenAI Realtime |
| LiveKit Agents | 开源实时媒体基础设施 + Agent 框架,自带 SFU、电话接入、多人房间,可编排 STT/LLM/TTS 或端到端 | 自建可控、多人/电话场景、需私有部署 |
| Daily + Pipecat | Daily 提供 WebRTC 传输,Pipecat 是开源语音 Agent 编排框架(pipeline 串 VAD/ASR/LLM/TTS,可换供应商) | 供应商可插拔、跨云语音 Agent |
面试一句话:纯 OpenAI 生态用
@openai/agents-realtime最快;要自控传输/多人/电话/私有化用 LiveKit;要供应商可插拔的级联 pipeline 用 Daily + Pipecat。
评测指标
- 首响应延迟(TTFT / time-to-first-audio):端到端目标 ~300ms,级联 ~1-2s。
- 连续输出稳定性(断流率)。
- 语音识别准确率(WER / CER,中文看 CER)。
- 打断响应时延(barge-in 到模型停说的时间)。
- 任务完成率与单次会话成本(音频/视频 token + ASR/TTS 字符/分钟费)。
落地建议
- 先做单语言、级联架构跑通可控闭环,再上端到端 Realtime 优化体验。
- 先做只读工具,再逐步开放写操作与审批流程。
- 语音链路务必做 ephemeral key 签发(绝不前端暴露真实 Key)+ PII 脱敏 + 内容 moderation。
- 上线前压测网络波动、TURN 兜底、峰值并发和异常恢复链路。
相关阅读
- 多模态基础与模型能力地图
- 多模态应用架构与成本优化
- AI多模态与实时交互(索引)
- AI安全风险与防护策略:Agent 工具安全与 PII 脱敏。