Créer et déployer un Skill Alexa sur AWS Lambda

Après plusieurs mois d'attente interminable, le service Alexa et les hauts parleurs intelligents d'Amazon sont enfin disponibles en France.

C’est l’occasion pour nous de vous accompagner pour prendre en main la plateforme Alexa Skills Kit et voir la méthodologie à suivre pour déployer un chatbot sur AWS Lambda

1. Les bases

Alexa est un assistant personnel créé par Amazon avec qui l'utilisateur peut discuter via un haut-parleur intelligent comme le Amazon Echo (et toutes ses déclinaisons, au nombre de 5 actuellement). Google Assistant est son homologue de la firme de Mountain View et il fonctionne à la fois sur mobile et sur les haut-parleurs Google Home. Alexa et Assistant viennent chacun avec plusieurs fonctionnalités de base (aussi appelés domaines) comme :

  • jouer de la musique
  • récupérer les news ou la météo
  • interagir avec la domotique
  • ...

Pour être efficace et utile, un assistant personnel doit faire un peu plus que ses domaines par défaut. C’est là qu’interviennent les Skills (compétences). Ce sont des chatbots spécialisés que les assistants utilisent pour répondre à des demandes particulières. Ces Skills, créés par des développeurs tiers, sont des services web plus ou moins complexes respectant les API (REST) de l'assistant par lequel ils veulent être exposés : Alexa Skill Kit pour Alexa et Google Assistant SDK/DialogFlow API pour Google.

Avec une architecture logicielle bien faite, un développeur peut tout à fait mutualiser son Skill en l'exposant sur Alexa et Assistant. Il pourra aussi le rendre disponible sur les applications de messagerie telles que Facebook Messenger ou Skype.

Si vous voulez en savoir plus sur les chatbots en général, je vous redirige vers cet article:

Après cette brève introduction, nous allons voir plus en détail comment créer un Skill Alexa et comment le déployer sur AWS Lambda (architecture Serverless).

2. Un Skill, c’est quoi ?

Un Skill est l'équivalent d'une application (ou service) avec laquelle nous accédons et interagissons par la voix (ou le texte). Comme tout chatbot, le Skill doit respecter un certain protocole d'interaction utilisateur édicté par la plateforme de diffusion. Étant un gage de qualité pour la plateforme (Alexa ou Assistant), il faut passer par une phase de validation avant de pouvoir rendre public son Skill pour les utilisateurs (comme cela a été le cas pour les applications mobiles).

Pour Alexa, l’étape de validation prend entre 2 et 4 semaines. Le processus de validation d’un Skill peut paraître long mais permet à Amazon de mettre à disposition des Skills avec des flux de conversation robustes et de qualité. Ce délai sera amené à être réduit au fur et à mesure que l’audience sera conquise et que l’usage des assistants sera plus généralisé.

Les Skills peuvent être créés et publiés de façon totalement gratuite. Nous reviendrons sur ce point plus tard.

Cas pratique

Dans cet article nous allons prendre comme exemple la création d'un Skill permettant de commander un sandwich. Nous allons voir comment créer le Skill, comment faire en sorte que ce Skill puisse comprendre notre intention de commander un sandwich, comment récupérer des variables telles que le type de sandwich que nous voulons commander.

Cet article vous permettra également de voir comment récupérer et utiliser ces informations dans un backend serverless comme Lambda.

La phrase ci-dessus est un exemple de phrase que sera capable de comprendre notre Skill.

Wake Word et Déclencheur

L'utterance représente la formulation d'une demande à faire à Alexa afin de commander un sandwich. Nous retrouvons tous les éléments que nous avons détaillé précédemment.  Nous pouvons remarquer qu'il y a également deux nouveaux éléments : le "Wake word" et le "Déclencheur" .

Pour déclencher le traitement d'un ordre vocal, Alexa a besoin d'être interpellée. C'est ce que nous appelons un wake-word, . Dans l'exemple nous avons pris le wake-word "Alexa" mais il en existe d'autres si vous le souhaitez :

  • Alexa
  • Amazon
  • Echo
  • Ordinateur

