Status: Accepted Date: 2026-04-16 Author: John Doe
Saymo auto mode должен непрерывно слушать звонок и реагировать на имя пользователя. Проблемы наивной последовательной реализации:
- Пропуск имени: пока Whisper обрабатывает чанк (~1-2с), аудио с именем может прийти и остаться необработанным
- Разрезание слов: имя попадает на границу двух чанков и не распознаётся ни в одном
- Ложные пропуски: VAD фильтр Whisper отбрасывает короткие фразы с именем
sounddevice callback thread: непрерывный захват → queue (никогда не блокируется)
↓
_transcribe_loop (async): queue → whisper → detector → triggered.set()
↓ (Event)
_trigger_loop (async): await triggered → drain queue → speak → resume
|-------- chunk 1 (4s) --------|
|-------- chunk 2 (4s) --------|
|-------- chunk 3 (4s) --------|
←── 2s ──→←── 2s ──→←── 2s ──→
- Chunk size: 4 секунды
- Overlap: 2 секунды (50%)
- Новый чанк каждые 2 секунды
- Имя на границе чанков гарантированно попадает в один из двух
Whisper часто искажает имена из-за акцента, шума или code-switching (русский ↔ английский). Пример для имени "Alexander":
- "Alexandr", "Alexnder" (акцент/шум)
- "Саш", "Саня", "Шура" (разговорные формы)
- "Aleks", "Alex" (code-switching)
Детектор принимает name_variants и опционально словарь
fuzzy_expansions из config.vocabulary.fuzzy_expansions — туда
пользователь сам добавляет наблюдаемые ошибки распознавания. Совпадение
ищется в текущем чанке и объединении с предыдущим.
vad_filter=False— отключен, чтобы не глотать короткие фразы с именемbeam_size=5, best_of=3— выше точность за счёт скоростиcondition_on_previous_text=False— каждый чанк независим
- Флаг
speaking— во время воспроизведения TTS транскрипция приостанавливается - После триггера — drain audio queue (очистка устаревших чанков)
- Cooldown 45 секунд между триггерами
Positive:
- Имя не теряется даже если Whisper занят обработкой
- Overlap гарантирует что слово на границе попадёт хотя бы в один чанк
- Fuzzy matching компенсирует неточности Whisper
- Нет feedback loop — пауза транскрипции во время speak
Negative:
- Двойная обработка overlapping участков (CPU overhead ~50%)
- Whisper small на CPU: ~1-2с на 4с чанк → эффективная задержка ~3-4с от момента произнесения имени до триггера
- Если говорят быстро после имени — 2с задержка перед speak может быть заметна
- Dedicated keyword spotter (Porcupine, OpenWakeWord): быстрее, но не поддерживает русские имена out-of-the-box
- Deepgram streaming: <300ms задержка, но требует API key и интернет
- VAD + имя detector: быстрее, но пропускает имя в потоке речи
- Полный отказ от STT: только hotkey trigger — проще, но не автоматически