Реализация голосового бота (Voice Bot) в мобильном приложении
Голосовой бот — это пайплайн из трёх звеньев: Speech-to-Text → NLP/LLM → Text-to-Speech. Каждое звено добавляет задержку. Суммарный latency меньше 1,5 секунды — это граница приемлемого для разговорного UX. Превысили — пользователь думает, что бот завис.
Оптимизация latency: где теряется время
Типичный breakdown задержки:
| Этап | Облачный вариант | Оптимизированный |
|---|---|---|
| STT (транскрипция) | 400–800ms | 200–400ms (streaming) |
| NLP / LLM ответ | 500–2000ms | 150–400ms (streaming + кэш) |
| TTS (синтез) | 300–600ms | 100–200ms (streaming) |
| Сеть (2x) | 100–300ms | — |
| Итого | 1,3–3,7s | ~1s с streaming |
Ключ к низкому latency — везде, где возможно, не ждать полного завершения предыдущего шага:
- STT с
shouldReportPartialResults = true— начинаем обработку до конца фразы - LLM streaming — как только первые токены пришли, начинаем синтез
- TTS streaming — начинаем воспроизведение, пока остаток фразы ещё синтезируется
Speech-to-Text: выбор движка
Нативные API. iOS — SFSpeechRecognizer, Android — SpeechRecognizer. Бесплатно, offline-поддержка (ограниченная). Точность для русского языка — приемлемая для коротких команд, хуже для развёрнутых фраз.
Whisper API (OpenAI). Лучшее качество транскрипции на русском, особенно с профессиональной терминологией. Задержка — 200–500ms для записи 5–15 секунд. whisper-1 модель, language: "ru".
Google Cloud Speech-to-Text. Streaming API позволяет получать partial results в реальном времени. StreamingRecognizeRequest + gRPC — минимальная задержка среди облачных вариантов.
Yandex SpeechKit. Лучшие результаты для русского среди всех вариантов (обучена на русскоязычном корпусе). Streaming распознавание через gRPC. Если бот работает только с русскоязычными пользователями — первый выбор.
// iOS: AVAudioEngine → Yandex SpeechKit streaming
class VoiceBotRecorder {
private let audioEngine = AVAudioEngine()
private var recognitionStream: RecognitionStream?
func startRecording() throws {
let inputNode = audioEngine.inputNode
let format = AVAudioFormat(commonFormat: .pcmFormatInt16,
sampleRate: 16000,
channels: 1,
interleaved: false)!
recognitionStream = speechKitClient.createStream(config: streamConfig)
inputNode.installTap(onBus: 0, bufferSize: 4096, format: format) { [weak self] buffer, _ in
guard let pcmData = buffer.int16ChannelData?[0] else { return }
let bytes = Data(bytes: pcmData, count: Int(buffer.frameLength) * 2)
try? self?.recognitionStream?.send(audio: bytes)
}
audioEngine.prepare()
try audioEngine.start()
}
}
Text-to-Speech: синтез речи
ElevenLabs. Лучшее качество речи, поддерживает русский. Streaming API через WebSocket или HTTP chunked response. Клонирование голоса — если бот должен говорить специфическим голосом бренда.
OpenAI TTS. tts-1 (быстрый) и tts-1-hd (качественный). Streaming через HTTP range requests. Голоса alloy, echo, nova и другие — для русского nova звучит наиболее естественно.
Yandex SpeechKit TTS. Для русского язык — один из лучших вариантов по naturalness. Голоса alena, filipp, jane. Streaming через gRPC.
Нативный синтез. iOS — AVSpeechSynthesizer, Android — TextToSpeech. Бесплатно, работает offline, но качество значительно ниже облачных вариантов — роботизированное звучание.
Управление аудио на мобильном
iOS. Категория AVAudioSession должна быть .playAndRecord с опцией .defaultToSpeaker. При воспроизведении TTS нужно деактивировать микрофон — иначе бот услышит сам себя (эхо). AVAudioSession.setActive(false) перед воспроизведением, true после.
try AVAudioSession.sharedInstance().setCategory(
.playAndRecord,
options: [.defaultToSpeaker, .allowBluetooth]
)
Android. AudioManager.requestAudioFocus() перед воспроизведением, abandonAudioFocus() после. Bluetooth-гарнитуры требуют отдельной обработки через BluetoothHeadset profile.
Прерывание разговора. Пользователь начинает говорить, пока бот ещё отвечает (barge-in). Нужно: детектировать начало речи пользователя → остановить TTS воспроизведение → начать запись. VAD (Voice Activity Detection) — или нативный через AudioRecord.getMaxAmplitude(), или более точный через WebRTC VAD.
Wake word и hands-free режим
Для hands-free сценариев (навигация за рулём, смарт-девайсы) — wake word детектирование: «Привет, ассистент» активирует бота без тапа. Решения: Porcupine (Picovoice) с поддержкой кастомных wake words, OpenWakeWord (open source). Работают полностью on-device, без сетевых запросов.
Процесс работы
Выбор STT/TTS движков под требования (язык, точность, latency, бюджет).
Разработка аудио-пайплайна: захват, кодирование, streaming.
NLP/LLM логика для понимания голосовых команд.
Оптимизация latency: streaming на всех этапах, кэширование частых ответов.
UI: визуализация состояний (слушает / думает / говорит), анимация звуковой волны.
Тестирование в условиях фонового шума, с разными акцентами и скоростью речи.
Ориентиры по срокам
Голосовой бот с нативными STT/TTS — 1 неделя. С облачными движками (Yandex SpeechKit / ElevenLabs), streaming и оптимизацией latency — 3–5 недель. С wake word и hands-free режимом — плюс 1–2 недели.