Le déclencheur est un mot de liaison qui précède le nom du Skill que nous voulons utiliser. Il existe plusieurs mots déclencheurs afin d'activer les Skill que nous voulons de façon naturelle la plus naturelle possible :

  • Demande à ...
  • Dis à ...
  • Lance ...
  • Va sur ...

Un nom pour l’invoquer

Quand nous cherchons à utiliser une application sur son smartphone, nous connaissons son nom mais nous la reconnaissons plus souvent grâce à son icône qui la rend identifiable parmi les autres. C’est la même chose pour un Skill sauf qu’ici il n’y a pas de logo mais seulement un nom. Pour ouvrir un Skill, il faudra donc connaître son nom, c’est pourquoi il est crucial de donner un nom original, significatif et unique à son Skill tout en restant dans la simplicité.

Si par exemple notre Skill s’appelle "Mon déjeuner", il faudra dire "Alexa, ouvre Mon Déjeuner". A partir de ce moment là, l'utilisateur entre dans l'univers du Skill et interagit avec une logique métier implémentée par le développeur (sous forme de questions/réponses plus ou moins éditorialistes ou dynamiques).

Une autre façon d’invoquer un Skill est de dire "Alexa, demande à Mon Déjeuner de …", cela permet au Skill d’être invoqué et d’exécuter une action en une seule phrase.

Le nom faisant partie de l’identité d’un service, les développeurs indépendants devront être prudents à ne pas utiliser une marque déposée sans l’autorisation de son propriétaire. Après litige par exemple, seule la RATP sera autorisée à utiliser le nom RATP pour son Skill Amazon.

Une intention pour se faire comprendre

Lorsqu’un utilisateur invoque un Skill c’est parce qu’il a quelque chose à demander. Quand il demande une information ou demande d’exécuter une action, le Skill va devoir déterminer l’intention sous-jacente de l’utilisateur. Par exemple en reprenant l’exemple du Skill "Mon Déjeuner" nous pouvons dire :

  • "Alexa, demande à Mon Déjeuner de commander un sandwich"
  • "Alexa, dit à Mon Déjeuner de commander un jambon beurre"

L’intention de l’utilisateur est de commander un sandwich. Alexa nous permet d’associer un événement à cette intention pour effectuer une action dont nous verrons les détails un peu plus tard.

Des utterances pour parler de façon naturelle

En invoquant un Skill pour lui demander quelque chose, nous voudrions qu’il soit capable de reconnaître notre intention quelque soit la façon dont la requête est formulée. C'est ici qu'entre en jeu la notion d’utterance.

Les utterances sont une ensemble de formulations plus ou moins équivalentes que l’on pourra associer à une même intention.

Les plateformes de chatbots intègrent toutes des moteurs de "Natural Language Understanding" (NLU) basés soit sur des mots-clés, des modèles de phrases ou sur le Machine Learning. Si vous voulez en savoir plus sur les moteurs de NLU, je vous redirige vers cet article :

Pour garantir la robustesse du NLU à reconnaître des intentions pour votre cas d'usage, il est nécessaire de créer des utterances qui seront utilisées dans une phase dite d'entraînement. C’est pourquoi il faut créer ou collecter des dizaines d’utterances pour une même intention.

Dans le cas précédent, les utterances "commande moi un sandwich" et "je veux un sandwich jambon beurre" sont deux utterances qui reflètent la même intention.

Des entités pour tout paramétrer

Dans une utterance, il se peut qu’il y ait quelques variations possibles, notamment sur l'objet de la demande. Par exemple avec l’utterance "Commander un jambon beurre" l'utilisateur pourrait très bien vouloir commander un sandwich "poulet curry" à la place.

C’est pour ce genre de cas que nous utilisons des entités (aussi appelées slots) qui consituent la partie variable d'une utterance. L’utterance devra donc être décomposée de :

  • une partie fixe : "Commander un"
  • une partie variable : "jambon beurre"

L’utterance prendra donc une forme du type : "Commander un {typeDeSandwich}".

