525ab41725ade51d15d18456499d29dad94e457c
voice_test — 实时 ASR 客服机器人测试台
Chrome 麦克风 → 实时 ASR(可选多模型)→ LLM 客服人设回答 → TTS 播报,全链路验证。
运行
source ~/.zshenv # BAILIAN_* 环境变量
go build -o voicetest . && ./voicetest
# 打开 http://localhost:8090 (Chrome,需允许麦克风;仅 localhost/https 可用 getUserMedia)
可选 ASR 模型
| 模型 | 厂商 | 已验证 |
|---|---|---|
qwen-audio-3.0-asr-flash-streaming |
阿里百炼 | ✅ 支持 continue-task 上下文 |
fun-asr-realtime |
阿里百炼 | ✅ 支持 continue-task 上下文 |
fun-asr-flash-2026-06-15 |
阿里百炼 | ✅ 不支持上下文(自动跳过) |
volc-bigmodel (Doubao-Seed-ASR / sauc) |
火山引擎 | ✅ X-Api-Key 新版鉴权 |
火山需要语音技术控制台(非 VOLCENGINE_ACCESS_KEY)的凭证,两种鉴权方式自动适配:
# 新版控制台(已验证可用):单 APP Key → X-Api-Key
export VOLC_ASR_APP_KEY=...
# 旧版控制台:APP ID + Access Token → X-Api-App-Key + X-Api-Access-Key
export VOLC_ASR_APP_ID=...
export VOLC_ASR_ACCESS_TOKEN=...
export VOLC_ASR_RESOURCE_ID=volc.bigasr.sauc.duration # 2.0 用 volc.seedasr.sauc.duration
环境变量
| 变量 | 默认 | 说明 |
|---|---|---|
BAILIAN_BASE_URL / BAILIAN_API_KEY / BAILIAN_WSS_BASE_URL |
- | 阿里百炼(zshenv 已有) |
BAILIAN_LLM_MODEL |
qwen3.8-flash |
客服回答模型(OpenAI 兼容流式) |
BAILIAN_TTS_MODEL |
cosyvoice-v3.5-plus |
语音合成模型 |
BAILIAN_TTS_VOICE |
zshenv 音色 | cosyvoice-v3.5-plus + 复刻音色已验证可用 |
PORT |
:8090 |
监听地址 |
已验证的端到端指标(同一句“查询订单发货”,50ms/块推流,句级流式 TTS + 无 thinking)
| 模型 | ASR final | 首 token | 首音频 | 全轮完成 |
|---|---|---|---|---|
| qwen-audio-3.0-asr-flash-streaming | 2.04s | 2.54s | 3.35s | 5.73s |
| fun-asr-realtime | 2.17s | 2.60s | 3.31s | 5.59s |
| fun-asr-flash-2026-06-15 | 1.86s | 2.16s | 2.89s | 5.10s |
| volc-bigmodel (Doubao-Seed-ASR) | 2.60s | 4.29s | 5.18s | 7.84s |
优化前(TTS 等全文 + LLM 默认 thinking):首 token ~4.6s / 首音频 ~5.5s / 全轮 ~8.2s。
两项优化:
enable_thinking: false(qwen3 默认开思考,纯耗时 +0.5s,非流式实测 1.10s→0.55s)- 句级流式 TTS:LLM 出字遇句末标点(。!?;超长退逗号)即切句喂 TTS,不等全文
ASR 尾静音实测:语音结束→final 判定 ≈ 0.5s(qwen 0.6s),max_end_pausing_time 参数在该端点不生效(垃圾参数同样延迟,服务端忽略未知参数)。
多轮对话(含 ASR 上下文注入)验证通过:两轮 finals=2 replies=2 无错误(百炼与火山均验证)。
结构
main.go— HTTP +/agentWS 会话编排(ASR 事件 → LLM 流式 → TTS 流式)asr.go— provider 接口asr_bailian.go— 百炼实时识别(run-task/continue-task 文本协议)asr_volc.go— 火山 sauc bigmodel(二进制帧协议)llm.go— OpenAI 兼容流式对话 + 客服 system prompttts.go— CosyVoice 流式合成(PCM16/16k)web/index.html— 测试页(AudioWorklet 采集 PCM16/16k、音量条、双栏转录)
已知简化
- 无打断(barge-in):TTS 播报期间 ASR 仍在识别,建议戴耳机测试避免回声。
- 会话历史仅存内存、每连接独立;刷新页面即重置。
验证清单
✅ 已自动化验证(脚本模拟浏览器客户端,50ms/块推流)
- 百炼 ASR 三模型协议全通:run-task → task-started → 音频流 → finish-task → task-finished
- 识别正确性:同一句“你好,我想查询一下我的订单什么时候发货。”三模型 100% 准确
- LLM
qwen3.8-flash流式回答,客服人设生效(口语化、无 markdown、主动要订单号) - TTS
cosyvoice-v3.5-plus+ zshenv 复刻音色:PCM16/16k 音频正常返回(cosyvoice-v2 会报 418,勿用) - E2E 指标见上表;多轮对话 finals=2 replies=2 无错误,ASR 上下文注入生效
fun-asr-flash不支持 continue-task → 已加模型守卫自动跳过- 火山 sauc 二进制帧协议:新版 X-Api-Key 鉴权、句级 utterance definite 判定 final、负包(flags=2/3)结束,真实凭证 E2E 验证通过(含多轮)
👤 需人工在 Chrome 验证
source ~/.zshenv
cd ~/Workspace/voice_test && go build -o voicetest . && ./voicetest
- Chrome 打开
http://localhost:8090,状态栏显示“已连接”,下拉框列出 4 个模型 - 选
qwen-audio-3.0-asr-flash-streaming→ 🎤 开始 → 授权麦克风 - 说“你好,我想查一下我的订单什么时候发货”:
- 左栏灰色 partial 实时上屏,停顿后固化为 final
- 延迟数字合理(<2s)
- 右栏客服回复流式出现
- 扬声器播出 TTS(建议戴耳机)
- 追问“订单号是 12345”:确认多轮上下文生效(回答应引用订单号)
- 停止 → 重新开始,切换
fun-asr-realtime/fun-asr-flash-2026-06-15重复 3 - 点停止后 asr badge 回 idle;服务端日志出现
ASR started而非报错 - 火山:选
volc-bigmodel重复 3、4(已自动化验证通过,人工复测语音即可)
🧹 清理
pkill -x voicetest
边界情况备忘
- 远程机器:SSH 端口转发
ssh -L 8090:localhost:8090,浏览器访问localhost:8090仍是安全上下文,麦克风可用 - 外放会自收音导致 ASR 把 TTS 也转写(无回声消除的浏览器实现依赖耳机)
- 端口冲突:
PORT=:9090 ./voicetest可换
Languages
Go
65.1%
HTML
34.9%