«Computer, how is my build doing?» и другие волшебные заклинания

Барух Садогурский рассказывает, как с помощью сервиса голосовых команд Alexa можно добавить голосовой интерфейс к совершенно неожиданным вещам, таким как IntelliJ IDEA и Jenkins, а также, откинувшись в кресле с бокалом любимого напитка, управлять всем, чем угодно.


В основе статьи — выступление Баруха на конференции JPoint 2017 в Москве.

Барух занимается Developer Relations в компании JFrog. Кроме этого, он энтузиаст Groovy, DevOps, IOT и Home Automation.

Что такое Alexa и зачем она в нашей жизни?


В этой статье я буду разговаривать с Alexa. Это — продукт компании Amazon — голосовой помощник, такой же, как Siri, Cortana (ни дай Бог, если кто не сумел удалить), Google Home и т.д. Alexa — это сегодня лидер рынка, и мы поговорим, почему, хотя причина очевидна.

Есть три вида Alexa-устройств.

l6bhylqamjvnfgjjemr0trh2dng.png

Я буду разговаривать с Amazon Tap. Раньше она не умела откликаться на имя, поэтому приходилось нажимать на кнопочку, отсюда в названии Tap. Сейчас она уже реагирует на имя, но название осталось. Полноценная Alexa большая, с хорошим динамиком. Есть еще «финтифлюшка» со слабым динамиком, которая предназначена для того, чтобы подключаться к другим ресиверам, динамикам и т.д. Все они вполне доступны, стоят 170, 130 и 50 долларов. У меня дома их в общей сложности девять. Зачем мне все это надо, мы сейчас поговорим.

Я упомянул о том, что Alexa сейчас — безусловный лидер рынка. Лидером она является благодаря открытому API для написания сценариев Alexa Skills. Как раз недавно говорилось о том, что количество скилов в основной базе достигло 10 тысяч. Большинство из них бестолковые, но благодаря многим полезным скиллам ничего похожего на Alexa по полезности и популярности нет. Как они накрутили 10 тысяч, вполне понятно. Там есть шаблон, по которому можно сделать скилл, поменяв пару строк. Затем опубликовать его, получить футболочку — и вот у них их 10 тысяч. Но сегодня мы научимся писать несколько более интересных скилов — и вы поймете, что это достаточно просто.

Почему я этим заинтересовался и как я пользуюсь армией «Алекс», которая у меня дома?

g4gz96foduueiasd0eugvmrvnim.png

Я встаю и первым делом прошу ее выключить будильник («Alexa, turn off the alarm»). После чего как-то добираюсь до кухни и прошу включить свет («Alexa, turn on morning lights»). Здороваюсь с ней («Alexa, good morning»). Кстати, на «Good morning» она отвечает интересные вещи, например, сообщает, что в Малайзии в прошлом году нашли большую змею. Полезная информация с утра, под кофе.

Затем я спрашиваю о новостях («Alexa, what«s my news flash?»), и она зачитывает мне новости с разных ресурсов. После этого спрашиваю, что у меня в календаре? («Alexa, what«s on my agenda?»). Благодаря этому я знаю, как выглядит мой день. И дальше я спрашиваю, как я еду на работу, есть ли по дороге пробки и так далее («Alexa, how«s my commute?»). Это — домашнее-ориентированное использование, тут вообще нет никаких custom skills, все это встроено.

Но есть еще много крутых вариантов применения.

tie2fwl1pj17_mrdqqpfrhohddy.png

  • Умный дом — это самый крутой вариант. Как вы уже, наверное, видели, свет я включал через Алексу. Но это может быть не только свет: замки, камеры, охранная сигнализация, всякие сенсоры — все, что подключается к умному дому.
  • Музыка. Alexa может проигрывать музыку, которую я люблю. Сюда же — аудиокниги. У взрослых на них обычно нет времени, но мой сын слушает сказки через Алексу.
  • Вопросы/ответы. То есть то, что обычно ищут в Википедии.
  • Новости/погода — об этом я уже говорил.
  • Заказ еды — конечно же, очень важно, чтобы можно было, не вставая с дивана, заказать пиццу, суши и т.д.


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

Аналитики утверждают, что за последние 30 месяцев в области голосовых интерфейсов произошел прогресс, которого не было в течение последних 30 лет. Суть в том, что голосовой интерфейс в какой-то момент заменил графический. Это логично, потому что графический интерфейс — это был костыль, который существовал только потому, что голосовой был недостаточно развит.

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