Il pourra évidemment y avoir plusieurs entités dans la même utterance mais aussi des valeurs par défaut ou des entités obligatoires/optionnelles.

Une des tâches du moteur NLU sera de détecter et extraire les valeurs des entités afin de permettre un traitement particulier de celles-ci (stockage, envoi à une API, table de correspondance ou synonymes).

Pour que le moteur de NLU puisse extraire une entité d'une utterance, il lui faut un type qui lui est associé. Les moteurs NLU fournissent par défaut quelques types tels que des nombres, les dates, des personnes ou des lieux. Il y aussi des types personnalisés basés sur un marquage manuel (tagging) par utterance, via liste de synonymes ou par expressions régulières.

Dans notre cas, nous allons créer un type spécifique "typeDeSandwich" qui contiendra une énumération des différents sandwichs attendus comme "jambon beurre" ou bien "poulet curry" ou encore "saumon avocat".

3. Comment créer un Skill pour Alexa ?

Paramétrage initial

La façon la plus rapide et visuelle de créer un Skill est de passer par la console développeur d’Amazon.

Avant toute chose, il faut tout d’abord créer un compte Amazon Developer. Si ce n’est pas déjà fait, rendez-vous à l’adresse suivante : https://developer.amazon.com/

Rendez-vous ensuite sur votre console de développeur et sélectionner "Alexa Skills Kit" dans la barre de navigation. C’est avec ce service que vous allez créer un Skill Alexa.

Cliquez maintenant sur "Create Skill".

Vous arrivez sur une page qui demande de renseigner le nom du Skill ainsi que la langue par défaut de votre Skill. Ici, le nom du Skill est purement informatif et n'est pas celui d'invocation qui sera utilisé pour le démarrer depuis Alexa.

Pour en savoir plus sur le choix d'un nom de Skill, je vous redirige vers cet article :

Le choix de la langue est très important car c’est celle-ci qui déterminera la langue des utterances que vous voudrez détecter et la réponse d’Alexa aux différentes intentions. Nous choisirons ici "French (FR)" pour créer un Skill en français.

Si vous voulez avoir un Skill disponible dans plusieurs langues, il faudra en créer plusieurs.

L’étape suivante est de sélectionner le type de Skill que l’on veut créer. Amazon met à disposition trois modèles : "Flash Briefing" , "Smart Home" et "Custom" Les deux premiers sont en fait des domaines prédéfinis permettant respectivement de se connecter à des sources d’information ou d’interagir avec des objets de domotique.

Dans notre cas, nous choisirons l’option "Custom" .

Les éléments clés de la création de votre Skill

C’est maintenant que le travail commence.

  1. Nom d’invocation

Il faut tout d’abord créer le nom d’invocation du Skill qui permettra à Alexa de démarrer notre Skill et de le distinguer parmi d'autres. Le nom du Skill doit être prononçable de façon concise et sans ambigüité comme par exemple "mon déjeuner". Il ne faut pas oublier les possibles accents, les mots sont interprétés de façon phonétique et donc un accent en moins peut totalement changer la façon dont le Skill est appelé.

  1. Création d’entité (Slot Type)

À partir du menu gauche de l’interface, il faut créer une entité (slot type) que nous appellerons "typeDeSandwich" qui va être une énumération des différents types de sandwichs.

Il faut là aussi ajouter "jambon beurre" et "poulet curry" à la liste et également leur donner des synonymes pour améliorer la reconnaissance par le moteur de NLU.

  1. Les intentions

Il faut maintenant créer des intentions en leur donnant un nom. Le nom de l’intention servira d’identifiant pour le code métier et doit donc être représentatif du sens porté par les utterances comme par exemple "OrderSandwich" . Comme nous l’avons vu plus haut, plus le nombre d’utterances est important plus le moteur de NLU comprendra l’intention véhiculée. Il faut donc saisir plusieurs utterances comme par exemple "Commande un sandwich" et "Commande un jambon beurre" .

  1. Marquage des slots dans les utterances

