Робот спрашивает: «Придёте завтра на приём?» В сценарии три ветки — «да», «нет», «перезвонить позже». А человек на том конце говорит: «ну я постараюсь, но если только после обеда».
Вот в этом зазоре и живёт вся сложность интерактивного обзвона. Распознавание речи отработало идеально — текст на руках, слово в слово. Осталась мелочь: понять, что человек имел в виду. Это отдельная задача, и решают её принципиально разными способами.
Речь ≠ смысл
Первое, что стоит развести: распознавание речи (STT) и классификация намерения — это два разных этапа, и второй нельзя получить бесплатно вместе с первым.
STT превращает звук в строку. Всё. Дальше у вас есть текст «ну я постараюсь, но если только после обеда» и список веток, по которым надо пойти. Соединить одно с другим — работа, которую кто-то должен сделать: или ваш код, или отдельная модель.
Последняя строка — любимая ловушка. Наивный поиск слова «да» в тексте уверенно отправит человека в ветку согласия, и завтра его будут ждать в клинике.
Четыре подхода
Вы перечисляете ожидаемые слова для каждой ветки, система ищет их в распознанном тексте. Никакого машинного обучения — обычный поиск подстроки.
Работает мгновенно, стоит ноль, полностью предсказуемо и отлаживается глазами: видно, какое слово сработало и почему. На коротких закрытых вопросах закрывает большую часть ответов — люди в разговоре с роботом действительно чаще отвечают односложно.
Ломается на: синонимах, которых нет в списке, отрицаниях («да не»), развёрнутых ответах и любой фразе, до которой автор сценария не додумался.
Тот же поиск, но умнее: слова приводятся к начальной форме («придёте», «приду», «придём» → один корень), считается расстояние между строками, чтобы пережить оговорки и огрехи распознавания.
Всё ещё быстро и бесплатно, всё ещё объяснимо. Заметно расширяет охват по сравнению с дословным поиском, особенно на русском с его склонениями.
Ломается на: том же, на чём и первый подход. Морфология — это про форму слова, а не про смысл. «Я не против» и «я против» отличаются одной частицей, а значат противоположное.
Здесь начинается смысл. Модель превращает фразу в вектор — набор чисел, положение которого отражает значение, а не написание. Вы заранее считаете векторы для эталонных фраз каждой ветки, а на звонке ищете ближайший к тому, что сказал абонент.
Главный плюс — перефразировки. «Ага, конечно», «разумеется», «а как же» окажутся рядом с «да», хотя ни одной общей буквы там нет. Модели такого класса небольшие, их реально держать у себя, и тогда данные не покидают периметр — весомый аргумент, если у вас медицина или финансы.
Цена вопроса: инфраструктура. Модель надо где-то держать, обновлять, мониторить, а качество на вашем домене — проверять самим. И принципиальное ограничение остаётся: близость векторов не понимает контекста вопроса. «После обеда» одинаково близко и к «приду», и к «перезвоните позже» — а правильный ответ зависит от того, что именно спрашивали.
Модели дают вопрос, который задал робот, список веток и фразу абонента — и просят выбрать одну ветку. Не пересказать, не объяснить, а именно выбрать из перечисленного.
Это единственный из четырёх подходов, который видит контекст. «После обеда» на вопрос «придёте?» и на вопрос «когда вам удобно перезвонить?» — разные намерения, и модель это различает. Она же вытянет смысл из «да не, не приду» и из «я не против».
Цена вопроса: задержка и деньги на каждом обращении. Плюс отдельная инженерная задача — заставить модель отвечать строго одним вариантом из списка, а не рассуждением на три абзаца.
Сравнение
| Что важно | Слова | Нечёткое | Эмбеддинги | LLM |
|---|---|---|---|---|
| Понимает перефразировку | Нет | Почти нет | Да | Да |
| Понимает отрицание | Нет | Нет | Частично | Да |
| Учитывает вопрос | Нет | Нет | Нет | Да |
| Задержка в разговоре | Незаметна | Незаметна | Небольшая | Ощутимая |
| Стоимость обращения | Нет | Нет | Своё железо | За каждый вызов |
| Понятно, почему так решил | Полностью | Полностью | Через расстояния | Не всегда |
| Что чинить при промахе | Дописать слово | Дописать слово | Эталоны, порог | Формулировку веток |
Три вещи, которые решают именно в звонке
В статьях про классификацию текста обычно сравнивают точность и на этом заканчивают. В телефонии точность — не главный критерий, и вот почему.
Пауза стоит дороже ошибки
В переписке подумать секунду — норма. В разговоре тишина после вашей реплики читается как «связь оборвалась», и человек начинает говорить поверх, переспрашивать или просто кладёт трубку. Классификатор, который отвечает точнее, но с заметной задержкой, на практике проигрывает быстрому и чуть более тупому.
Отсюда простое следствие: бюджет времени на решение фиксирован, и он маленький. Всё, что в него не влезает, не имеет значения, каким бы умным оно ни было.
Умный этап должен быть исключением, а не правилом
Если гонять тяжёлый классификатор на каждую реплику, вы платите за все ответы, включая те самые «да», которые разобрал бы поиск по словам. А таких — большинство.
Разумная схема двухступенчатая: сначала дешёвая проверка, и только когда она не дала уверенного совпадения — умный этап. Тогда расходы и задержка появляются лишь на действительно сложных ответах, а на простых сценарий работает как раньше.
Побочный эффект приятный: чем лучше автор сценария подобрал ожидаемые слова, тем реже включается дорогой этап. Аккуратно составленный сценарий буквально дешевле в эксплуатации.
Сбой не должен ронять звонок
Человек на линии, реплику надо выдать сейчас. Повторить запрос, как в вебе, нельзя — разговор идёт в реальном времени и ждать не будет.
Поэтому у классификатора обязан быть жёсткий таймаут и понятное поведение при отказе. Правильный отказ — это уход в ветку «ничего из перечисленного», ту самую, куда сценарий и так попадает, когда не разобрал ответ. Тогда даже полностью недоступный классификатор означает всего лишь «работаем как без него», а не оборванный звонок.
Это стоит закладывать в архитектуру с самого начала. Классификатор, который при недоступности бросает исключение вместо «не знаю», превращает внешний сервис в единую точку отказа для всех ваших разговоров.
Как это работает в AutoCall.kz
В интерактивных сценариях у каждого элемента распознавания есть ветка «Иначе» — куда уходит абонент, чей ответ не совпал ни с одним из ожидаемых слов. Она и есть точка подключения умного этапа: сначала отрабатывает сопоставление по словам, которые вы задали, и только не совпавшие ответы разбираются дальше — с учётом самого вопроса, а не одной лишь фразы.
Результат всегда одна из ваших веток или «Иначе» — придумать новую ветку классификатор не может по построению. А при любом сбое или превышении времени звонок уходит в «Иначе», то есть ведёт себя ровно так, как вёл бы без всякой классификации.
Практический совет для тех, кто собирает сценарии: формулируйте вопрос так, чтобы на него хотелось ответить коротко. «Придёте завтра — да или нет?» соберёт куда больше односложных ответов, чем «Хотелось бы уточнить ваши планы на завтра». Чем чётче вопрос, тем реже нужен умный этап.
Что дальше
Всё описанное — про сценарии, где ветки заданы заранее. Соседняя история — голосовые ИИ-агенты, где никаких веток нет вообще: агент ведёт разговор целиком и сам решает, что делать с ответом. Про разницу между этими подходами мы писали отдельно.
Отдельная тема, к которой мы вернёмся, — выбор омни-модели: одной модели, которая принимает звук и сразу отдаёт и текст, и смысл, без разделения на распознавание и классификацию. Это меняет расклад целиком, потому что убирает из цепочки один этап, а вместе с ним и его задержку. Про то, как мы выбираем такую модель для AutoCall.kz, будет отдельная статья.