Вот этот API, который лежит поверх распознавания голоса и определенного Artificial Intelligence, который есть в Алексе, — это то, что гарантирует взрывное развитие в этой индустрии и возможность для многих людей писать много полезных скиллов.

Сегодня мы посмотрим два скилла. Первый открывает приложение, мою IntelliJ IDEA, и он, конечно, прикольный, но не очень полезный (так как открывать приложение голосом, а затем писать код ручками не имеет особого смысла). Второй будет про Jenkins, и он должен быть намного полезнее.

Написание скилла для Alexa


Написание скилла — простая штука и состоит из трех этапов:

  • Определить интерактивную модель — тот самый голосовой API;
  • Написать обработчик команд, которые к нам приходят;
  • Пройти ревью в Амазоне (этот этап мы рассматривать не будем).


rkp9ok3spkwvf-yeshqaakezyb0.png

Интерактивная голосовая модель: что это, зачем это?


В основе лежит очень простая идея:

71u2mjqorjbn9ev9yfccyxkovko.png

Мы можем вычленять переменные из текста и передавать в обработчик (к примеру, я прошу открыть IDEA, которая является слотом, но я точно так же мог попросить открыть Rider или Sea Lion).

JSON-ом я называю команды, а дальше даю текстом, как эти команды могут звучать. И вот тут происходит волшебство, потому что одно и то же можно сказать разными способами. И этот Artificial Intelligence (Voice Recognition, который предоставляет Alexa) умеет подбирать по смыслу не только ту команду, которую я прописал, но и все похожие. Кроме этого, есть набор встроенных команд, таких как Stop, Start, Help, Yes, No и так далее, для которых не надо писать никаких примеров.

Вот JSON IntentSchema, в которой прописано, какие примеры я хочу. Этот наш пример, который открывает тулзы из JetBrains Toolbox.

{
 	"intents": [
   	{
       	"intent": "OpenIntent",
       	"slots" : [
        {
  	        "name" : "Tool",
              	"type" : "LIST_OF_TOOLS"
        }
     	]
 	},
 	{
     	"intent": "AMAZON.HelpIntent"
 	}  
  ]
}


Вы видите, что у меня есть интент, который называется OpenIntent, и есть один слот Tool. Его параметр — это какой-то список тулзов. Кроме того, там еще хелп.

Типы слотов


Вот какие бывают типы слотов:

  • Встроенные, такие как AMAZON.DATE, DURATION, FOUR_DIGIT_NUMBER, NUMBER, TIME;
  • Масса всякой информации, которую Alexa уже знает и вокруг которой мы можем написать скиллы, например, список актеров, рейтинги, список городов в Европе и США, список известных людей, фильмов, напитки и т.д. (AMAZON.ACTOR, AGREATERATING, AIRLINE, EUROPE_CITY, US_CITY, PERSON, MOVIE, DRINK). Информация о них и все возможные варианты уже заложены и хранятся в Alexa.
  • Custom Types.


Обязательно нужно помнить, что они не являются enum. То есть этот список служит только приоритетом. Если Alexa узнает какое-то другое слово, оно будет передано в мой скилл.

Вот тот самый List of Tools — те варианты, которые я ей дал.

z9gxzvaix_ewbkbiusxzliqc5je.png

Написание тут отличается от написания продуктов компании JetBrains просто потому, что Alexa работает с натуральными словами. Соответственно, если я напишу IntelliJ IDEA в одно слово, она не сможет распознать, что это такое.

Примеры фраз для команд


Вот примеры того, как люди могут обращаться, чтобы затребовать открытие этого инструмента:

OpenIntent open {Tool}
OpenIntent start {Tool}
OpenIntent startup {Tool}
OpenIntent {Tool}


Есть и другие варианты. Когда Alexa видит этот набор, она знает, что синонимы этих слов тоже попадают под этот интент.

Обработчик команд


Мы описали голосовой интерфейс, и дальше у нас идет обработчик команд. Он работает очень просто: Alexa превращает голос, которым мы с ним говорим, в REST-запрос в формате JSON.

