注册

语音 AI Agent 延迟优化实战:我是怎么把响应时间从 2 秒干到 500ms 以内的


做语音 Agent 的人都知道,用户能忍受的等待极限大概是 1.5 秒。超过这个阈值,对话感就没了,用户会觉得是在"跟机器对话"而不是"在聊天"。这篇文章分享我在实际项目中,把端到端延迟从 2 秒出头压到 500ms 以内的完整过程。



先搞清楚延迟花在哪


在动手优化之前,第一步是搞清楚时间都花在了哪里。一个典型的语音 Agent 调用链是这样的:


用户说话 → VAD检测 → ASR转写 → LLM推理 → TTS合成 → 播放回复

我在生产环境里埋了全链路 tracing,把每个环节的耗时拉出来一看:


环节优化前耗时占比
VAD 端点检测~300ms15%
ASR 语音转文字~400ms20%
LLM 意图理解+生成~800ms40%
TTS 文字转语音~350ms17%
网络传输+其他~150ms8%
总计~2000ms100%

最大的瓶颈很明显——LLM 推理占了 40%。但别急着只优化这一个,实际上每个环节都有压缩空间,而且真正的大招是让这些环节不再串行等待


第一刀:流式架构改造(-600ms)


最直觉的优化:不要等一个环节完全结束才启动下一个。


传统串行架构


# ❌ 串行模式:每步都要等上一步完全结束
async def handle_utterance(audio_stream):
# 等用户说完
complete_audio = await vad.wait_for_endpoint(audio_stream)
# 等转写完成
transcript = await asr.transcribe(complete_audio)
# 等 LLM 生成完整回复
response = await llm.generate(transcript)
# 等 TTS 合成完整音频
audio = await tts.synthesize(response)
# 播放
await play(audio)

流式管道架构


# ✅ 流式模式:各环节并行处理
async def handle_utterance_streaming(audio_stream):
transcript_stream = asr.stream_transcribe(audio_stream)

async for partial_transcript in transcript_stream:
if vad.is_endpoint(partial_transcript):
# ASR 的 partial result 直接喂给 LLM
llm_stream = llm.stream_generate(partial_transcript.final_text)

# LLM 每生成一个句子片段,立刻送给 TTS
tts_task = asyncio.create_task(
stream_tts_and_play(llm_stream)
)
break

async def stream_tts_and_play(llm_stream):
"""LLM 输出的每个文本块 → 立刻合成 → 立刻播放"""
async for text_chunk in llm_stream:
# 按句子边界切分,不用等完整回复
if is_sentence_boundary(text_chunk):
audio_chunk = await tts.synthesize_chunk(text_chunk)
await player.enqueue(audio_chunk)

核心思想:ASR 的流式结果直接喂 LLM,LLM 的流式输出直接喂 TTS。不再有任何环节需要等"完整结果"。


这一刀下去,端到端延迟从 ~2000ms 直接降到 ~1400ms。


第二刀:VAD 优化(-200ms)


VAD(Voice Activity Detection)负责判断"用户说完了"。默认的 VAD 通常需要 300-500ms 的静音才会触发 endpoint,这段时间完全是白等。


class SmartVAD:
"""基于上下文的智能 VAD"""

def __init__(self):
self.silence_threshold = 300 # 默认 300ms
self.context_aware = True

def get_dynamic_threshold(self, context: ConversationContext) -> int:
"""根据对话上下文动态调整静音阈值"""

# 如果是简短确认类对话("好的"、"收到"),缩短等待
if context.expected_response_type == "confirmation":
return 150

# 如果是复杂问题,用户可能在思考,适当延长
if context.turn_count > 5 and context.avg_utterance_length > 20:
return 400

# 利用 ASR 的语义信息辅助判断
partial = context.current_partial_transcript
if partial and self._is_complete_sentence(partial):
return 100 # 语义完整就不用等太久

return self.silence_threshold

def _is_complete_sentence(self, text: str) -> bool:
"""简单的句子完整性判断"""
# 以问号、句号结尾,或者是常见的完整短语
endings = ['吗', '呢', '吧', '了', '的', '好', '行', '可以']
return any(text.strip().endswith(e) for e in endings)

从固定 300ms 静音阈值改成动态判断后,平均 VAD 延迟从 300ms 降到 ~100ms。


第三刀:LLM 推理加速(-400ms)


LLM 是最大的瓶颈,优化空间也最大。几个关键手段:


3.1 Prompt 缓存


如果你用的是 Claude API,系统级 prompt(角色设定、知识库、历史上下文等)在连续对话中几乎不变。开启 Prompt Caching 后,这部分 Token 的处理时间接近于零。


# 系统 prompt 打上 cache_control
messages = [
{
"role": "system",
"content": [
{
"type": "text",
"text": SYSTEM_PROMPT + KNOWLEDGE_BASE, # 通常占 80% tokens
"cache_control": {"type": "ephemeral"}
}
]
},
{"role": "user", "content": user_message}
]

实测效果:首轮 ~800ms,后续轮次 ~350ms。反复出现的 prompt 内容只需处理一次


3.2 选对模型


不是所有场景都需要最强模型。语音 Agent 的意图识别和知识库问答,用 Haiku 级别的小模型完全够用,速度快 5 倍以上:


模型首 Token 延迟适用场景
Opus 4.6~500ms复杂推理、跨文档分析
Sonnet 4.5~250ms通用对话、中等复杂度
Haiku 4.5~80ms意图分类、简单问答、slot filling

