Мы построили систему речевой аналитики на базе искусственного интеллекта. Она распознаёт речь, выделяет проблемные диалоги и автоматически оценивает качество звонков. Рассказываю, как мы выстраивали пайплайн распознавания и анализа речи, боролись с искажениями моделей и добивались того, чтобы ИИ понимал разговорную речь не хуже человека.

Исходные условия, или как зародился проект

С компанией Ленремонт мы в Aiston работаем не первый месяц. Это крупнейшая в России сеть ремонтных мастерских и сервиса по ремонту бытовой техники на дому. Недавно команда обратилась к нам с новой задачей. 

В колл-центре компании работают диспетчеры, которые принимают звонки от клиентов, оформляют заявки, согласовывают выезды мастеров, решают спорные ситуации. В день через линию проходит примерно 18 тысяч разговоров. И все эти звонки нужно контролировать и проверять, соблюдаются ли корпоративные стандарты и требования. 

Проблема в том, что вручную прослушать такое количество звонков невозможно: это запредельное количество для 10 человек в отделе контроля качества (ОКК). Такая ситуация приводила к тому, что:

  • отдел прослушивал рандомно около 10% звонков, из этого объёма примерно в 10% случаев находились ошибки операторов — общая картина проблем оставалась неизвестной;

  • несмотря на наличие критериев, оценки могли быть субъективными и зависеть от конкретного проверяющего, его настроения и внимательности в конкретный момент;

  • мотивация и обучение сотрудников опирались на ручные и нерепрезентативные показатели (опять же, из-за субъективности);

  • компания не могла оперативно понять причины проблем и вовремя скорректировать сценарии общения.

В итоге падала общая эффективность колл-центра — вместе с качеством сервиса и продажами.

Решили построить систему на базе ИИ

К этому моменту мы уже работали над несколькими проектами с применением ИИ и речевых технологий. Сразу поняли, что такие инструменты отлично лягут в решение задачи, поэтому сразу предложили пойти по пути автоматизированной речевой аналитики.

Система на основе искусственного интеллекта должна была взять на себя весь рутинный анализ и сделать сам процесс контроля быстрым и стандартизированным. 

Главная цель была не заменить человека, а дать специалистам возможность сфокусироваться на действительно проблемных звонках, где требуется экспертная оценка и разбор ситуации. 

На разработку системы ушло два с половиной месяца.

Если кратко: построили пайплайн на WhisperX, Pyannote и Mistral NeMo для транскрибации, диаризации и смыслового анализа. Разработали собственную систему критериев и методику оценки, чтобы ИИ понимал разговоры как человек.

Далее подробно о том, как мы создавали систему шаг за шагом.

Большое проектирование: от ревизии данных до логики оценки

С самого начала мы понимали, что для правильной работы системы искусственного интеллекта нам потребуется четкий набор исходных данных — критерии оценки и инструкции, по которым модель сможет анализировать звонки.

Вместе с Заказчиком разработали и описали текущие процессы оценки

Чтобы разделить контексты и снизить вероятность искажения оценок, выделили 4 основных типа коммуникации:

  1. Диспетчер — принимает заявки клиентов и фиксирует детали заказа.

  2. Мастер — связывается с клиентом для уточнения деталей и выполнения работ.

  3. Отдел контроля качества (ОКК) — обзванивает клиентов после обслуживания, чтобы оценить качество сервиса.

  4. Телемаркетинг — делает исходящие звонки с предложениями услуг.

Изначально рассматривали только три, но добавили телемаркетинг по запросу Заказчика.

Возник вопрос: что считать качественным разговором?

Нам выдали огромный список критериев, которыми ежедневно пользовались сотрудники ОКК. Мы решили проверить, как критерии работают в звонках и насколько они измеримы на практике.

Задача сразу осложнилась тем, что фильтры записей внутреннего хранилища Заказчика работали некорректно, поэтому в выборку для выгрузки попадали внутренние разговоры, тестовые записи и звонки, не относящиеся к проекту. 

Пришлось часть аналитики делать вручную.

Всего в выборку отобрали по 10 разговоров каждого типа коммуникации и пришли к пониманию, что изначальный список критериев был скорее теоретическим. Реально в оценке использовались лишь 3-4. Всё остальное либо не фиксировалось, либо игнорировалось.

Формула хорошего разговора

