Цифровые ассистенты — тренд в массовом обслуживании. Они автоматизируют работу поддержки, помогают пользователям найти и подобрать услуги, записаться на прием, развлекают.
Привет, меня зовут Никита. Я руковожу командой, создающей Робота Макса, цифрового ассистента Госуслуг. Еще год назад у ассистента не было команды, потом появилось 7 человек. Сейчас нас 70, мы стараемся быть лидерами изменений на Госуслугах и внедрять новые практики командной работы.
При создании ассистента важно не только правильно сформировать технологический стек, но и быть глубоко погруженным в контекст сферы, для которой создается умный помощник. У Госуслуг важные задачи, уникальная специфика и терминология, многомиллионная аудитория. Как оформить ребенку паспорт, получить выплату к школе или компенсацию билетов в театр, записаться к врачу или сообщить о нарушении? Во всем этом вам должен помочь цифровой ассистент.
Сегодня я расскажу из чего состоит Макс и как он таким стал.
Как возник ассистент Макс и какая у него цель
Текущий поиск Госуслуг написали 13 лет назад. C++, сильная команда разработчиков и опыт создания глобального поиска. Но время шло, развивался мир и госуслуги, а поиск — нет. Разница в темпе развития привела к десяткам заплаток, состав команды сменился, документация устарела. Legacy-код повлиял на мотивацию и производительность. Время релиза услуги в поиске достигло суток. При обновлении Sitemaps старые услуги пропадали, новые не появлялись. Ранжирование задавалось вручную. Autocomplete не знал морфологии и не работал, если фраза содержала стоп-слова. Так мы поняли, что быстрее и правильнее создать новое.
Границы получения услуг, кому можно или нельзя, когда и как, описываются официальными формулировками. Часто используются канцеляризмы и аббревиатуры. Вместо «налоговая» — «ФНС» или «Федеральная налоговая служба». Вместо «ремонтировать» — «производить ремонт». Люди так не разговаривают. Но завтра же изменить язык государство не сможет. Законы и акты придется переписать, для новых внедрить редакционную политику, научить сотрудников. А госуслуги нужны сейчас. Так мы поняли, что людям нужен переводчик с «государственного».
При проработке концепции нового поиска аналитики обратили внимание на поведение пользователей в социальных сетях. Люди организуют группы, где создают пошаговые инструкции «как получать госуслуги». Читатели идут по понятному пути, быстро и без переживаний. Так мы поняли, что Госуслугам нужен проводник, который поймет с полуслова, поможет подготовиться и даст подробный совет.
Боль наших пользователей — техническая поддержка. Команда провела независимые замеры среднего времени ожидания оператора в чатах поддержки. Показатель по лидерам российского рынка — до 3 минут. А пользователи Госуслуг ждут помощи оператора 2 или 3 часа. При этом больше 60% обращений типовые. Так мы поняли, что Госуслугам нужен спасатель, который ответит без оператора.
Цель Робота Макса — сопроводить, поддержать и помочь. Найти услугу, рассказать о ней, объяснить, как действовать. И все это на понятном языке.
Из чего же, из чего же, из чего же
Рассказывать о Максе можно долго, поэтому, чтобы вы не заскучали, в этой статье я остановлюсь на ключевых компонентах. А также поделюсь схемой архитектуры, если вас заинтересует какая-то конкретная область — пишите в комментариях и мы раскроем её в следующих статьях.
Схему в высоком разрешении можно посмотреть по ссылке.
«Мозг» Макса — брокер, который асинхронно опрашивает сервисы предоставления ответов и выбирает релевантный. Для выбора используется информация о длине введенной фразы, способе ввода, намерении пользователя и наличии ответа в сервисе. Брокер разработан на Python 3.9 с использованием асинхронных пакетов, таких как FastApi, aiologger, aioredis, httpx. Стратегию выбора сервиса может настроить любой пользователь без привлечения разработчиков. Количество параметров в стратегии не ограничено, но при конфликтах пользователю сообщается о наличии ошибки. Для хранения стратегии используется БД PostgreSQL.
Интеграционная шина брокера связывает компонент с функциональностью персонализации, хранилищем диалогов, хранилищем контекстов, единым аналитическим кластером Госуслуг, кэшем и ELK. Все эти сервисы регулируются через feauture flags, а при повышенной нагрузке могут отключаться, чтобы сократить количество внутрисистемных запросов. При необходимости Макс сохранит контакт только с одним-двумя сервисами ответов и продолжит помогать пользователям. Через конфигурирование брокера настраивается А/Б тестирование и канареечные релизы. Взаимодействие с фронтом идет через socket-соединение, за счет хранения контекстов происходит зеркалирование и пользователь может работать одновременно с нескольких устройств. Кроме сокетов поддерживается long-polling и rest.
Системное логирование ведётся в LogStash, что позволяет наглядно изучать работу приложения в Kibana, с удобной фильтрацией и отображением графиков.
Анализ обращений пользователей к Максу показал, что 71% запросов это короткие фразы, длиной до 3 слов. 49% пользователей отправляют 1 слово, 14% - 2, 8% - 3.
Чтобы правильно реагировать на короткие запросы, команда провела кластеризацию и выявила, что в 51% случаев в запросе содержится только домен услуги. Домен — обобщенное обозначение услуги или группы услуг. Например, домен COVID включает в себя такие услуги как «Запись на вакцинацию», «ПЦР-тест», «Сертификат переболевшего», «Проблема с лечением COVID».
31% запросов содержит только запрос к действию без обозначения домена услуги или услуги. Например, «запись», «регистрация», «оформление».
И 14% содержат название услуги, например, «Запись к врачу», «Замена паспорта» или «Пособие беременным».
При выборе решения для ответов на короткие запросы мы ориентировались на высокий уровень управляемости, быструю настройку и, конечно, точность ответа. В результате проработки сформировались 2 варианта: нейросеть на основе fastText и обратный поиск Elasticsearch - percolate, по основам слов, который вызывает квизы — JSON’ы с графом переходов между вариантами ответов.
Проверка концепции показала, что нейросеть из-за схожести домена услуги и полного названия услуги часто ошибалась при ответе. Средний уровень точности составлял 40%, что недостаточно для запуска в продуктивную среду. Было решено работу с нейросетью выделить в отдельный поток, чтобы найти ей оптимальное применение. Квизы показывали точность в 2 раза выше при том же времени на настройку. Чтобы сократить время поиска, квизы настроены на перехват запроса, поэтому при настройке используются основы слов, а не полное их значение. Для квизов был переиспользован плеер услуг, разработанный специально для новой версии портала. Это не только сократило время на встраивание, но и позволило заполнять услуги в интерфейсе Макса.
Итак, 71% запросов у нас короткие, но 29% — больше 3 слов. Что делать с ними? Кластеризация показала, что подавляющая доля длинных фраз — конкретные вопросы об услуге. Примеры запросов: «какой размер пошлины за замену паспорта?» или «нет сертификата о вакцинации, хотя я привился». Ответы на такие вопросы содержатся в базе знаний раздела «Помощь», это стандартный FAQ-формат. Для сохранения единства информации было принято решение индексировать базу знаний.
Первой концепцией было переиспользовать обратный поиск, который мы применяли на коротких запросах. Но для запросов такого типа он не показал достаточного уровня точности и занимал слишком много времени на обучение из-за длины фразы и количества ключей.
Вторая идея заключалась в применении Elastic, но уже в формате обычного поиска. Для индексации была настроена предобработка морфологии с использованием словаря hunspell, словарь стоп-слов, ориентированный на предлоги и местоимения, а также словарь синонимов. Поиск по телу статьи на предварительных тестах показал ужасные результаты, точность составляла 10%. Причина заключалась в редакционной политике. Что полезно человеку — роботу полезно не всегда. Политика «пиши-сокращай» позволила ясно доносить информацию, но индексировать ответ стало невозможно. Например, для вопроса «Заверять ли анкету для загранпаспорта на месте работы» ответ из базы знаний был — «нет, не нужно».
К индексу по телу статьи попробовали добавить заголовок, точность выросла до 45%, но и этого было недостаточно. Формулировки запросов расходятся с названием статей, заголовки услуг в различных доменах близки по названию, что мешает точному поиску. На брифинге возникла идея — добавить к каждой статье 5 скрытых заголовков, аналог разметки, отражающий вариативные запросы пользователей. Результат вышел отличный, точность ответа выросла до 92%.
Новая проблема возникла, когда количество индексированных вопросов превысило 700. Близкие домены и вопросы в них стали путать поиск, точность снизилась до 60%, часто Elastic отдавал откровенную чушь. Чтобы исправить ситуацию, были сформированы две гипотезы. Первая – что для точного поиска нужна предварительная классификация домена услуги, тогда поиск будет сравнивать меньшее количество статей и риск ошибиться будет ниже. Вторая – что для точного поиска нужно доработать запрос, не использовать стандартный «query_string».
Для проверки первой гипотезы был разработан классификатор на облаке слов с применением TF-IDF-меры. Он показал точность 80% и позволял в короткий срок встроить данные в ассистента. Для повышения точности классификатора была использована вышеупомянутая нейронная сеть на fastText. За счет обучения каждого класса на выборке из 500-1000 фраз пользователей и совмещения его с TF-IDF-классификатором точность выросла до 94%
Для проверки второй гипотезы поисковый запрос был изменен на «multi_match», с дополнительным коэффициентом сложения значений релевантности всех полей документа. Таким образом, каждое из 6 полей, участвующих в поиске, дополняет и усиливает друг друга. Появилась возможность гибко настраивать ранжирование результатов. Без применения классификатора новый запрос привел к точности 80%. Включение в пайплайн классификатора и нового поискового запроса вернуло качество поиска на прежний уровень.
Создание классификатора позволило решить еще одну проблему. Обучить ассистента всему и сразу невозможно. В качестве вех для обучения используются услуги, об этом процессе мы расскажем отдельно, но главное — непрерывный процесс пополнения Макса новыми знаниями. Чтобы не терять уровень покрытия, для поиска услуг, которым Макс не обучался, используется старый поиск. Разработанный классификатор был применен не только для повышения точности поиска на Elastic, но и для определения, настроена ли услуга в навыках Макса или стоит отправить запрос в старый поиск. Таким образом Макс сохраняет уровень покрытия услуг, выводя их на новый уровень качества.
Контролировать качество работы Макса, выявлять всплески пользовательских запросов и количество аудитории позволяет компонент логирования бизнес-метрик. Макс запоминает количество входов в виджет и выходов из него, введенные и отправленные запросы пользователей, время и дату запросов, выявленный класс, переход к предложенному ответу или переход по ссылке. Обезличенная статистика попадает в аналитический кластер Госуслуг через Kafka. С полученной информацией работает команда анализа данных. В аналитическом кластере есть настроенные дашборды по посещаемости, конверсии отвечающих сервисов, ТОП отправленных фраз, ТОП фраз, на которые не отреагировали сервисы ответов. ТОП статей FAQ, ТОП квизов и ТОП ссылок, по которым переходили пользователи. Кстати, поздравьте нашу команду, ночью 29 октября мы вышли на главную Госуслуг и побили рекорд своей посещаемости, с Максом работали 1 353 999 граждан за сутки. В первую неделю запуска количество пользователей в сутки не превышало 45 000.
Хайрез, как всегда, по ссылке.
Работа со статистикой
У Макса есть две основные метрики оценки работы — покрытие и точность. Покрытие означает насколько знания Макса соответствуют запросам пользователей. Точность — насколько правильно Макс отвечает на вопросы, которым его обучили. Для анализа этих показателей применяются методы предварительной кластеризации и ручная разметка. Частота обновления — от 2 до 4 недель. Резкие всплески отображаются на дашбордах, но методичное обновление метрик покрытия и качества позволяет отследить результат на длительном промежутке времени.
Первый шаг при анализе покрытия — выявить покрытие доменов в запросах пользователей. Какая доля фраз задается по услугам, которым Макса обучали, какая доля фраз по доменам, которым Макса не обучали, и какая доля запросов не является сутевой, например, мат, абракадабра или фразы приветствия. Каждый домен тщательно размечается и на выходе команда имеет список тем для обучения. Следующий шаг — разметка непокрытых вопросов внутри доменов, где обучали Макса и анализ распределения. Для дообучения в первую очередь берутся самые популярные услуги.
При анализе качества в первую очередь ведется анализ доли ответов, где Макс правильно ответил на вопрос, где ответил неверно и где вообще не ответил. За этим следует декомпозиция на сервисы — квизы, поиск по FAQ и старый поиск. Следующий шаг — декомпозиция на категории проблем. Например, отсутствие ключевых слов, некорректная работа словаря стоп-слов.
Сейчас команда работает над добавлением метрик оценки пользователем ответов Макса. Мы хотим знать от пользователей, помог ли ответ Макса, и, если нет, как можно его изменить, чтобы помог.
Напоследок
О чем еще можно рассказать…
Например, как мы выявили нетривиальное поведение пользователей и сформировали классы для обработки таких запросов.
Как наши дизайнеры переработали внешний вид Макса и как мы встроили анимацию.
Как мы меняем работу с операторами.
Как мы обнаружили запросы пользователей о статусе своего заявления и как работаем с направлением персонализации и рекомендательным движком.
Как мы работаем над сохранением контекста диалога, чтобы быть еще ближе к пользователю и лучше его понимать.
Как мы проверяли гипотезы перехода к оператору.
Как мы работаем с инфраструктурой и системными компонентами.
Как мы развиваем предобработку.
Как организован процесс вывода навыков и как мы сократили время вывода с 5 дней до 24 часов.
Выбирайте, что интереснее. Обсудим в следующий раз.
Если у вас есть идеи, что можно улучшить и как, присылайте их на почту нашей команды: robot_maks@rtlabs.ru или пишите в комментарии к статье.
Спасибо.
Иллюстрации: Михаил Голев