И снова привет, Хабр! В прошлой статье мы рассказывали, как создаем голосового агента (предпочитаем этот термин, а не "голосовой робот") всего на 500 записях. Если кратко вспомнить содержание, то мы научились успешно обучать агентов на очень небольшой базе звонков. Чтобы было понятно, зачем это - наша компания предоставляет услуги контакт-центра на базе искусственного интеллекта. Ну а для построения логики диалога мы используем визуальный конструктор, который повышает эффективность этой работы. В новой статье как раз и рассказываем о том, что за система и как она работает. Со скриншотами и кейсами - все, как вы любите.  Как и любая другая компания, Neuro.net и наши технологии развиваются постепенно. Наши цифровые агенты были хороши уже несколько лет назад. Но вот их обучение было делом очень непростым. В предыдущей версии платформы сценарий диалога мы задавали при помощи стандартного набора экшенов, порядок которых определялся строками в таблице. Дерево диалога составлялось при помощи разных условий и экшена goto. Экшены мы группировали в логические единицы. У такой системы было несколько достоинств: Возможность разобраться с обучением даже людям, кто не слишком хорошо разбирается в программировании. Оперативное обучение цифровых агентов. Но были и недостатки, причем немало: Написание сценариев на основе таблиц, экшенов и т.п. - достаточно трудоемкая задача, которая требовала выделения ресурсов. Увеличение количества сценариев приводило к повышению количества требований к их функциональности. Сами сценарии становились сложнее, ориентироваться в них было очень непросто. Поэтому мы решили использовать Python, а вместо экшенов использовать набор библиотек и методов, которые разработали сами. Это решение было очень правильным, мы убили сразу несколько зайцев - получили возможность писать сложные сценарии диалогов за вменяемое время, упростили работу с условиями, переменными и ветвлениями, плюс смогли подключать сторонние библиотеки для реализации разных интеграций. Python, конечно, очень удобен. Но для нас было важно, чтобы цифровых агентов могли обучать и те, кто далек от программирования. Если использовать "голый" Python, логично, что сотруднику нужно знать хотя бы его базовые основы, что уже повышает порог вхождения. Более того, мы хотели добиться того, чтобы конструктор могли использовать не только сотрудники, но и партнеры и будущие клиенты. У некоторых из них не было программистов в штате и они задавали резонный вопрос: “А сможем ли мы создавать и настраивать виртуальных агентов самостоятельно, если у нас нет программистов?”. Для того, чтобы отвечать на него утвердительно, мы решили создать визуальный конструктор сценариев, в котором пользователь мог бы самостоятельно накидывать блоки с действиями, выстраивая между ними связь. Сказано - сделано, после того, как появилась идея визуального конструктора, мы решили провести анализ возможных путей реализации проекта. Этап 1. Изучение существующих на рынке решений Чтобы не изобретать велосипед (правда, мы не знали, изобретен он уже или нет), мы решили изучить существующие на рынке решения, другие конструкторы голосовых и чат-ботов. Найденные решения, если нравились, мы пробовали в деле, хотя это не всегда было возможно. Короче, задача стояла набрать базу референсов и отобрать самые интересные и удобные решения. Интерфейс работы конструктора ManyChat Интерфейс работы конструктора JustAI Мы проанализировали больше десятка конструкторов, среди которых: ManyChat Twilio JustAi Voximplant Botmock Watbot Miro Разные другие На этом этапе мы выяснили, что все конструкторы состоят из: Экшен-блоков и их параметров Связей, которые выстраиваются между блоками Рабочей области, в которой все это размещается Этап 2. Анализ собственных сценариев и методов После того, как мы закончили изучать сторонние решения, приступили к анализу собственных - в первую очередь, сценариев, написанных на Python, которые уже работают, а также методов наших библиотек. Задачей этого этапа было понять, на какие блоки конструктора можно разбить сценарии диалогов и какие взаимосвязи между ними можно выстроить. Этот этап оказался не таким уж и сложным благодаря тому, что разработчики оставили описание каждого метода и почти каждого аргумента. Одновременно мы проанализировали примеры сценариев, оценивая как скрипт-дизайнеры используют библиотеки, методы, переменные окружения, какие задают циклы и т.п. В итоге получили два важных вывода: Нужно реализовать конструктор так, чтобы он мог генерировать Python код, который не будет входить в конфликт с существующей архитектурой. Таким образом, можно будет организовать взаимодействие скриптов созданных с помощью конструктора и скриптов написанных вручную. кроме того, не потребуется значительных доработок со стороны бэкенда и телеком. Каждый блок конструктора должен представлять собой функцию Python, которая будет вызывать следующую функцию через result и т.д., тем самым будет выстраиваться связь между блоками. Для универсальности (ведь блоки всегда можно связывать друг с другом произвольно) аргументы в функциях использоваться не должны, вместо аргументов будут использоваться методы наших библиотек, которые работают с переменными окружения. Этап 3. Взаимодействие с разработчиками Этот этап реализовывался параллельно с предыдущим. Приступая к нему, мы уже сформулировали требования и с ними отправились к разработчикам. Важнее всего на этом этапе была работа с фронтендерами, которым мы описали концептуальную модель, ее критерии, показали похожие продукты. Обсудив все, веб-разработчики запросили паузу на обдумывание и анализ полученной информации. Ну а мы использовали это время для составления блоков и их параметров. Этап 4. Поиск библиотеки Разработчики смогли найти подходящее решение - это Rappid. Данная библиотека наиболее полно удовлетворяла требованиям - у нее были все необходимые нам функции для реализации проекта, плюс возможность дальнейшего расширения функционала. В общем, библиотека была использована для разработки конструктора. Все шло своим чередом. После того, как мы определились со всеми требованиями, архитектурой и инструментом, приступили к реализации проекта. Начали, как обычно, с MVP, посредством которого можно набросать простой сценарий диалога и проверить работоспособность системы. Интерфейс конструктора мы сделали максимально простым, даже минималистичным, лишив его всяких лишних деталей, которые лишь мешали бы в процессе работы. Основной для интерфейса послужил наш UIKit и собранные на этапе анализа референсы. Основные элементы интерфейса Рабочая область. Это фон в виде сетки, база, на которой размещаются основные блоки. Далее добавляем тулбары: Навигация по рабочей области Откат операции и сохранение Возвращение в основной интерфейс Тулбар с общими функциями CMS, включая уведомления и управление аккаунтом Сайд-бар с экшен-блоками. Здесь разместили список доступных блоков, учитывая возможность добавления новых функций в будущем. Не забыли и о необходимости управления самими блоками, добавив сайдбар с отображением параметров выбранного элемента. Добавили отображение блоков. Каждый из них должен иметь название, вход (т.е. начало функции) и один или несколько выходов (return). Пример стандартного и нашего экшен-блоков Пример сгенерированного кода И, конечно, мы добавили связи между блоками, а также тулбар, который позволяет посмотреть и оценить сгенерированный конструктором код Python. Стандартные и наши связи между блоками Зачем? Эта функция дает возможность проверить корректность работы конструктора, что полезно для тех пользователей, кто умеет и любит работать с Python. Проверка кода В ходе отрисовки интерфейса параллельно передаем веб-разработчикам готовые материалы для оперативной кастомизации компонентов библиотеки. Ну и делаем прототип, который демонстрируем партнерам и клиентам для получения обратной связи. Вот такой получился прототип Прототипом заморочились не напрасно - после его демонстрации нас попросили сделать так, чтобы при взгляде на схему было сразу понятно, что говорит виртуальный агент. На этом этапе убеждаемся, что библиотеку выбрали оптимальную для своих нужд.  С момента постановки идеи до создания готового MVP решения прошло всего 1,5-2 месяца. Это совсем немного, если учитывать, что нам пришлось пройти три важных этапа работы, включая анализ сторонних и собственных решений, отрисовку интерфейса и, собственно, разработку проекта. Важный нюанс - мы постарались не использовать формальные подходы с составлением детальных технических заданий, подробнейших описаний или userflow. Благодаря такому решению получилось оперативно реагировать на новые требования, проблемы и ограничения в процессе работы над проектом. Итог - готовый и полностью работоспособный продукт, собранный за несколько месяцев. Сейчас мы его дорабатываем, оптимизируя поведение, интерфейс и юзабилити, плюс добавляем новые функции. Собственно, на этом все. Если у вас есть что спросить или посоветовать - ждем в комментариях к статье. Спасибо! Дизайнер