Мы заново пересмотрели структуру оценки, чтобы привести оценку к рабочему виду. 

Шаг 1. Выделили четыре основные группы, которые задали логику анализа для модели:

  • структура разговора — как сотрудник поэтапно выстраивает диалог;

  • коммуникативные навыки — насколько речь ясная и вежливая, без ошибок;

  • следование скриптам и регламентам — насколько точно выполняются внутренние стандарты и сценарии общения;

  • обработка конфликтных ситуаций — как сотрудник работает с возражениями.

Шаг 2. Каждую группу декомпозировали на четкие языковые, поведенческие или структурные элементы, которые модель сможет распознать. 

Например: в структуре разговора — приветствие, выявление потребности, корректное завершение диалога; в коммуникативных навыках — запинки, слова-паразиты, эмоциональная окраска, доступность речи.

На этой базе мы собрали обновлённый набор критериев для каждого типа коммуникации — диспетчера, мастера, отдела контроля качества и телемаркетинга. 

Позже добавили отдельный набор критериев для анализа поведения клиента — например, если он грубит, отказывается от услуги или проявляет агрессию. Эти данные не влияют на оценку сотрудника, но дают дополнительную аналитику по качеству коммуникации.

Шаг 3. Каждый критерий получил описание и шкалу оценки:

  • бинарную (0/1) для тех, где признак чётко фиксируется или отсутствует, без промежуточных состояний (наличие приветствия, заключения и др.); 

  • многоуровневую (0–3) для тех, где качество признака можно оценить по степени выраженности.

Шкала подбиралась исходя из того, насколько стабильно и предсказуемо нейросеть может распознать критерий. В финальной версии все критерии разделили на положительные и отрицательные, чтобы видеть оценку по балансу.

Шаг 4. Брейнштормили некоторое время, чтобы определить, как должна формироваться итоговая оценка. 

Нужно было сбалансировать положительные и отрицательные сигналы и сделать так, чтобы система не штрафовала за ошибки, а видела весь контекст. 

Придумали подход, где итоговая оценка = сколько плюсов набрал + сколько минусов избежал, нормализованное по максимальному возможному числу критериев.

В результате формула:

(факт_положительных + максимум_отрицательных – факт_отрицательных) / сумма_максимум × 10

позволила получать честную, сопоставимую оценку по шкале 0–10 — одинаково понятную и для модели, и для отдела контроля качества.

Перевели аудио в структурированный текст

Выбрали WhisperX — большую языковую модель для распознавания речи, которую адаптировали под русский язык. Она конвертировала аудио в JSON: каждая реплика шла с тайм-кодом, идентификатором спикера и фразой. 

При первых тестах стало ясно, что идеального результата добиться тяжело: 

  • реплики собеседников иногда “слипались” в один блок; 

  • у некоторых звонков все фразы попадали под одного спикера; 

  • тайм-коды сбивались, и модель теряла последовательность разговора.

Чтобы решить эти проблемы, хотели ввести отдельный “ремонтный” шаг — отдельную, промежуточную нейросеть для автоматического разделения фраз и выравнивания тайм-меток. Но из-за нестабильности данных и сильного разброса по длительности звонков этот шаг все усложнял, поэтому его решили отключить.

Позже нашли решение попроще: сделали тот же ремонтный этап внутри LLM, которую выбрали как основную (Mistral NeMo). Она не гарантирует идеального результата, но работает надёжнее и проще в поддержке.

Придумали цепочку промптов, чтобы модель понимала, кто говорит и как этот разговор оценивать

Здесь началась основная работа с проектированием промптов. Тестировали разные версии: 

Подробный промпт с полным описанием критериев и примерами для пограничных случаев. 

Например, модель получала инструкцию вроде:

“Если оператор перебивает клиента, это снижает оценку по критерию ‘комфортность диалога’. Если делает паузу и уточняет вопрос — наоборот, повышает.”

Такой подход давал высокую точность, но промпт занимал слишком много контекста и снижал стабильность вывода на длинных диалогах — модель могла “залипать” на длинных текстах или путать роли спикеров.

Упрощённая версия. Из промпта удалили всё, что не влияло на вывод в значительной мере. Логика критериев была упрощена и ускорена, но модель всё ещё могла ошибаться или пыталась добавить в ответ всё, что считала «удачным примером». 