Запрос может идти или в AWS Lambda Function или на произвольный HTTP-сервер. Преимущество Lambda Function в том, что для них не нужен произвольный HTTP-сервер. У нас есть platform as a service, где мы можем писать наш обработчик без необходимости поднимать какие-то сервисы.

Преимущества AWS Lambda Function:

  • Serverless cumpute server — он работает сам по себе
  • No-ops!
  • Node.js — это самая элегантная из имплементаций. Мы пишем Javascript-функции, и когда мы дергаем этот сервис, там они отрабатываются.
  • Поддержка Python (мы пишем скрипт с какими-то функциями, и это все прекрасно работает)
  • Java 8.


С Java 8 все гораздо сложнее. В Java у нас нет каких-то top-level-функций, которые мы можем написать и вызывать, — все это должно быть завернуто в классы. Наш друг Сергей Егоров на короткой ноге с ребятами, которые пилят Lambda, и сейчас работает над тем, чтобы Groovy можно было использовать в Lambda не так, как сейчас (когда мы делаем jar-файл и работаем с ним так же), а напрямую через Groovy-скрипты, когда можно будет писать скрипты с колбеками, которые будут вызываться.

Speechlet


Класс, который обрабатывает запросы Alexa к Java, называется Speechlet. Когда вы видите спичлеты, вы вспоминаете про апплеты, про мидлеты и про сервлеты. И вы уже знаете, чего ожидать — контролируемого цикла исполнения, то есть, грубо говоря, какой-то интерфейс, который нам, как разработчикам, нужно будет имплементировать с разными фазами жизни нашего «лета», в данном случае — спичлета.

И вы не ошиблись, потому что вот у вас интерфейс Speechlet, где есть четыре метода, которые нам нужно имплементировать:

public interface Speechlet {
void onSessionStarted(SessionStartedRequest request, Session session);
       SpeechletResponse onLaunch(LaunchRequest request, Session session);
       SpeechletResponse onIntent(IntentRequest request, Session session);
void onSessionEnded(SessionEndedRequest request, Session session);
}


В начале оnSessionStarted — это когда Alexa поднимается и осознает, что у нее есть спичлет. onLaunch — это когда мы вызываем команду с названием нашего скилла. onIntent — когда с нами поговорил человек, и мы получили то, что он сказал, в виде Json и команду, которую он назвал. onSessionEnded — это когда мы делаем обычный клинап.

В общем-то очень похоже на любой другой «лет», и сейчас мы посмотрим, как все выглядит в коде.

Где писать Speechlet


Существует два места в Амазоне, с которыми нам нужно работать:

bictkhvfrazj3t5dshsjf2a9num.png

  • Alexa Skill Kit, где мы описываем новый скилл (интерактивную модель, метаданные, название, куда обращаться, когда идет запрос).
  • Lambda или любой другой сервис, где у нас живет speechlet, который является обработчиком запросов. То есть, грубо говоря, у нас получается примерно так:


gzri1yxr5bwrdnef-1-wtqtpega.png

У нас есть юзер, который говорит: «Alexa, ask Jenkins how«s my build?». Это приходит в устройство, в данном случае — в Amazon Tap. Дальше все идет в тот самый скилл, который превращает голос в JSON, обращается в Lambda Functions и дергает Jenkins API.

Пример кода: JbToolBoxActivator Speechlet