Pour chaque utterance, Il faut marquer les mots décrivant le type de sandwich. Pour cela, il suffit de sélectionner dans l’utterance le nom du sandwich. Une fois le slot sélectionné, vous allez devoir lui associer un type (entité). Il est possible d’utiliser un type par défaut fourni par Alexa mais aucun ne permet de correspond à la reconnaissance de sandwichs, nous utiliserons donc notre type "typeDeSandwich" .

  1. Construire le modèle

L’étape suivante consiste à lancer le création du modèle à partir des utterances et intentions que nous avons défini en cliquant sur "Build model" en haut de la console Alexa. Cette étape prend généralement moins d’une minute.

  1. Hébergement

Dans le cadre du développement d’un Skill un peu évolué, vous aurez certainement besoin d’un serveur web ou une fonction Lambda/Cloud Function qui hébergera du code technique pour effectuer des traitements métier. C'est le point que nous allons aborder au chapitre suivant.

Hébergement du code technique ou métier

Pour faciliter l’hébergement de notre code, nous utiliserons AWS Lambda. C’est un service d’Amazon permettant d’exécuter du code sans avoir besoin de configurer et gérer de serveurs. Le code est exécuté seulement quand c’est nécessaire, c’est à dire quand le serveur reçoit une requête de la part d’Alexa dans notre cas. Il faut donc créer un compte sur http://aws.amazon.com/. C’est un service payant mais le premier million de requêtes est gratuit (pour l’instant). Dans notre cas une requête correspond à une interaction avec le Skill.

En allant sur la console AWS, il faut créer une nouvelle fonction Lambda.

Il y a ensuite trois possibilités : une fonction "From scratch" , un modèle ou bien "Serverless Application Repository" . Nous choisissons de créer une fonction Lambda à partir d'un modèle, ce qui permet d'avoir déjà d'avoir une base de code avec des modules Node.js déjà installés sur la Lambda.

Nous avons à notre disposition plusieurs modèles qui incluent un runtime Node.js ainsi que le Alexa Skill Kit (ou ASK) permettant de communiquer avec notre Skill Alexa.

Dans la barre de recherche saisissez "alexa" et choisir "alexa-Skill-kit-sdk-factSkill" par exemple.

Communication entre Lambda & Skill

Pour permettre au Skill d’appeler notre fonction Lambda, il faut autoriser la fonction Lambda à s'activer quand elle reçoit une requête venant d'Alexa. Pour cela, nous devons sélectionner "Alexa Skills Kit" comme déclencheur de la Lambda sur la console AWS.

En cliquant dessus, vous devez renseigner un "Skill ID" qui est l’identifiant unique permettant de communiquer avec notre Skill. Cet identifiant se trouve en allant sur l’onglet "Endpoint" dans la console Alexa, en ayant sélectionné "AWS Lambda ARN" . Cet identifiant commence par "amzn1.ask.Skill" .

Il faut également renseigner dans le Skill l'adresse ARN de la Lambda que nous avons créé. Cet identifiant se trouve en haut à droite de la console AWS et commence par "arn:aws:lambda" . Les adresses ARN peuvent être régionalisées afin de couvrir plusieurs zones géographiques et ainsi réduire la latence entre la requête de l'utilisateur et la réponse d'Alexa.

Interface de la console AWS

Interface de la console Alexa

Implémentation de la Fonction Lambda

Le code du Skill présent par défaut dans la lambda ne correspond pas aux intentions de notre Skill. Nous allons utiliser un outil très pratique pour générer le code de notre Lambda à partir du modèle d'interaction du Skill.

Le modèle d'interaction du Skill est disponible au format JSON. Nous y retrouvons le nom d’invocation du Skill, les intentions avec les différentes utterances et leurs entités. Le site https://skillinator.io/ va générer le code Lambda automatiquement à partir de ce fichier JSON.

Le code généré vient remplacer celui fourni en exemple, il ne faut pas oublier de renseigner l’identifiant du Skill dans la constante "APP_ID" . Pour notre Skill, nous souhaitons renvoyer le message "Merci d’avoir commandé le sandwich"lorsque l’intention "OrderSandwich" est détectée. Le code est le suivant:

