docs: add Speechmatics STT postmortem — all 4 modes failed, unusable
Detailed record of why livekit-plugins-speechmatics was removed: - EXTERNAL: no FINAL_TRANSCRIPT (framework never sends FlushSentinel) - ADAPTIVE: zero output (dual Silero VAD conflict) - SMART_TURN: fragments Chinese speech into tiny pieces - FIXED: finalize() async race condition with session teardown All tested on 2026-03-03, none viable with LiveKit agents v1.4.4. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
7fb0d1de95
commit
121ca5a5aa
|
|
@ -0,0 +1,67 @@
|
|||
# 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 timer,partial 停止 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.0`(1秒静音后 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.ts` 和 `voice-config.controller.ts` 中默认值改为 'openai'
|
||||
- web-admin 设置页中的 Speechmatics 选项和 i18n 翻译
|
||||
Loading…
Reference in New Issue