1. 背景问题
在电话机器人或语音交互系统中,如果你使用大语言模型(LLM)来生成回复文本,常见流程是:
用户说一句话
ASR(语音识别)得到完整文本
将文本发给大模型
大模型生成完整回复文本(几百字)
将完整文本送给 TTS(语音合成)生成音频
FreeSWITCH 播放音频给用户
这种模式的问题是:
延迟高:大模型生成需要几百毫秒到几秒,TTS 合成也需要时间。
对话割裂:用户会在电话另一端等待“思考中”的静默期,体验很差。
如果用户问一个长问题,模型一次性返回长答案,整个延迟可能 3~5 秒甚至更多,电话交互就卡顿了。
2. 解决思路 — 流式 TTS + 首 token 启播
阿里云 TTS(智能语音交互)支持流式模式:
你可以一边发送文字,一边获取语音流数据。
即便只给出一个字,TTS 也会开始合成并返回音频帧。
这样我们可以改造流程:
用户语音 → ASR → 得到文本
把文本发给大模型,订阅流式输出(首 token 先到)
在收到第一个 token 时立刻送给 TTS
TTS 立即开始合成音频,并流式返回
FreeSWITCH 通过 自定义播放模块,边收音频边播放给用户
大模型后续 token 到来时,继续推送给 TTS,TTS 持续返回音频流
这样用户几乎可以在大模型说第一个字时就听到声音,延迟从几秒降到亚秒级。
3. 系统架构设计
┌──────────────┐
│ FreeSWITCH │
│ (通话接入) │
└─────┬────────┘
│ RTP/PCM
▼
┌──────────────┐
│ ASR 服务 │
│ (可用阿里云) │
└─────┬────────┘
│ 识别文本
▼
┌──────────────┐
│ 大模型(LLM)│
│ 流式输出 │
└─────┬────────┘
token流
▼
┌──────────────┐
│ 阿里云 TTS │
│ 流式合成 │
└─────┬────────┘
音频流
▼
┌──────────────┐
│ FreeSWITCH │
│ 边收边播 │
└──────────────┘
4. 关键实现步骤
4.1 LLM 端:流式输出
以 OpenAI/阿里云灵积等为例,你需要用 WebSocket 或 SSE 接口获取流式 token:
for event in llm_stream():
token = event["content"]
send_to_tts(token) # 每来一个 token 就推送给 TTS
4.2 阿里云流式 TTS 接口调用
阿里云的流式 TTS 接口支持 WebSocket 推送 音频帧:
import websockets
import asyncio
import base64
async def tts_stream(text_chunks):
async with websockets.connect(TTS_WS_URL) as ws:
for chunk in text_chunks:
await ws.send(make_tts_request(chunk))
await ws.send(make_tts_end_signal())
async for msg in ws:
audio_data = parse_audio(msg) # base64解码
send_audio_to_fs(audio_data) # 推给 FreeSWITCH RTP
text_chunks
来自大模型实时 token 拼接send_audio_to_fs()
可以用 mod_socket、mod_external_media 或 RTP 直推实现
4.4 避免“卡头”问题
为了保证流畅,建议:
大模型 token 到来即送 TTS,不要等完整句子
可以延迟播放 100~200ms 缓冲,防止网络抖动
对短停顿(标点符号)做实时送段,让语音自然
5. 性能与延迟对比
模式 | 首字播放延迟 | 整句播放延迟 |
---|---|---|
全量 LLM → 全量 TTS | 10~15 秒 | 同首字延迟 |
流式 LLM → 流式 TTS | 2-3 秒 | 与说话同步 |
实测中,用户在电话另一端几乎能感受到人类对话般的即刻回应,而不是等机器人“想完再说”。
6. 总结与价值(有问题可嘉我1869731,欢迎探讨)
延迟大幅下降:从几秒降到亚秒级
体验提升:对话更加自然连贯,几乎无静默
可扩展性强:可替换阿里云 TTS 为其他支持流式合成的引擎
适用场景:
电话机器人
智能客服
大模型语音助手
实时语音翻译