'OrderSandwich': function() {
    let typeDeSandwichSlotRaw = this.event.request.intent.slots.typeDeSandwich.value;
    let typeDeSandwichSlot = resolveCanonical(this.event.request.intent.slots.typeDeSandwich);

    let baseSpeechOutput = `Merci d'avoir commandé le sandwich`;
    const speechOutput = (typeDeSandwichSlot === undefined) ? `$(baseSpeechOutput)`:`$(baseSpeechOutput) $(typeDeSandwichSlot)`

    this.emit(":ask", speechOutput, speechOutput);    
}

Vous remarquerez que ce bloc utilise le nom exact de l’intention de notre Skill.

Un Skill plus intelligent

La fonction Lambda met à disposition un runtime Node.js, son comportement est donc le même qu'une application Node.js classique.

Selon le cas d'utilisation de notre Skill et ce que nous souhaitons lui faire faire faire, nous pouvons tout à fait le connecter à différents services qui exposent des API REST. Il est  tout à fait possible d'installer des modules Node.js avec npm et les utiliser dans notre Lambda s'il y a besoin, et donc bien sûr consommer des API REST.

Pour ce genre de cas plus complexe il est préférable de développer le code de son backend en local puis de le déployer sur notre Lambda au lieu d'utiliser l'éditeur en ligne fournit par Lambda. Cela permet notamment d'utiliser npm ou yarn pour installer des packages, chose qui est impossible avec l'éditeur en ligne de Lambda. Pour en savoir plus sur la création de package de déploiement pour Lambda, je vous redirige vers ces deux articles :

Dans notre exemple de Skill permettant de commander un sandwich, nous pourrions par exemple consommer l'API REST de JustEat pour créer un ordre d'achat pour un sandwich quand l'utilisateur dira à Alexa une phrase du type "Alexa, demande à mon déjeuner de passer une commande de sandwich poulet curry" .

4. Comment tester un Skill ?

Pour tester le Skill, il faut aller sur la console développeur Alexa et cliquer sur l’onglet "Test" dans la barre de navigation supérieure.

Sur la partie gauche de l’écran, vous avez accès à un simulateur Alexa, ce qui vous permettra d’utiliser notre Skill.

Vous pouvez par exemple dire à Alexa : "Alexa, demande à mon déjeuner de commander un sandwich" .

Cette requête est envoyée au serveur Alexa qui va identifier le Skill à utiliser (mon déjeuner) et reconnaître l’intention de l’utterance grâce au moteur de NLU. Alexa envoie ensuite l’intention à notre service Lambda qui utilisera le Alexa Skills Kit pour traiter l’intention reconnue. La réponse est ensuite renvoyée à Alexa.

5. Pour finir ?

La chaîne de développement de skills pour Alexa est assez complète avec les notions de NLU (intentions, entités) et d’intégration dans un back-end.

Toutefois, nous ressentons un manque du côté de la gestion des versions du skill ou d’environnements de déploiement (développement, staging, production) qui permettraient d’avoir un processus qualité que l’on trouve dans le développement logiciel habituel. À noter toutefois qu’Amazon fournit des APIs complètes d’administration et d’injection qui permettent d’automatiser l’entraînement du skill et son déploiement.

Formation

Si le sujet des agents conversationnels vous intéressent, nous avons mis en place un cursus de 2 jours pour se découvrir ou se perfectionner dans la création de chatbots.

Au cours de cette formation, nous vous proposons de découvrir les méthodes de création d'un chatbot (CUX, VUI, entraînement), les solutions qu'offrent les acteurs du marché ainsi que les technologies sous jacentes (NLU, NLP, API).

A travers un cas pratique, vous apprendrez à maîtriser le processus de création d'un chatbot, vous approfondirez les bonnes pratiques à adopter ainsi qu'à piloter les différentes étapes d'un projet "chatbot" .

Formation Chatbot : créer son premier agent conversationnel