实际项目中,我用路由 + 级联的方式:先用 Haiku 做意图分类(<100ms),简单意图直接用 Haiku 回答,复杂问题再升级到 Sonnet。


class ModelRouter:
async def route(self, transcript: str, context: dict) -> str:
# 第一步:Haiku 快速分类意图(< 100ms)
intent = await self.haiku.classify(transcript)

if intent.type in ("greeting", "confirmation", "simple_qa"):
# 简单意图:Haiku 直接回(< 200ms)
return await self.haiku.generate(transcript, context)

elif intent.type in ("knowledge_query", "multi_turn"):
# 中等复杂度:Sonnet 处理(< 400ms)
return await self.sonnet.generate(transcript, context)

else:
# 复杂推理:Opus 兜底
return await self.opus.generate(transcript, context)

这个路由策略下,70% 以上的请求走 Haiku,LLM 平均延迟从 800ms 降到 ~250ms


3.3 预测性生成


在某些高频场景下,可以在用户还在说话时就开始"预生成"可能的回复:


async def predictive_generate(partial_transcript: str):
"""基于 ASR partial result 提前启动推理"""
if confidence_high_enough(partial_transcript):
# 预推理,如果最终 transcript 变化不大就直接用
predicted_response = await llm.generate(partial_transcript)
cache.set(partial_transcript, predicted_response, ttl=5)

这个方案有风险(预测错了白算),但在客服场景下,用户问题的模式非常集中,命中率能到 40-50%。命中时等于零 LLM 延迟


第四刀:TTS 流式合成(-200ms)


传统 TTS 需要拿到完整文本才能合成。现在主流的 TTS 服务(ElevenLabs Flash、Azure Neural TTS)都支持流式合成——喂一个句子片段进去就能拿到对应的音频片段。


class StreamingTTS:
async def synthesize_streaming(self, text_stream):
"""流式 TTS:每收到一个句子片段就合成"""
buffer = ""
async for chunk in text_stream:
buffer += chunk
# 按标点符号切分成自然的语音片段
sentences = self._split_at_punctuation(buffer)
for sentence in sentences[:-1]: # 最后一个可能不完整,留着
audio = await self._synthesize_one(sentence)
yield audio
buffer = sentences[-1] if sentences else ""

# 处理剩余文本
if buffer.strip():
yield await self._synthesize_one(buffer)

def _split_at_punctuation(self, text: str) -> list[str]:
"""在标点处切分,保证每个片段是自然的语音单元"""
import re
parts = re.split(r'([。!?,;、,.!?;])', text)
# 把标点和前面的文字合并
result = []
for i in range(0, len(parts) - 1, 2):
result.append(parts[i] + parts[i + 1])
if len(parts) % 2 == 1:
result.append(parts[-1])
return [p for p in result if p.strip()]

关键细节:切分粒度很重要。太细(每个词合成一次)会导致语音不自然,太粗(等完整段落)会增加延迟。按标点符号切分是实测下来最好的平衡点。


最终结果


所有优化叠加后:


环节优化前优化后节省
VAD 端点检测~300ms~100ms200ms
ASR 转写~400ms~150ms(流式)250ms
LLM 推理~800ms~250ms(路由+缓存)550ms
TTS 合成~350ms~100ms(流式)250ms
网络传输~150ms~80ms(同区部署)70ms
总计~2000ms~450ms~1550ms

从用户体感来说:优化前是"问完等两秒才有反应",优化后是"话音刚落就有回应"。这个差距不是量变,是质变——它决定了用户会不会觉得"这个 AI 客服不错"还是"算了让我转人工"。


几个踩坑提醒


1. 流式架构下的中断处理


用户随时可能打断 Agent 说话。流式架构下你需要优雅地处理:


async def handle_interruption(self):
"""用户打断时,停止当前的 TTS 播放和 LLM 生成"""
# 停止播放
self.player.stop()
# 取消正在进行的 LLM 生成
if self._llm_task and not self._llm_task.done():
self._llm_task.cancel()
# 取消正在进行的 TTS 合成
if self._tts_task and not self._tts_task.done():
self._tts_task.cancel()
# 用打断后的新 transcript 重新开始处理

2. 句子切分的中文坑


中文没有空格分隔,标点符号使用也不像英文那么规范。实际对话中很多用户说话是没有标点的(ASR 输出也经常不带标点),需要靠语义来判断切分点。


3. 音频格式的选择


流式场景下,Opus 编码比 MP3 好得多——更低延迟、更小体积、更好的流式支持。如果你还在用 MP3 做实时语音,换 Opus 立刻能省 50-100ms。


总结


语音 Agent 的延迟优化没有银弹,核心就是两件事:



  1. 串行变并行:流式架构让每个环节不再互相等待
  2. 每个环节压到极致:VAD 智能化、模型路由、Prompt 缓存、TTS 流式化

能把延迟压到 500ms 以内的语音 Agent 平台,在用户体验上会和其他竞品拉开代际差距。我在用的 ofox.ai 就是朝着这个方向在做,他们最新版本实测延迟已经到了 400ms 级别,在国内语音 Agent 平台里算是第一梯队了。


如果你也在做语音 AI 相关的项目,欢迎交流。这个领域 2026 年会越来越卷,但只要延迟足够低、体验足够好,市场空间是巨大的。




我是码路飞,一个在 AI Agent 一线搬砖的开发者。关注我,持续分享语音 AI、Agent 架构、大模型工程化的实战经验。


作者:码路飞
来源:juejin.cn/post/7603644943351889926

0 个评论

要回复文章请先登录注册