FreeSWITCH 对接阿里云流式 TTS:让大模型通话秒级响应
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 base64async 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 为其他支持流式合成的引擎
-
适用场景:
-
电话机器人
-
智能客服
-
大模型语音助手
-
实时语音翻译
-