语音Agent是2026年最火的AI应用方向之一,但市面上的一站式平台(Vapi、ElevenLabs Conversational AI)到底藏了多少延迟?最近HN上一个开源项目shuo给出了答案:自己搭管线,端到端延迟能压到400ms,比Vapi快整整2倍。我花了两天时间把这套架构从头跑了一遍,记录下整个过程和踩的坑。
语音Agent为什么这么难
文本聊天的交互很简单——用户打字、按发送、等回复。轮次边界由用户的”发送”按钮定义,所有延迟都可以接受。语音完全不是这回事。系统需要实时判断:用户在说话还是在听?两个状态之间的切换,就是所有难度所在:
- 用户开始说话 → 立即打断Agent,取消生成、取消TTS、清空音频缓冲
- 用户说完了 → 立即开始生成回复,延迟越低越好
判断”用户说完了”远比想象中困难。人说话会停顿、犹豫、发语气词,背景噪音也会干扰。纯粹的音量检测(VAD)根本不够用。
架构设计:把问题拆成一个状态机
整个语音Agent可以简化为一个两状态的状态机:
| 状态 | Agent行为 | 触发条件 |
|---|---|---|
| 用户说话中 | Agent静默、持续监听 | 检测到语音开始 |
| 用户听取中 | Agent生成回复并播放 | 检测到语音结束 |
两个状态转换就是核心:barge-in(打断)和turn-end(轮次结束)。所有优化都围绕这两个转换的速度展开。
第一步:VAD + 预录音频验证架构
先不管STT/LLM/TTS,用最简单的方式验证核心循环能不能跑通。技术栈:
- FastAPI处理WebSocket连接
- Twilio做电话接入,流式传输μ-law音频(8kHz、20ms帧)
- Silero VAD做语音活动检测(模型仅2MB)
import asyncio
from silero_vad import load_silero_vad, get_speech_timestamps
model = load_silero_vad()
class TurnState:
def __init__(self):
self.user_speaking = False
async def on_audio_frame(self, frame, ws):
# Silero VAD判断是否有语音
speech_prob = model(frame, 8000).item()
if speech_prob > 0.5 and not self.user_speaking:
# 用户开始说话 → 立即打断Agent
self.user_speaking = True
await ws.send_json({"event": "clear"}) # 清空Twilio音频缓冲
elif speech_prob < 0.3 and self.user_speaking:
# 用户停止说话 → 播放预录回复
self.user_speaking = False
await self.play_prerecorded(ws)
这一步的意义:隔离测试轮次检测逻辑,拿到延迟基线。预录音频的响应几乎是瞬时的,所以后面加上STT/LLM/TTS后,增加的延迟就是管线本身的开销。踩坑:Silero VAD对短停顿非常敏感。用户说话中间稍微停一下,VAD就判定结束了。纯VAD做turn detection在实际对话中根本不可用,必须结合语义信号。
第二步:Deepgram Flux替代VAD
Deepgram的Flux API把语音识别和轮次检测合并到了一个模型里。输入音频流,输出两种关键事件:start_of_turn和end_of_turn(附带转写文本)。这是一个重大升级——Flux不仅看音频信号,还看语义内容来判断用户是否说完了。”我想要那个…”后面停顿,Flux不会急着切轮次,因为语义上句子没说完。
async def handle_flux_events(flux_ws, agent_pipeline):
async for event in flux_ws:
if event["type"] == "end_of_turn":
transcript = event["transcript"]
# 用户说完了 → 启动Agent回复管线
await agent_pipeline.start_turn(transcript)
elif event["type"] == "start_of_turn":
# 用户开始说话 → 打断一切
await agent_pipeline.cancel() # 停LLM生成
await agent_pipeline.flush() # 停TTS
await twilio_ws.send_json({"event": "clear"})
第三步:STT → LLM → TTS全流式管线
这是整套架构的核心。当Flux发出end_of_turn信号后,三级管线同时启动:
- LLM流式生成:转写文本+对话历史发给LLM,拿到第一个token就立即往下传
- TTS流式合成:LLM输出的token实时喂给ElevenLabs的WebSocket TTS
- 音频流式播放:TTS产出的每个音频包直接转发到Twilio
关键:三级管线是流式衔接的,不是等上一步完成再开始下一步。LLM吐出第一个token的瞬间,TTS就开始合成了。
class AgentPipeline:
def __init__(self):
# 预热TTS WebSocket连接池(关键优化!)
self.tts_pool = WebSocketPool(
url="wss://api.elevenlabs.io/v1/text-to-speech/...",
size=3
)
async def start_turn(self, transcript: str):
self.cancelled = False
# 从连接池拿一个预热好的TTS连接
tts_ws = await self.tts_pool.acquire()
# LLM流式生成
async for chunk in self.llm.stream_chat(transcript):
if self.cancelled:
break
# 实时把文本喂给TTS
await tts_ws.send({"text": chunk.content})
# 告诉TTS文本发完了
await tts_ws.send({"text": "", "flush": True})
async def cancel(self):
self.cancelled = True
一个省了300ms的优化:TTS的WebSocket连接必须预热。每次新建WebSocket到ElevenLabs要几百毫秒的握手时间,维护一个连接池(3个预连接的socket),turn开始时直接从池里取,省掉了约300ms。
延迟对比:地理位置比模型选择更重要
先看本地运行的结果(作者在土耳其的偏远木屋里测试):
| 部署方式 | TTFT (首token) | 端到端延迟 | 体感 |
|---|---|---|---|
| 本地(土耳其) | ~1300ms | ~1700ms | 明显卡顿,对话不自然 |
| Railway EU | ~300-500ms | ~790ms | 流畅,接近自然对话 |
| Railway EU + Groq | ~80ms | ~400ms | Agent回复比人还快 |
| Vapi(同配置) | – | ~840ms | 正常 |
从1700ms到400ms,4倍提升。最大的两个因素:1. 服务器和API提供商同区域部署音频包在三个外部服务之间来回跳转(Twilio → Deepgram → LLM → ElevenLabs),每一跳都有网络延迟。把编排服务器部署到跟API提供商同一区域(EU),直接省掉了900ms。2. LLM的TTFT是瓶颈中的瓶颈在语音管线里,LLM的首token时间(TTFT)决定了整条管线能多快开始产出音频。作者测了360次请求,结果很清楚:
| 模型 | TTFT (中位数) | 备注 |
|---|---|---|
| Groq llama-3.3-70b | ~80ms | 比人眨眼还快 |
| gpt-4o-mini | ~250ms | 还行 |
| gpt-4o | ~400ms | 语音场景太慢 |
| Claude Sonnet | ~350ms | 文本好用,语音嫌慢 |
Groq的80ms TTFT碾压所有云端LLM API。换上Groq之后,对话体验质变——Agent回复快到人类跟不上。
自建 vs 平台:什么时候该自己搭
跑完整个流程,我的判断:用Vapi/ElevenLabs的场景:
- 快速原型验证,不关心延迟细节
- 团队没有实时音频处理经验
- 标准的客服/助手场景,延迟800ms够用
自建管线的场景:
- 延迟是核心体验指标(400ms和800ms体感差距巨大)
- 需要深度定制轮次检测逻辑
- 想控制成本(API调用按量计费,平台还要加一层抽成)
自建的核心代码量其实不大——shuo项目总共就几百行Python。难度不在代码,在于理解每一层的延迟来源和优化手段。
如果你也想试
最小化复现步骤:
- 注册Twilio账号,买一个电话号码($1/月)
- 注册Deepgram(有免费额度),拿到Flux API key
- 注册Groq(免费),拿到API key
- 注册ElevenLabs(有免费额度),拿到TTS API key
- clone shuo仓库,配置环境变量,部署到Railway/Fly.io
git clone https://github.com/NickTikhonov/shuo.git cd shuo cp .env.example .env # 填入 TWILIO_*, DEEPGRAM_API_KEY, GROQ_API_KEY, ELEVENLABS_API_KEY pip install -r requirements.txt python main.py
部署时注意:服务器一定要选跟API提供商同区域。选美西还是欧洲取决于你用的服务商的数据中心位置,选错了延迟直接翻倍。
写在后面
语音Agent的技术栈在2026年已经相当成熟了。Silero VAD、Deepgram Flux、Groq推理、ElevenLabs TTS——每一层都有优秀的专业供应商。真正的技术门槛不在单个组件,而在流式编排:怎么让数据在组件之间不停顿地流动。400ms的端到端延迟意味着什么?意味着AI语音对话已经比大多数人类客服的反应速度还快。接下来的问题不是”能不能做到实时”,而是”实时对话能做什么新东西”。项目地址:github.com/NickTikhonov/shuo原文:ntik.me/posts/voice-agent