Например, при фразах вроде «ага, сейчас посмотрю» она иногда интерпретировала это как корректное завершение разговора или подтверждение задачи, хотя по контексту это было просто филлер. 

На диалогах не самого лучшего качества такие случаи приводили к галлюцинациям и шумным ответам, поэтому из промпта полностью убрали всё, связанное с примерами.

One-shot / Few-shot learning. Тестировали подход, при котором модели помимо списка критериев передавались один или несколько примеров ввода и вывода, чтобы приблизить результат к ожидаемому образцу. Например:

Вход: «Здравствуйте, это мастер из Ленремонта, по заявке 345...»

Выход: { "приветствие": 1, "идентификация": 1, "вежливость": 1 }

Идея работала: на коротких звонках модель действительно начинала лучше понимать формат задачи и структурировать ответ ближе к шаблону. Но из-за ограничений окна контекста полноценное применение оказалось невозможным — при длинных транскриптах контекст быстро исчерпывался, и оценки критериев становились субъективными и нестабильными.

Гибридный промпт. Финальный вариант — это минимальный по объёму, без примеров, но с жёстко зафиксированной структурой вывода в JSON. Такой формат оказался самым стабильным и удобным в обработке.

В итоге цепочка анализа строится так:

Первым стал ASR-fix — слой, который фиксит результаты транскрипции. Он убирает склейки реплик, но не трогает таймкоды — мы поняли, что лучше пересчитывать их на бэкенде, чем терять точность.

Второй промпт — роль и тип. Определяет, кто говорит и к какому типу относится звонок. На этом этапе сталкивались с путаницей в ролях, поэтому пришли к протоколу эксклюзивности: в звонке может быть только два участника, без смены спикеров посреди разговора.

На третьем этапе подключаются 4 профильных промпта — оператор, мастер, ОКК и телемаркетинг. Они уже отвечали за аналитику: вычленяли критерии и выставляли оценки. 

Чтобы исключить галлюцинации моделей, ввели строгое правило доказательства: если модель не находит подтверждения критерию в тексте транскрибации — балл 0.

Заранее задали JSON-схему, допустимые значения и шкалы, запретили домыслы и зафиксировали формат вывода. Если ответ не соответствует схеме — валидатор его отбрасывает, звонок идёт на повтор. Это оказалось надёжнее любых постфильтров.

Каждый промпт в итоге включает:

  • роль модели;

  • краткую задачу;

  • инструкции;

  • ограничения — фиксированные значения;

  • формат вывода — строгий JSON;

  • анти-поведение — список запретов.

Дополнительно ввели негативные примеры, чтобы улучшить обработку пограничных случаев.

Определили, какая модель справится с анализом

Изначально вся система работала на Qwen. Reasoning-модель хорошо справлялась с анализом смысла на тестовых примерах, но нестабильно держала длинные цепочки промптов. 

На той версии Ollama, которую мы тогда использовали, у Qwen3 иногда возникала особенность: при определённых типах диалогов модель могла без видимых причин уходить в цикл. Точные триггеры такого поведения до конца не определены, но сейчас оно проявляется только в двух случаях: при переполнении окна контекста или при наличии противоречащих друг другу правил внутри промпта.

Чтобы исключить неточности, провели собственное исследование и сравнили альтернативы. Тестировали 7 моделей: Gemma2, Gemma3, Qwen3, Mistral NeMo, Mixtral, Llama, Hermes-Llama 3.1).

Для этого задали три критерия оценки:

  1. точность — насколько правильно модель классифицирует роли и извлекает критерии;

  2. стабильность — выдает ли она валидный JSON без зацикливаний, “галлюцинаций” и обрывов;

  3. скорость средней задержки вывода — сколько секунд в среднем занимает обработка одного звонка.

Внутренние рассуждения (reasoning) мы оставили выключенным, кроме Qwen3: у неё с reasoning действительно росло качество, но стабильность падала.

Все модели работали по единым правилам: один JSON-контракт и одинаковые условия тестирования. На каждый тип диалога приходилось около 60 выводов моделей — этого объёма хватало, чтобы увидеть различия в стабильности и качестве. 

Каждая правка промпта требовала новой генерации этих выводов и их ручного пересмотра: приходилось отдельно проверять каждый результат, искать отличия и оценивать, насколько корректно модель отрабатывает критерии по конкретному диалогу.

