Dans le post précédent, nous avons créé un bot qui route simplement les messages de l’utilisateur sur notre dailog par défaut. Ce que je vous propose dans ce tuto, c’est d’utiliser LUIS afin de router les messages de notre utilisateur en fonction de leur contenu !

Objectif : notre bot doit permettre de commander une bière.

LUIS

Découverte

Pour commencer, allez sur LUIS et créez un compte.

page d'accueil luis

Sur la homepage, trois possibilités s’offre à vous :

  1. utiliser cortona prebuilt app : une appli préconçue qui permet d’avoir l’intelligence de l’assistant cortona. Utile pour certains cas : réservation d’hôtel, activer/désactiver une alarme, météo, réserver un vol,… Rapide à mettre en place, mais non personnalisable (une application LUIS ne peut pas en hériter).
  2. créer une nouvelle application : permet de concevoir une appli LUIS from scratch. Plus long, mais indispensable dans le cas ou la prebuilt app ne gère pas votre cas d’utilisation.
  3. importer une application existante : toute application LUIS peut être exportée (format json) puis importée.

LUIS va nous permettre d’analyser les réponses de l’utilisateurs et d’en extraire les informations qui nous intéressent. Quelle informations LUIS extrait-il d’une phrase ? Pour voir un exemple, utilisons l’application préconçue (cortona prebuilt app) en entrant la phrase suivante : Je souhaite réserver un hôtel à Paris en mars.

Ecran de test cortona prebuilt app

Vous devriez obtenir le résulat suivant :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

{
"query": "Je souhaite réserver un hôtel à Paris en mars",
"topScoringIntent": {
"intent": "builtin.intent.places.make_reservation"
},
"entities": [
{
"entity": "hôtel",
"type": "builtin.places.place_type"
},
{
"entity": "Paris",
"type": "builtin.places.absolute_location"
},
{
"entity": "mars",
"type": "builtin.places.date",
"resolution": {
"date": "XXXX-03",
"resolution_type": "builtin.datetime.date"
}
}
]
}

Ce qui va principalement nous permettre de déterminer la façon de traiter le message est l’intention. Ici, l’API a détecté que l’intention la plus probable était une réservation (propriété topScoringIntent). Viennent ensuite les entités, qui sont des informations en relation avec l’intention. L’API détermine le type de chacune des entités pour nous permettre de les utiliser pour l’intention : la réservation.

Dans notre cas d’étude, nous avons une intention : commander une bière. La quantité (25cl, 50cl, …) et la marque sont des entités.

Voyons comment procéder.

Création de l’application

Créez donc une nouvelle application :

Ecran de création d'une application LUIS

Nous arrivons sur l’écran de contrôle (alias dashboard) de notre application.

Sur le dashboard de notre appli vous pouvez voir que nous avons déjà une intention : None. Elle sera l’intention par défaut si LUIS n’arrive pas à déterminer une autre intention.

1.Intention

Créons notre première intention :

Ecran d'ajout d'une intention

Juste après l’ajout de notre intention, LUIS nous demande de saisir des phrases qui induisent cette intention. Le but est de saisir plusieurs phrases qui représente afin d’entraîner notre bot à la reconnaître/l’identifier. Logiquement, plus vous allez saisir de phrases d’exemples, plus l’application reconnaîtra facilement l’intention.

Ecran de saisie des phrases

Passons à la saisie des entités.

2.Entity

A. Saisie des entités

Vous pouvez ajouter des custom entity ou des prebuilt entity. Que signifie prebuilt ? LUIS nous propose une liste d’entités qu’il sait déjà identifier. Vous trouverez la liste ci-dessus :

Liste prebuilt entity

Ajoutons notre première entité : la marque. Vous pouvez voir qu’il existe trois types d’entité :

  • Simple : entité générique qui décrit un concept simple. Nos entités seront de ce type.

ajout entité simple

  • Hierarchical : entité formée d’un parent et plusieurs entités enfants partageant les mêmes caractéristiques. Utile lorsque vous souhaitez identifier une ou plusieurs entités et que leur ordre est important. Cas typique d’utilisation : plage de date ou encore lieu de départ et d’arrivée.

  • Composite : entité composée de plusieurs entités existantes (prebuilt et/ou custom). Par exemple si l’on souhaite que notre bot gère la commande de plusieurs bières dans une même phrase, il nous serait nécessaire de créer une entité composée afin d’associer la marque et la quantité pour chacune des bières commandées. Sans utiliser d’entité composite, nous aurions des marques de bière et des quantités non liées en résultat et donc inexploitables.

Nous avons saisie nos entités !

liste de nos entité

B. Identification

Bon maintenant il faut aider LUIS à les identifier. Pour cela nous allons utiliser nos précédentes phrases (lors de la saisie de notre intention) et lui indiquer les entités présentes dans chacune :

identification des entités

