Files

7.4 KiB
Raw Permalink Blame History

voice_test — 实时 ASR 客服机器人测试台

Chrome 麦克风 → 实时 ASR(可选多模型)→ LLM 客服人设回答 → 下拉选择 TTS 模型、预置/复刻音色并配置语速、语调、音量和表达指令;页面还可录制并下载复刻用 WAV 样本。

运行

cp .env.example .env      # 按注释填写百炼/火山凭证及地域地址
go build -o voicetest . && ./voicetest
# 程序启动时自动加载当前目录的 .env;系统环境变量优先

.env.example 已注明 API Key、Workspace ID、复刻音色及火山语音凭证的控制台获取入口;.env 已加入 .gitignore,不要提交真实密钥。

Chrome 在 HTTP 地址授权麦克风

http://localhost:8090 默认可以使用麦克风。通过局域网 IP 或域名访问 HTTP 服务时,Chrome 默认禁止 getUserMedia,开发测试可这样放行:

  1. 打开 chrome://flags/#unsafely-treat-insecure-origin-as-secure
  2. Insecure origins treated as secure 设置为 Enabled
  3. 填入完整来源,例如 http://192.168.1.10:8090,不能省略协议或端口。
  4. 点击 Relaunch 重启 Chrome。
  5. 重新打开页面,点击地址栏左侧站点图标 → 网站设置麦克风允许

也可使用独立测试配置启动 Chrome:

google-chrome \
  --user-data-dir=/tmp/voice-test-chrome \
  --unsafely-treat-insecure-origin-as-secure=http://192.168.1.10:8090

该选项仅用于受信任的开发网络;正式部署应使用 HTTPS。也可以通过 ssh -L 8090:localhost:8090 user@server 转发后访问 http://localhost:8090,无需放宽 Chrome 安全策略。

可选 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

环境变量

完整模板与参数获取方式见 .env.example

变量 默认 说明
BAILIAN_BASE_URL / BAILIAN_API_KEY / BAILIAN_WSS_BASE_URL - 阿里百炼地址与 API Key
BAILIAN_LLM_MODEL qwen3.8-flash 客服回答模型(OpenAI 兼容流式)
BAILIAN_TTS_MODEL cosyvoice-v3.5-plus 语音合成模型
BAILIAN_TTS_VOICE 默认音色或百炼复刻/设计生成的 voice_id
BAILIAN_TTS_INSTRUCTION 默认声音表达指令,网页可覆盖
BAILIAN_VOICE_API_URL DashScope 声音管理接口 查询当前账号的复刻/设计音色下拉列表
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。

两项优化:

  1. enable_thinking: false(qwen3 默认开思考,纯耗时 +0.5s,非流式实测 1.10s→0.55s
  2. 句级流式 TTS:LLM 出字遇句末标点(。!?;超长退逗号)即切句喂 TTS,不等全文

ASR 尾静音实测:语音结束→final 判定 ≈ 0.5sqwen 0.6s),max_end_pausing_time 参数在该端点不生效(垃圾参数同样延迟,服务端忽略未知参数)。

多轮对话(含 ASR 上下文注入)验证通过:两轮 finals=2 replies=2 无错误(百炼与火山均验证)。

结构

  • main.go — HTTP + /agent WS 会话编排(ASR 事件 → LLM 流式 → TTS 流式)
  • asr.go — provider 接口
  • asr_bailian.go — 百炼实时识别(run-task/continue-task 文本协议)
  • asr_volc.go — 火山 sauc bigmodel(二进制帧协议)
  • llm.go — OpenAI 兼容流式对话 + 客服 system prompt
  • tts.go — CosyVoice 流式合成(PCM16/16k
  • voices.go — TTS 模型、预置音色与百炼复刻音色列表
  • .env.example — 环境变量模板及各参数获取方式
  • web/index.html — 测试页(AudioWorklet 采集 PCM16/16k、WAV 样本录制、音量条、双栏转录)

已知简化

  • 打断依赖 ASR 产生 partial 事件;外放回声可能误触发,建议戴耳机测试。
  • 会话历史仅存内存、每连接独立;刷新页面即重置。

验证清单

已自动化验证(脚本模拟浏览器客户端,50ms/块推流)

  • 百炼 ASR 三模型协议全通:run-task → task-started → 音频流 → finish-task → task-finished
  • 识别正确性:同一句“你好,我想查询一下我的订单什么时候发货。”三模型 100% 准确
  • LLM qwen3.8-flash 流式回答,客服人设生效(口语化、无 markdown、主动要订单号)
  • TTS cosyvoice-v3.5-plus + 百炼复刻音色: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 验证

go build -o voicetest . && ./voicetest
  1. Chrome 打开 http://localhost:8090,ASR/TTS 模型及预置/复刻音色均显示为下拉框
  2. qwen-audio-3.0-asr-flash-streaming🎤 开始 → 授权麦克风
  3. 说“你好,我想查一下我的订单什么时候发货”:
    • 左栏灰色 partial 实时上屏,停顿后固化为 final
    • 延迟数字合理(<2s
    • 右栏客服回复流式出现
    • 扬声器播出 TTS(建议戴耳机)
  4. 追问“订单号是 12345”:确认多轮上下文生效(回答应引用订单号)
  5. 停止 → 重新开始,切换 fun-asr-realtime / fun-asr-flash-2026-06-15 重复 3
  6. 点停止后 asr badge 回 idle;服务端日志出现 ASR started 而非报错
  7. 点击“录制复刻样本”,录制后可试听并下载单声道 PCM WAV
  8. 火山:选 volc-bigmodel 重复 3、4(已自动化验证通过,人工复测语音即可)

🧹 清理

pkill -x voicetest

边界情况备忘

  • 远程机器:SSH 端口转发 ssh -L 8090:localhost:8090,浏览器访问 localhost:8090 仍是安全上下文,麦克风可用
  • 外放会自收音导致 ASR 把 TTS 也转写(无回声消除的浏览器实现依赖耳机)
  • 端口冲突:PORT=:9090 ./voicetest 可换