Голосовой канал банка: STT → тот же текстовый агент → TTS. Покажи, что не строишь «голосовую магию», а переиспользуешь ядро.
Что говорит кандидат:
«Ключевой вопрос: у нас уже есть текстовый бот? Тогда голос — это ДВА новых слоя вокруг того же ядра: STT (речь → текст) и TTS (текст → речь) + оркестрация диалога. Не отдельный бот. Уточню: какой язык и диалект (MX-ES?), какой канал — телефон (кодек, шум) или in-app? Есть ли авторизация по голосу или по DTMF/данным? И где данные — можно ли vendor STT или нужно локально из-за PII в разговорах?»
Почему это сильно: ты сразу свёл задачу к «два слоя вокруг ядра» — это правильный рефрейм. И поднял язык/кодек/шум и PII — голосовые данные это чувствительно.
Вопрос: «Зачем вообще STT→текст? Почему не дать модели аудио напрямую?»
Ответ: «Мультимодальные модели умеют аудио, но: (1) текстовое ядро уже готово и оттестировано — RAG, тулы, политики, evals; (2) переиспользование = один источник правды для политик; (3) STT-ошибки легче логировать и мерить (WER), чем „аудио-галлюцинации". Текстовый и голосовой канал делят RAG и политики — это и есть архитектура».
Вопрос: «Ты же не делал voice?»
Ответ (честно): «Не делал. Но текстовый агент у меня есть, а голос = STT + TTS вокруг него. STT меряется WER на ваших звонках, TTS — субъективно и по латентности. Всё остальное — уже решённые задачи: RAG, router, тулы, HITL».
Что говорит кандидат:
«К метрикам текстового бота (resolution, recontact, эскалация) добавляются: WER на реальных звонках MX-ES (не LibriSpeech!), точность интента после STT, latency: время до первого звука ответа (p95), полный цикл диалога. И доля диалогов, где STT-ошибка привела к неверному ответу — это связка STT → ядро».
Вопрос: «Почему WER на ваших звонках, а не на бенчмарке?»
Ответ: «LibriSpeech — чистые англоязычные аудиокниги. У банка: испанский, телефонный кодек, шум улицы, имена, номера карт, суммы. WER на чужом бенчмарке не скажет ничего про то, как модель распознает „quinientos pesos" в шуме. Поэтому: сэмпл реальных звонков, разметка, WER + ошибки на критичных сущностях (номера, суммы) — отдельно. Плюс меня интересует не общий WER, а WER на сущностях, которые идут в тулы».
Что говорит кандидат:
«50k звонков/мес, пик 10 одновременных разговоров (телефонные линии — узкое место, не GPU). Разговор: 5 минут = 300с аудио, STT реального времени (1× фактор), TTS — быстрее речи. Задержка: STT 200–500 мс на фразу, ядро — как текстовый бот, TTS 100–300 мс. Целевой p95 «слышу ответ» — 1–2 секунды. Трафик небольшой — начнём с API, GPU не окупается».
Что рисует кандидат:
Звонок → телефонный шлюз / WebRTC
→ STT (речь → текст, потоково)
→ [ВХОД В ТО ЖЕ ЯДРО, ЧТО И ТЕКСТОВЫЙ БОТ]
input guard → router → RAG/тулы → generate → output guard
→ TTS (текст → речь)
→ лог: call_id, WER-фрагменты, latency, cost
Отдельно: авторизация (DTMF или данные), HITL — перевод на оператора
с передачей саммари диалога.
Ключевые решения:
Вопрос: «Как обработаешь, если STT ошибся в номере карты?»
Ответ: «Номер карты — критичная сущность. Варианты: (1) подтверждение вслух перед действием („карта 5290…? да/нет"); (2) cross-check: если номер не совпал ни с одной картой клиента — переспросить, не выдумывать; (3) DTMF-ввод для критичных данных — телефонная клавиатура надёжнее голоса. Для блокировки — обязательно подтверждение, это action-тул с HITL».
Вопрос: «Латентность — как уложиться?»
Ответ: «Потоково: STT отдаёт частичные результаты, ядро может начать думать на первом фрагменте. TTS — начинаем говорить первым предложением, пока генерится второе. Целевая разбивка: STT 300 мс + ядро 400 мс + TTS 200 мс ≈ 1с до первого звука. Плюс кэш частых ответов (комиссия SPEI — точный кэш)».
Что говорит кандидат:
«Копну в связку STT → ядро. WER — прокси, но решает конечная метрика: интент распознан верно? Считаю: после STT прогоняю текст через router и сравниваю интент с gold-интентом звонка. Если STT испортил сущность (сумму, номер) — это ловится отдельной метрикой ошибок на сущностях. И data flywheel: звонки, где ядро ответило неверно из-за STT, идут в выборку для дообучения STT или в few-shot для ядра».
Вопрос: «Что важнее: WER или точность интента?»
Ответ: «Точность интента. WER может быть 10%, но если ошибки на незначимых словах — ядро всё поняло. И наоборот: WER 3%, но номер карты распознан неверно — блокировка уйдёт не на ту карту. Поэтому две метрики: интент-точность после STT (сквозная) и WER на критичных сущностях. Сквозная — главная, WER — диагностическая».
Что говорит кандидат:
«Шум/кодек → WER растёт → fallback: переспросить, повторить медленнее, или HITL. STT провайдер 500 → fallback на второго/локального. Клиент перебивает → barge-in, TTS стоп. Не распознал сущность → подтверждение, не догадка. PII в разговоре → маскировка в логах, записи по политике банка. Регрессия ядра → те же evals, что у текстового бота — голос не ломает ядро, он добавляет слой».
Что говорит кандидат:
«v0: потоковый STT + существующее текстовое ядро + TTS + DTMF для критичных данных + HITL. v1: дообучение STT на звонках (если WER на сущностях не падает), биометрия голоса, больше языков. Сознательно не беру: отдельную „голосовую модель" вместо ядра, полную автоматизацию без подтверждений на деньги».
Вопрос: «С чего начнёшь?»
Ответ: «Соберу 200 реальных звонков, размечу интенты и сущности (номера, суммы), прогоню 2 STT-модели, посчитаю интент-точность и WER на сущностях. Параллельно — подключу существующее ядро к STT через API и проверю сквозной путь. TTS выберу по латентности и качеству на испанском. Текстовый бот при этом не трогаю — голос добавляет слой».
| Критерий | Ты показал |
|---|---|
| Рефрейм задачи | «Два слоя вокруг существующего ядра», не новый бот |
| Честность про пробел | «Voice не делал» + WER на их звонках |
| Голосовая специфика | Поток, barge-in, VAD, DTMF, подтверждение вслух |
| Сквозная метрика | Интент после STT, WER на сущностях |
| Безопасность | PII звонков, HITL на action |