it0/packages/services/voice-agent/SPEECHMATICS_POSTMORTEM.md

3.4 KiB
Raw Blame History

Speechmatics STT 集成失败记录 (2026-03-03)

结论

Speechmatics 的 livekit-plugins-speechmatics 插件完全不可用。 经过一整天的深度集成和调试,四种 Turn Detection 模式全部失败,没有任何一种能在 LiveKit agents 框架 v1.4.4 下正常工作。该方案已被彻底移除STT 回退至 OpenAI。

测试的四种 Turn Detection 模式及失败原因

1. EXTERNAL 模式

  • 现象: 只有 INTERIM_TRANSCRIPT永远没有 FINAL_TRANSCRIPT
  • 原因: EXTERNAL 模式需要客户端手动调用 client.finalize() 才会产生 FINAL。 但 LiveKit agents 框架在 VAD 检测到说话结束后不调用 stream.flush() (不发 FlushSentinel而是推送静音帧 + 等待 FINAL 事件。 结果: 2 秒超时 → "final transcript not received" → 用户无回复。
  • 尝试的修复: monkey-patch _process_audio 在 FlushSentinel 时调用 finalize() → 但 FlushSentinel 根本不会到达(框架不发 flush
  • 尝试的修复 2: debounce timerpartial 停止 400ms 后自动 promote 为 FINAL → 能工作但产生重复 FINAL每个 FINAL 触发 LLM 请求导致前一个被 abort

2. ADAPTIVE 模式

  • 现象: 零转写输出,完全静默
  • 原因: ADAPTIVE 使用 Speechmatics SDK 内置的 Silero VAD 做客户端转弯检测, 但 LiveKit 自己也有 Silero VAD 在运行,两个 VAD 冲突导致音频流被截断

3. SMART_TURN 模式

  • 现象: 连续语音被切成碎片("有好结果。"、"收?的知识。"、"就。"
  • 原因: 服务器端智能转弯检测过于激进,把中文连续语音切成小段, 每段各自产生一个 FINAL_TRANSCRIPT每个 FINAL 触发一次 LLM 请求, 前一个请求被 abort实测完全不可用

4. FIXED 模式(最后尝试)

  • 配置: end_of_utterance_silence_trigger=1.01秒静音后 finalize
  • 现象: 仍然不工作
  • 原因: VoiceAgentClient 内置的 END_OF_UTTERANCE handler 调用 finalize() 但 finalize() 是异步链create_task → emit() → _stt_message_queue → _emit_segments 经常输掉与 session teardown 的竞争

额外发现的问题

语言码兼容性

  • Speechmatics 使用 ISO 639-3中文为 "cmn"LiveKit 的 LanguageCode("cmn") 会自动归一化为 "zh",而 Speechmatics API 不接受 "zh"
  • 需要手动 stt._stt_options.language = "cmn" 绕过

延迟

  • 即使在能产生转写的情况下Speechmatics 的延迟也明显高于 OpenAI
  • OpenAI Realtime API (gpt-4o-transcribe) 约 10 秒端到端Speechmatics 超过 35 秒

时间线

  • 09:00 开始集成 livekit-plugins-speechmatics
  • 10:00 解决语言码映射问题
  • 11:00 发现 EXTERNAL 模式无 FINAL开始 monkey-patch
  • 13:00 发现 FlushSentinel 永远不到达,理解框架架构
  • 14:00 实现 debounce timer能转写但有重复问题
  • 15:00 搜索官方文档,切换到 SMART_TURN → 语音碎片化
  • 16:00 切换到 FIXED 模式 → 仍然不工作
  • 17:00 放弃,彻底移除所有 Speechmatics 代码,回退至 OpenAI

删除的文件

  • src/plugins/speechmatics_stt.py — 整个 Speechmatics STT 工厂
  • requirements.txt 中的 livekit-plugins-speechmatics>=1.0.0
  • agent.py 中的 speechmatics 分支
  • docker-compose.yml 中的 SPEECHMATICS_API_KEY
  • voice-config.entity.tsvoice-config.controller.ts 中默认值改为 'openai'
  • web-admin 设置页中的 Speechmatics 选项和 i18n 翻译