Теперь самое время посмотреть на код
(https://github.com/jbaruch/jb-toolbox-alexa-skill/blob/master/src/main/groovy/ru/jug/jpoint2017/alexa/jbtoolboxactivator/JbToolBoxActivatorSpeechlet.groovy)

Вот наш спичлет. Мы вынесли в константы Help Test, Default Question и так далее. У нас есть HTTP BUILDER, напомню, это сервис, который бежит к Amazon Lambda. Соответственно, он должен дергать что-то по интернету. На самом деле это Groovy, но добавьте boilerplate, и будет вам Java.

На оnSessionStarted мы конфигурируем наш HTTP клиент, говорим, что будем стучаться в тулбокс по такому-то хосту и такому-то порту. Дальше мы считываем из файла список поддерживаемым тулзов, который вы тоже уже видели (List of tools.txt).

Из onLaunch мы выдаем HelpResponse. Этот тот самый, о котором вы слышали, — я могу открывать такие же тулзы.

310be981575a6ff98546250c5baa8b56.png

Cамое интересное происходит в onIntent. Мы делаем switch по названию интента. То есть из всех команд, которые у нас были, что к нам пришло. В данном случае, если вы помните, у нас было два интента. Один — это open, который наш кастомер, а другой — это help. Еще могут быть stop, cancel и любые другие.

e434f072e434e733c8eee51f7a739963.png

И вот самое интересное — openIntent. Мы из него вынимаем тот самый слот, тул (у нас это были IDEA и так далее), и дальше обращаемся по HTTP-билдеру в наш URI плюс вот этот тул. То есть мы обращаемся к API JetBrains Toolbox, который понимает этот формат.

Соответственно, потом мы возвращаем ответ. Ответ у нас может быть или Opening $toolName, или, если тул не в списке: Sorry, I can«t find a tool named $toolName in the toolbox. Goodbye.

Хелп работает хелпом, стоп и кансел делает Goodbye. Если пришел интент, которого у нас не существует, мы кидаем invalid Intent.

Все предельно просто, я специально написал его таким простым, чтобы вы увидели, как это просто.

onSessionEnded у меня ничего нет. Тут у меня есть метод newAskResponse, который в чистейшем виде boilerplate в течение десяти строчек кода создает три объекта: один объект, в который в конструкторе теоретически нужно перевести два других, в которых нужно перевести какие-то тексты. В общем все, что он делает, — создает объект SpeechletResponse, в котором у нас есть OutputSpeech text и repromptText. Почему это занимает десять строчек кода? Ну, так исторически сложилось, мы об этом немного поговорим. Надеюсь, все остальное, кроме этого бойлерплейта, понятно и просто.

Пример кода: Jenkins Speechlet


Давайте осмотрим на другой skill. И в этот раз пойдем наоборот: от кода к скиллу и в конце попробуем его запустить. Вот Jenkins speechlet — обработчик скилла, который управляет Дженкинсом (https://github.com/jbaruch/jenkins-alexa-skill/blob/master/src/main/groovy/ru/jug/jpoint2017/alexa/jenkins/JenkinsSpeechlet.groovy).

Все начинается очень похоже: оnSessionStarted мы инициализируем HTTPBuilder, который будет обращаться к Дженкинсу через Rest API в JENKINS_HOST и авторизоваться с определенным username и password. Вот это, конечно, через environment variables не очень правильно. У Alexa есть целая система, которая позволяет регистрироваться с username и password в скилл, то есть когда мы инсталлируем этот скилл на нашей локальной Alexa, открывается окно, в котором мы можем залогиниться. Но для простоты здесь мы берем username и password у environment variables.

onLaunch мы отбарабаним тот же текст: «Приветствуем вас, гигантские морды, мы управляем Дженкинсом», — и тут начинается наш интересный onIntent.

Тут у нас, соответственно, побольше интентов, имеет смысл посмотреть нашу модель — https://github.com/jbaruch/jenkins-alexa-skill/blob/master/src/main/resources/speechAssets/IntentSchema.json

У нас есть LastBuild, который, очевидно, вернет нам информацию про наш последний билд, GetCodeCoverage, который вернет нам информацию о покрытии кода, и FailBuildIntent, который завалит билд. Кроме того, есть еще куча встроенных, таких как help, stop, cancel и даже yes, no. Посмотрим, что мы, собственно говоря, делаем с этими yes и no.

Начнем. Вот к нам пришел интент, и мы берем у него данные по имени. Если у нас попросили last build, то мы пойдем в Jenkins API и возьмем оттуда список билдов с их именем и цветом (цвет красный или синий — прошел или не прошел). Возьмем last, билд с таким-то названием, прошел он или не прошел.

GetCodeCoverage — опять же, мы обратимся к Jenkins API, к плагину, который называется jacoco. В нем, как и в любом хорошем плагине, есть масса параметров. Мы возьмем один — lineCoverage — и получим какую-то информацию.

FailBuild — это запрос на превращение приходящего билда в фейловый. Не хотелось бы сразу на это соглашаться. Alexa часто отзывается впустую, поэтому есть вероятность случайно зафейлить билд. И мы у нее попросим подтверждения. Мы пошлем еще один запрос и скажем: «вот я хочу завалить билд» «Действительно ли это то, что ты имел в виду?». Мы положим в sessions. Это как раз то, что держится через разные invokations, и мы положим какой-то флаг в fail requested.

И дальше у нас есть то самое yes-no. Если мы ответили да, то нужно проверить, был ли вопрос или, может, мы просто так сказали «да». И если вопрос был, то опять же, мы создадим какой-то post request, в этот раз в наш Jenkins API, и завалим job. И если действительно job стал красненьким, мы скажем, что мы завалили job, а если нет — ничего не получилось. Ну и stop — мы говорим Goodbye и выходим.

Такая интересная функциональность, и кода тут на одну страницу. Я пытался усложнить код, но там нечего усложнять, потому что это на самом деле так просто.

После этого мы собираем все это грейдлом, причем Gradle тут простейший. У меня тут есть куча зависимостей: groovy, который мне, естественно, нужен, плюс три зависимости вот этого API, логгер, commons-io, commons-lang. Все! testCompile — естественно, у меня тесты под это дело. И дальше я строю ZIP, в котором в главной директории лежит мой jar. Кроме того, есть директория lib со всеми зависимостями. Реально проще некуда.

9ef54da2021670cefd6d37a162af09a5.png

Использование Alexa Skill Kit


Теперь посмотрим, что мы делаем с этим билдом. У нас есть два места, куда мы реально обращаемся. Первое — Alexa Skill Kit, в нем есть все скиллы, которые я написал. Давайте посмотрим на Jenkins Skill.

3ccnd_4frnrnz2wxcncth5kre6q.png

Как я уже сказал, тут у нас есть metadata: название и invocation name — то самое слово (Дженкинс), когда я говорю: «Alexa, попроси у Дженкинса сделать то-то».

pkezpl5ov6a8amasmvmglr9yfe8.png

Далее можно указать, нужен ли мне аудиоплеер (если я, к примеру, хочу стримить звук, например, играть музыку, проигрывать новости и так далее)

ad28965299cc273e0eefb973d1ca8043.png

Дальше у нас есть наша интерактивная модель — тот самый JSON, который описывает интенты.

qvbvrt3jd0izjt2ybedqepffakk.png

Тут нет никакого слота, но в JetBrains у нас был бы custom slot и у этого слота были бы values и примеры, которые работают на мои интенты.

5a77a53cbe7b7c5c9228e902a6ce2fe0.png

Вкладка конфигурации — что я вызываю: Lambda или HTTPS.

5cb22178f1fe5c64a7b99318af681e05.png

Тут же есть тот самый Account Linking — даем ли мы возможность залогиниться при настройке скилла (и по идее, в Jenkins было бы неплохо это сделать).

fb6b0cb6c5ed6c84b162bd817296ce18.png

И дальше Permissions для всяких покупок, но это нас уже не очень интересует.

192b772b3e8c43c94cf6b641f0a60512.png

Вкладка тестирования — тут я могу писать то, что она будет делать, если я буду говорить.

dqwmn5pphjbhs6n4s7vhbq4qwt8.png

Дальше вкладка Publishing Information. Скилл проходит всякие проверки у Амазона. Я должен им рассказать, какая от него польза, как это тестируется и так далее.

Использование AWS Lambda


Вторая часть работы со скиллом — это моя AWS Lambda. Там у меня нет ничего, кроме этих трех скиллов.

u4oleru0ynokergndonirj2zx1o.png

Давайте посмотрим на Jenkins. Сюда я заливаю тот самый jar, который построил Gradle. Еще здесь есть variables (host, password и user).

18xy3sh6aasllq3vzvc-u-jz1pu.png

В конфигурации я пишу, какой мне нужен runtime. Как я уже говорил, поддерживается Node, Python, Java. И недавно стал поддерживаться С#. Дальше — handler. Это — где внутри находится мой спичлет. Role у меня называется lambda_basic_execution. И у меня есть description. Все.

txdvswzu3dahd6ujiuoh5iawssu.png

Триггер приходит из Алексы. Есть специальный вид триггеров, который называется Alexa Kit. Это значит, что вызов будет оттуда.

edzfxpqzrcmaaj6edcecbgnbzjs.png

И тут тоже можно потестировать, если известно, какой JSON Алекса посылает Лямбде. А я знаю, какой, ведь когда я это буду тестировать здесь, я увижу этот Jenkins. И сейчас давайте посмотрим на этот Jenkins. Я послал запрос: how is my build.

bcd290d5189b50171707a90df6a9c326.png

Я послал intent, intent называется last build, и Alexa сообразила, что я хочу.

9vxlo5ekxwulrqjtgmatcxc7d3u.png

Это все обернуто в JSON, который я могу протестировать в Лямбде. Я могу сказать: я посылаю вот этот JSON. И когда я это скажу, я могу протестировать только этот кусок.

bblvfw4ub00eojiiskbcx0tvwio.png

Да, у меня есть тестирование end to end вот с этой штукой распознавания голоса (текст в JSON, в Лямбду и потом обратно) или я могу этот тестировать только на уровне Лямбды, если я знаю тот JSON, который нужен.

Демонстрация работы Jenkins Speechlet


В общем, пора бы уже запустить все. У нас есть Jenkins, и у меня есть билд предыдущего скилла.

y1vmqdp_xbniuijvbxyi-8ctgg0.png

Дальше у меня происходит вот такой диалог с системой:

Барух: Alexa, open Jenkins
Alexa: With this skill you can control your build server
Барух: Alexa, ask Jenkins, how is my build?
Alexa: You last build jb-toolbox-alexa-skill is passing. What do you want to do next?
Барух: What«s the code coverage?
Alexa: The code coverage for the last jb-toolbox-alexa-skill build is 30%. What do you want to do next?
Барух: Fail the build.
Alexa: I understand you want to fail the latest successful build. Are you sure?
Барух: Yes
Alexa: Successfully changed the build status to failed. Thank you and goodbye.

mqiorkk7mkmnto7u7oayfyu6ypu.png

Это очень круто и очень просто, даже стыдно за такой легкий уровень.

Визуальный компаньон Alexa


Кроме голосового интерфейса, у Alexa есть визуальный компаньон. Это приложение, в котором кроме настройки всех девайсов, интернета и прочего, есть еще карточки. Это такой стрим из информации, которая является вспомогательной для голосового интерфейса. В общем-то, это здравая мысль, потому что не все можно сказать голосом. Если я, например, сейчас запросил code coverage, и она мне дала какую-то метрику — на самом деле jacoco возвращает шесть метрик: покрытие по branch execution, по методам, по линиям кода и т.д. Естественно, имеет смысл отобразить это визуально в приложении. Это можно сделать одной строчкой — есть команда «пошли текст в приложение». И дальше туда можно посылать простой текст, картинку или html, которые будут там отображаться. Например, если спросить о погоде, помощник даст краткий ответ. В приложении же можно увидеть погоду на всю неделю. Также я сейчас проверил, что у меня дома заперт замок, и что мой сын в данный момент включил себе сказку о Красной Шапочке. Вот как это выглядит:

buo34loc4f11guznt8wmcv722pk.png

Недостатки Alexa: мнимые и реальные


Давайте теперь поговорим про два вида недостатков: мнимые и реальные. Первый — мнимый — связан с распознаванием речи. Пользователь может говорить с акцентом или не очень внятно произносить слова. Я не знаю, как они это делают, но Alexa прекрасно понимает даже моего маленького сына, хотя мы с женой понимаем его далеко не всегда.

Второй мнимый недостаток показан на иллюстрации ниже.

decb07bd3fc149bed762ec0ca9f79439.png

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

Еще существует такой аспект: «Ой-ой-ой, нас постоянно слушают». Это все давным-давно уже реверс-инжинирнули, всем прекрасно понятно, что слушают. Единственное, что слушают постоянно, — это триггер-слова. То есть когда я ее зову. Иногда триггер-слова произносятся случайно, после этого в течение десяти секунд записывается, что мы говорим, и запись отсылается на главный интент, на главный скилл. Если там она не распознается, то выкидывается в мусор. Поэтому вся эта паранойя неоправданна.

А теперь мы с вами поговорим про реальные недостатки. Их можно разбить на несколько категорий.

Есть недостатки voice user interface. Они связаны с тем, что некоторые называют вещи одинаковыми словами. Попробуйте попросить музыку группы Helloween и не получить музыку к празднику Halloween. Думаю, что, учитывая прогресс, контекст должен эту проблему решить, потому что Alexa уже должна знать, что между музыкой к празднику Halloween и группой Helloween я предпочитаю группу. К этому все идет, но пока что это еще не так, особенно — если контекст непонятен.

И еще одна проблема. Связана она с отсутствием поддержки нестандартных названий и имен. Если Alexa не знает какое-то имя или название, то она не сможет его произнести.

Кроме того, у самой Alexa как у консьюмерского девайса, тоже есть недостатки:

  • Не понимает множественные команды. Я могу построить интерактивную модель, как мы сделали с Jenkins, когда я не произносил каждый раз ее имя для передачи следующей команды. Но, например, выполнить команду «Alexa, turn on TV and set living room lights to 20%» на данный момент она не может. И если команд много и ты ими пользуешься постоянно, это надоедает.
  • Не работает в кластере. Несмотря на то, что у меня дома семь таких девайсов, каждый из них считает себя единственным. И поэтому если я стою в месте, где их три, то все три мне отвечают. Кроме того, я не могу с помощью одной включить музыку у другой, потому что они не знают, что их больше, чем одна. Эта проблема известна, над ней работают и, надеюсь, скоро это будет решено.
  • Не знает, где она находится и где нахожусь я. Из-за этого Alexa не может среагировать на команду «Turn on the lights». Я должен сказать «Turn on the lights in the bedroom», и это глупо.
  • Само приложение сделано на html5, оно медленное, кривое, но это тоже чинится.
  • Понимает только три языка: британский английский, американский английский и немецкий. Соответственно, по-русски ее еще пока не научили.


Самые большие и мерзкие недостатки вылезают при попытке написать Alexa Skill, например тот, который мы сейчас делали. Java API — это кошмар, голосовую модель нужно вручную копировать на страничку, и это указано даже в документации. Кроме того, нет никакого бутстрапа: ни Maven Archetype, ни Lazybones Template.

Нет никакой локальной тестовой инфраструктуры, то есть если я поменял единственную строчку в коде, мне нужно пойти на сайт скилла и поменять ручками в text area json, a потом пойти на Лямбду и загрузить там новый jar (ну, на Lambda, допустим, есть Rest API, потому что она все-таки написала для разработчиков, туда можно сделать continuous deployment, там все нормально). Но на стороне skill kit при любом изменении мне нужно пойти и все это загрузить и потестировать только на сервере. Локально никакой инфраструктуры нет, и это, естественно, тоже очень большой минус.

Заключение


Вот и все. Скиллы, о которых шла речь, можно взять с моего Github — jb-toolbox-alexa-skill и jenkins-alexa-skill. У меня к вам есть большая просьба: давайте придумывать и писать полезные скиллы, тогда мы сможем вернуться к этой теме на следующих конференциях.

Чтобы вы не пропустили ни одной детали, под спойлером мы оставили для вас ответы на вопросы из зала

Вопрос о безопасности. Есть ли вероятность брутфорса, когда пин-код может быть подобран (например, чтобы открыть дверь)?

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

Смартфон, ноутбук при включении могут требовать аутентификацию. Как обстоят дела с Alexa?

У Alexa нет никакого пин-кода на включение, ты можешь его украсть и включать и выключать свет у меня дома. А все опасные штуки по идее должны быть защищены пин-кодом. На данный момент нет никакого voice recognition, хотя над этим работают, и это будет прикручено к аутентификации.

Что вы можете сказать об Alexa в сравнении с Google Home?

Google Home намного моложе Alexa, и у него пока что много проблем. Самая главная — это то, что писать скиллы для Google Home намного сложнее. Это требует намного большего уровня вхождения, что не очень хорошо для адаптации этой технологии. Однако у Google Home есть большое преимущество — собственный поисковик. У Alexa его нет, поэтому без кастомного поискового скилла Гугла обойтись невозможно.

Ты показывал большие и маленькие устройства Alexa. Есть ли смысл ставить много больших устройств?

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



Надеемся, вам пригодится опыт Баруха. А если вы любите смаковать все детали разработки на Java так же, как и мы, наверняка вам будут интересны вот эти доклады на нашей апрельской конференции JPoint 2018:

  • Анализ программ: как понять, что ты хороший программист (Алексей Кудрявцев, JetBrains)
  • Приключения Сеньора Холмса и Джуниора Ватсона в мире разработки ПО (Барух Садогурский, JFrog и Евгений Борисов, Naya Technologies)
  • Extreme scaling with Alibaba JDK (Sanhong Li, Alibaba)

© Habrahabr.ru