Dans l’écran entity in use vous devriez avoir le résultat suivant :

entités utilisées

3.Train & Test

Notre application est presque prêtre, il nous faut maintenant l’entraîner ! Pour cela, allez sur l’écran Train & Test. Avant toute chose, il faut entraîner une première fois notre application :

entrainement

Maintenant deux possibilités : tester manuellement votre application ou lui filer un jeux de données.

Nous allons la tester manuellement, voir si elle identifie correctement notre intention et nos entités dans différentes phrases :

entrainement manuelle

Notre application est preque prête ! Nous allons utiliser une dernière fonctionnalité afin d’accroitre la reconnaissance de nos entités : les Features.

4.Features

Les features ont pour but d’améliorer rapidement la dectection des intentions et des entités. Deux possiblités :

  • Phrase list features : peut être vu comme une liste de synonymes liés à une entité ou à une intention. Dans notre cas, les quantités commandées peuvent être exprimées de différentes façon : 25cl, un demi, un quart de litre, … Si dans les phrases d’exemples nous avons principalement taggué demi comme étant une quantité, l’application sera que les élements de cette liste peuvent être traité similairement.

feature

  • Regex features : utile pour identifier un pattern qui apparaît régulièrement dans votre cas d’utilisation. Cas typiques : codes produits, numéros de vol,…

5.Publication

Bon il nous reste une dernière étape pour enfin pouvoir utiliser notre nouvelle application LUIS dans notre Bot : la publier ! Pour cela, il nous faut une clé lié à un endpoint. Dans l’UI de LUIS, vous trouverez un menu my keys qui vous permettra d’enregistrer une nouvelle clé. Il y a trois types de clé :

  • Programmatic API Key : clé associée à votre compte LUIS qui vous permet de gérer vos applications LUIS via l’API. Sachez que toutes les actions que nous avons menées jusqu’ici peuvent être réalisée via l’API de LUIS.
  • External Key(s) : clé nécessaire pour coupler votre application LUIS à certain service externe, type Bing Spell Check service.
  • Endpoint Key(s) : une clé que l’on obtient à partir du portail Azure. C’est la clé que l’on veux !

Sélectionnez Endpoint Key puis Buy key on Azure, rassurez vous nous allons prendre une clé gratuite pour la démo :)

écran de création du endpoint

Une fois le endpoint créer, allez chercher la clé sur l’écran de gestion des clés :

gestion des clé

Ajoutez le key1 dans l’interface de gestion des clés de LUIS, puis retourner dans le menu publish. Vous avez sans doute remarqué que l’on dispose de deux slot pour publier son appli : staging pour les tests et validation puis production. Associez la clé à votre App puis publiez la sur le slot statging.

Notre application LUIS est déployée, go dans le code de notre bot pour l’utiliser !

Intégration dans le Bot

Reprenez le code du tuto précédent. Si vous ne l’avez pas vous le trouverez ici

Première étape, renseignez l’url de notre application LUIS puis créez un objet IntentDialog à mapper sur notre route par défaut. Toutes requêtes sera traitées par cet objet et passera donc par notre application LUIS.

1
2
3
4
5
6

let url = 'url de votre application LUIS';
let recognizer = new builder.LuisRecognizer(url);
let intents = new builder.IntentDialog({ recognizers: [recognizer] });
bot.dialog('/', intents);

Il ne nous reste plus qu’à lier les intentions à notre IntentDialog :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

intents.matches('orderBeer', [
(session, args, next) => {
let brand = builder.EntityRecognizer.findEntity(args.entities, 'brand'); // Extraction d'entité
let size = builder.EntityRecognizer.findEntity(args.entities, 'size'); // Extraction d'entité
session.send(`Vous avez commandé une ${brand.entity} en ${size.entity}. Elle est en cours de préparation !`);
}
]);

intents.matches('None', [
(session, args, next) => {
session.send(`Je n'ai pas compris votre demande`);
}
]);

Et voilà, notre Bot est prêt à recevoir des commandes ! Évidemment, il y a énormement d’axes d’améliorations à prévoir pour que notre Bot puisse acomplir au mieux sa tâche :

  • Entraîner d’avantage notre Bot afin qu’il devienne incollable sur les marques et quantités qu’il est possibles de commander.
  • S’il n’arrive pas à trouver les entités, peut-être que l’utilisateur les a omise, dans ce cas prévoire de prompter l’utilisateur pour lui demander.
  • On pourrai également modifier notre application LUIS puis notre Bot afin qu’il apporte des conseils à un utilisateur qui ne sait pas quel bière commander.

LUIS fait partie de la famille des cognitives services de Microsoft :

liste cognitives services

En couplant notre Bot à ces services, nous avons une multitude de possibilités pour améliorer l’expèrience offerte par notre BeerBot :)

Le code du projet sur mon github : https://github.com/felixbillon/BeerBot

A très vite !