Нюансы создания навыков для разработчиков
Содержание
Что такое навык с точки зрения программиста?
Навык в Алисе — это Чат-бот с рядом ограничений и особенностей. Подробнее об отличиях от остальных чат-ботов см. ниже.
Как и любой чат-бот, навык требует программного модуля, выполняющегося на постоянно включённом сервере с доступом в интернет. В данный момент поддерживается только один протокол работы: POST-запрос на ваш сервер с серверов Яндекса и ответ на него со стороны вашего сервера.
- Ваш веб-сервер имеет адрес, доступный из внешнего интернета. Он постоянно слушает этот адрес.
- Пользователь вызывает навык в приложении Яндекс на телефоне, на Яндекс.Станции или на другом совместимом устройстве.
- Сервера Яндекса формируют POST-запрос со специальным JSON-объектом в теле запроса.
- Ваш сервер разбирает этот объект. По его содержимому он понимает, какой пользователь в какой навык и какую команду отправил.
- Ваш сервер формирует ответ для сервера Яндекса тоже в виде JSON-объекта. Он должен успеть за 3 секунды.
- Алиса зачитывает ответ вслух, выводит нужные кнопки, показывает пользователю картинку и так далее.
Это что, нужно ставить свой сервер и держать его включённым?
Не обязательно. Вообще, способов запустить навык довольно много. Если ожидается небольшое количество пользователей, то можно уложиться в символическую сумму или даже бесплатно.
Сервисы, которые предоставляют в аренду постоянно включённый виртуальный или физический сервер под любые нужды:
Сервис | Плюсы | Минусы |
---|---|---|
Amazon Web Services | Мощная продвинутая платформа для опытных пользователей с огромным количеством функций, многие из которых имеют бесплатные лимиты. | К недостаткам можно отнести запутанный интерфейс и высокий порог вхождения. |
Яндекс.Облако | Облачная платформа от Яндекса, которая даёт вам в использование виртуальные сервера на Linux или Windows Server. Прозрачная ценовая политика, калькулятор для расчёта. | Из недостатков: отсутствие возможности выполнять автоматический деплой средствами платформы, высокие цены на некоторые базы данных. |
Google Cloud | Мощная платформа от интернет-гиганта, по возможностям не уступающая Amazon, но сделанная чуть более просто и понятно. | Невозможность простым способом узнать цену (нужно вбивать много данных в калькулятор), а также разделение системы на большое количество подмодулей, которые вызывают путаницу. |
Microsoft Azure | Изначально заточенная под .NET платформа, позволяющая, однако, разворачивать приложения и на других языках. Очень щедрый вступительный лимит в виде виртуальных денег, которые можно тратить на различные функции. | Невероятно сложный и крайне недружественный интерфейс. |
DigitalOcean | Лучший на рынке интерфейс, подкупающий своей простотой и отсутствием лишнего. | Изначально сама компания сдаёт только сервера, без какой-либо платформы управления проектами, но добавить к серверам различные функции можно с помощью системы внутренних приложений (Apps). |
Hetzner | Сервис аренды серверов, одни из самых низких цен на международном рынке. | Как и в случае с DigitalOcean, никакой системы управления проектами. Только сервер и всё, настраиваете сами. |
Есть вариант развернуть навык на PaaS: то есть готовой облачной платформе, которая просто скачивает ваш код из репозитория. Гиганты вроде Amazon или Azure умеют так делать, но настройка этой функции, если вы никогда не работали с ними прежде, займёт у вас больше времени, чем настройка отдельного сервера с нуля.
Сервисы с быстрым деплоем прямо из репозитория (serverless):
Сервис | Плюсы | Минусы |
---|---|---|
ZEIT Now | Удобный и быстрый сервис с гибкой ценовой моделью (платишь столько, сколько тратишь) и хорошим бесплатным тарифом. | Поддерживает довольно мало языков. |
Heroku | Пожалуй, самый простой в освоении сервис из списка, который возьмёт на себя вообще всё, вплоть до автоматической регистрации SSL-сертификата для вашего домена (в платном тарифе). | Модель монетизации довольно спорная: нужно оплачивать отдельный сервер под каждое приложение. Для прототипирования подойдёт бесплатный тариф. |
На каком языке писать?
На любом, который поддерживает веб-запросы. Сам Яндекс предлагает посмотреть примеры на Python и Node.js, но вы вольны выбирать PHP, Ruby, Go, Java, Kotlin, C# или другой язык в зависимости от ваших предпочтений и компетенции.
Персонально автор статьи рекомендует для начинающих сделать навык на Node.js и развернуть его на бесплатном тарифе Heroku. Продвинутым же программистам есть смысл написать навык на своём любимом языке, обернуть его в контейнер и развернуть на Dokku - DigitalOcean. Автор статьи пишет навыки на Java и C#, но этот выбор глубоко индивидуален.
Протокол работы
Запрос от серверов Яндекса
Как уже было сказано, Яндекс вызывает сервер навыка и передаёт ему в теле POST-запроса JSON-кодированный объект. Есть несколько важных нюансов, которые вы могли пропустить или не найти в документации, но которые следует знать:
- Яндекс может добавлять в объект какие-то поля, которых в документации нет
Настройте свой JSON-десериализатор на игнорирование полей, отсутствующих в модели данных.
- При запуске навыка поле command пустое
Таким способом вы можете отличить момент запуска навыка от всего остального. При этом поле original_utterance может не быть пустым и содержать текст "Алиса, запусти навык Такой-то".
- Наличие экрана проверяется наличием ключа, а не значения
Если у пользователя есть экран, то во входящем объекте будет ключ meta.interfaces.screen со значением в виде пустого объекта. Иначе такого ключа не будет.
- Вы не можете узнать никаких подробностей о пользователе
Тот или иной пользователь идентифицируется значением поля session.user_id, но это совершенно никак не связано с логином Яндекса. Вы не можете узнать имя или почту пользователя, если только не спросите у него.
- Один и тот же пользователь на разных устройствах идентифицируется, как разные пользователи
Вы не сможете узнать, что с Яндекс.Станции ваш навык запустил тот же человек, который уже запускал его со своего телефона. Если не придумаете какую-то схему авторизации, в которой пользователь будет говорить Станции определённой ключ, который ему выдал телефон.
- Нельзя привязывать контекст диалога к session_id
session_id может поменяться, даже если пользователь не выходил из навыка.
- Примерно раз в минуту приходит heartbeat-запрос от Яндекса
Яндекс автоматически будет присылать в ваш навык запрос с текстом ping примерно раз в минуту, не удивляйтесь. Таким способом он проверяет, что сервер навыка жив. Подойдёт любой корректный ответ (автор статьи отправляет ответ с текстом pong). Если вы ведёте лог всех сообщений от пользователей, исключите из него этот запрос, чтобы не забивать ненужной информацией.
Ответ Яндексу от вашего сервера
Ваш сервер должен сформировать ответ не дольше, чем за 3 секунды, иначе навык выдаст ошибку. Старайтесь не использовать долгие вычисления и сложные запросы к базе данных, а также не разворачивать навык на хостинге или другом слабом сервере, который может просто медленно работать сам по себе. Ответ тоже отправляется в виде специального JSON. Это может быть ответ:
- С текстом
- С кнопками непосредственно под сообщением, вертикально одна под другой
- С кнопками над полем ввода пользователя, горизонтально одна справа от другой, скроллится
- С изображением
- С текстом описания
- С возможностью нажать на изображение, как на кнопку
- С кнопками над полем ввода пользователя, горизонтально
- С несколькими изображениями
- С заголовком галереи изображений
- С возможностью нажимать на каждое изображение, как на кнопку
- С кнопкой под галереей изображений
- С кнопками над полем ввода пользователя, горизонтально
Важные нюансы при работе с ответами такие:
- Заполняйте tts
В ответе есть специальное поле, которое показывает, как именно голосовому синтезатору произносить слова. Например, это могут быть слова, которые одинаково пишутся, но имеют разное ударение: з`амок и зам`ок. Для хорошего восприятия пользователем лучше заполнить это поле. Протестировать, как именно Алиса будет произносить те или иные слова, можно вот здесь, а подробности заполнения поля представлены в документации.
- То, что Алиса говорит, может отличаться от того, что выведено на экран
Если в поле tts есть информация, то Алиса прочитает только её. При этом на экран можно вывести другой текст. Например, добавить каких-то подробностей, которые не обязательны и слишком утомительны для зачитывания вслух, но при необходимости дают пользователю возможность узнать их, взглянув на экран.
- Вы не можете вывести длинный текст вместе с изображением
Ограничение на описание под изображением: 256 символов.
- Вы не можете вывести вертикальные кнопки по-умолчанию вместе с изображением
У кнопок есть свойство hide. По-умолчанию оно установлено в значение false, в таком случае кнопки будут выводиться вертикально одна под другой непосредственно под сообщением, вместе с которым они были отправлены. Такие кнопки не могут быть выведены под сообщением-картинкой. Переключите их в true, чтобы отобразить горизонтально над полем ввода пользователя.
- Ссылки в тексте не будут кликабельны
Для создания кликабельной ссылки используйте кнопку с полем url.
- Изображения нужно предварительно подготавливать и загружать
На настоящий момент нет простого способа на лету отправить пользователю сгенерированную картинку. Изображения нужно подготовить и предварительно загрузить в панели управления разработчика.
Чуть больше о картинках
Полезный материал: Размеры изображений в Навыках
Два урока из Школы Алисы на тему подготовки изображений:
Возможности навыков
Что умеет навык, чего не умеют обычные чат-боты
- Распознавание голоса
Навык (а точнее — Алиса) может понимать естественную речь на русском языке. В теории это позволяет получать от пользователя большое количество данных, которые он в противном случае не стал бы вводить. Эта особенность позволит вам понять, в каком направлении делать ваш навык (и стоит ли вообще превращать ваше приложение в навык).
Пример:
Обычные боты: Пользователь нажимает на кнопки на экране, чтобы пройти по дереву меню и вызвать определённую функцию. Это подходит для ситуаций, когда количество вариаций возможных команд от пользователя не слишком большое. Вы вряд ли заставите человека набирать с мобильного телефона длинный текст, такой, как адрес местожительства.
Навык: Пользователь может не иметь возможности нажимать на экран, потому что у него, например, заняты руки. Зато ему не составляет труда произнести длинную фразу: третья улица Строителей, дом двадцать пять, квартира двенадцать, одну заливную рыбу и водки, пожалуйста.
- Синтез голоса
Навык прочитает вслух текст на русском языке (и с некоторыми ограничениями на английском). Если правильно управлять вниманием пользователя, то можно быть уверенным, что он не пропустит важную информацию, которую в обычной ситуации пробежал бы взглядом вскользь. К тому же добавляются нестандартные сценарии использования: работа с группами людей, работа с детьми, которые не умеют читать, работа с людьми с ограниченными возможностями и так далее.
Пример:
Обычные боты: Если пользователь хочет показать результат выполнения команды другому человеку, то он должен показывать ему экран телефона или компьютера, либо зачитывать вслух ответ самостоятельно.
Навык: Пользователь может положить телефон в центр стола, и ответы Алисы будут слышать все люди за столом.
- Использование на Яндекс.Станции и подобных устройствах
Это очень важная особенность, дающая принципиально новые сценарии, которые для обычных ботов были бы невозможны: от управления умным домом до голосового помощника при выполнении фитнес-упражнений.
Пример:
Обычные боты: Пользователь неизбежно вынужден доставать телефон (компьютер) и смотреть в экран. Зрение является основным способом взаимодействия с внешним миром, поэтому, скорее всего, никакую другую работу пользователь в этот момент выполнять не сможет.
Навык: При наличии Яндекс.Станции пользователь может сидеть за столом и писать что-либо в тетрадь, периодически спрашивая у Алисы различные уточнения или прося её выполнять расчёты.
- Токенизация входящей команды
Сервера Яндекса автоматически выбирают из строки:
- Имена собственные (Иван, Эйфелева башня)
- Адреса (Россия, Москва, третья улица Строителей)
- Дату и время (тринадцатого марта, десять лет назад)
- Числительные (двенадцать, одна целая пять десятых)
Пример:
Обычные боты: Чат-бот со справочной информацией о достопримечательностях. Программист должен самостоятельно подключать словарь названий и производить обработку входящей строки, чтобы понять, какое слово в строке является названием.
Навык: Сервер Яндекса сам подскажет программисту, что во фразе "Где находится Эйфелева башня?" определённые слова являются названием.
- Воспроизведение звука
Программист может подготовить собственный звук или взять готовый звук из библиотеки Яндекса и воспроизвести его в любом месте при синтезе голоса.
Пример:
Обычные боты: Чат-бот может отправить пользователю аудиосообщение, которое пользователь проигнорирует, потому что не был готов доставать наушники.
Навык: Если оппонент в битве ведёт себя предсказуемо, навык может сигнализировать об этом звуком "грустного тромбона".
Что не умеет навык по сравнению с обычными чат-ботами
- Инициировать переписку
К сожалению, на настоящий момент любое действие навыка может быть только ответом на действие пользователя и никак иначе. Это не позволяет навыкам самостоятельно напоминать пользователю о чём-либо. В дополнение это накладывает ограничения на скорость ответа: навык должен ответить сразу же, он не может подождать полминуты (например, чтобы выполнить расчёт) и затем ответить.
Пример:
Обычные боты: Чат-бот ВКонтакте или Telegram, который пересылает вам в личку заголовки входящих писем в электронной почте.
Навык: Невозможно сделать навык, который сам говорил бы пользователю о поступлении нужного товара в магазин.
- Принимать от пользователя изображения или другие файлы
Навыки не могут получать от пользователя ничего, кроме голосовых или текстовых команд.
Пример:
Обычные боты: Чат-бот в Telegram, который получает от пользователя фотографию и определяет, присутствует ли на этой фотографии хот-дог или нет.
Навык: Невозможно сделать навык, который сканировал бы QR-код с чека.
- Идентифицировать пользователя
Навыки не получают никакой информации о пользователе, даже если он готов им её предоставить. Они не знают имя, пол, список членов семьи и так далее.
Пример:
Обычные боты: Чат-бот в любой системе может обратиться к пользователю по имени, что делает диалог более натуральным и персонализированным.
Навык: Бот в Алисе вынужден просить пользователя представиться и надеяться на то, что система правильно распознает его имя.
- Понимать местоположение пользователя
Навык не может получить доступ к GPS телефона, даже если пользователь согласится передать эту информацию.
Пример:
Обычные боты: Чат-бот-Тиндер, позволяющий людям знакомиться на основании географической близости друг к другу.
Навык: Нельзя сделать навык, который будет запоминать место, где вы припарковали свой автомобиль.
- Запускать команду в навыке по ссылке
На текущий момент навыки не поддерживают механизм Deep linking. Вы не сможете вызвать в навыке определённое состояние с помощью особым образом сформированной ссылки.
Пример:
Обычные боты: Чат-бот в Telegram для организации встреч может сформировать специальную ссылку на конкретную встречу. Когда пользователь нажимает её, то переходит в бота, сразу видя информацию о конкретной встрече с предложением принять участие. Если бы пользователь зашёл в этого бота без такой ссылки, то увидел бы меню создания новой встречи.
Навык: Не получится сделать навык с таблицей размеров красных резиновых шаров и отправить другому человеку ссылку на конкретную запись в этой таблице внутри навыка.
Прочее
Эта статья не касается самого процесса создания навыков, прохождения модерации и публикации в каталоге.
На эти темы рекомендую посмотреть Школу Алисы. Есть смысл заглянуть также в FAQ по Навыкам, где есть тематические статьи и ссылки на некоторые инструменты для разработчиков.
Всех желающих приглашаем в Чат Яндекс.Диалоги, где вы сможете получить ответ на интересующий вас вопрос.