Вручную такое количество анализировать было сложно, поэтому мы собрали автоматический скрипт на Python. Логика в коде простая, но надёжная:

  • каждая транскрибация и промпт хранятся как отдельные задачи с уникальными идентификаторами;

  • если ответ не проходит валидацию по JSON-схеме — он автоматически отклоняется и задача повторяется;

  • результаты сохраняются в структуре output_<model>_<dialog>.json, что позволяет агрегировать данные для аналитики и сравнения моделей.

После сотен автоматических тестов выделили чемпиона: Mistral NeMo стал самой надёжной моделью, которая аккуратно правила транскрипты, уверенно определяла роли и держала контракт без ошибок.

Оптимизировали пайплайн

На первых этапах весь конвейер занимал до двух минут на один звонок. Чтобы оптимизировать процесс:

  • ввели ограничение на количество одновременно запущенных процессов и добавили параллельную обработку звонков для быстрой работы;

  • добавили диаризацию для деления аудио на спикеров — это резко уменьшило ошибки смешения реплик.

Финальная сборка пайплайна выглядела так: 1) WhisperX; 2) Pyannote; 3) Mistral NeMo.

Как бэкенд собирает, распределяет и анализирует звонки

Основная логика построена на двух Python-сервисах, работающих как цепочка задач. 

Первый сервис — это обёртка на Django. Он принимает запросы от основной системы «Ленремонта» и передаёт их в нужные модели.

Внутри компании есть собственная телефония на Asterisk: все звонки попадают туда, а дальше через API — к нам. Django-сервис принимает аудиофайлы, ставит их в очередь и отправляет либо в Whisper для транскрибации, либо в LLM для анализа.

После завершения обработки он возвращает результат через вебхук.

Второй сервис отвечает за управление пайплайном. Раз в 5 минут он запрашивает новые записи звонков, ставит их в очередь и поочерёдно запускает шаги обработки. 

Каждый шаг асинхронный: когда модель завершает работу, результат уходит на вебхук, и запускается следующая задача в цепочке. Так формируется полностью автоматический цикл от звонка до отчёта.

Как выглядит система

Система реализована как отдельный модуль «Диалоги с клиентами» — с тремя основными вкладками: звонки, сотрудники, заявки.

Каждая вкладка открывает свой срез аналитики.

В «Звонках» отображаются все разговоры с клиентами

Это основное окно мониторинга. Здесь собраны все звонки с ключевыми параметрами: номер клиента, сотрудник, длительность, дата и время, оценка. 

Здесь же отображаются аналитические отметки — теги, присвоенные системой после анализа разговора.

В верхней панели добавили фильтры, чтобы сотрудник ОКК мог быстро отфильтровать звонки: например, увидеть все звонки со спорной оценкой ниже 6 и тегом ‘Жалоба’.

Внизу блока — сводная статистика, чтобы видеть живую нагрузку на контакт-центр.

В «Карточке диалога» — вся сводная аналитика по звонку

Карточка диалога объединяет все данные по звонку: транскрибацию разговора, аналитику по критериям, итоговую оценку и метрики оператора.

Здесь сразу видно, к какой заявке и какому сотруднику относится разговор. Справа отображается аналитический блок с баллами по каждому критерию, а слева — контекст заявки, оператора и клиента.

Всё синхронизировано с аудиоплеером, так что можно одновременно слушать и анализировать.

В разделах «Сотрудники» и «Заявки» система показывает разные срезы аналитики

Из общего списка звонков можно перейти во вкладки «Сотрудники» и «Заявки».

  • В первой можно посмотреть аналитику по каждому оператору — все его звонки, средний балл и оценки по критериям.

  • Во второй — историю взаимодействия с клиентом в рамках конкретного заказа, включая статусы заявок и результаты звонков.

Такая структура позволяет сравнивать показатели сотрудников и отслеживать качество обработки заявок в динамике.

После внедрения системы контроль качества в колл-центре стал полностью автоматизированным

Если раньше отдел успевал проверять не больше 10% звонков, то теперь система охватывает 99% разговоров. Время анализа одного диалога сократилось примерно на 70%, а нагрузка на сотрудников отдела контроля качества уменьшилась в 10 раз. 

В дальнейшем планируем расширить систему: добавить анализ эмоциональных состояний, подключить чаты и мессенджеры, а также дополнить систему агентами для подсказок в реальном времени и обучения операторов.

Комментарии (0)