Tu m’entends quand je te parle ? (partie 3)

Suite + 1

Dans la suite des journées 1 & 2, je continue le développement de ma petite application permettant d’échanger avec le téléphone. Aujourd’hui, on va essayer d’intégrer avec un ChatBot. Je sais, les chatbot c’est “So 2017” et pas du tout 2018 mais est-ce ma faute à moi si je suis toujours en retard ? ;)

Choix

En regardant rapidement, je suis tomber sur plusieurs solutions :

Il y en a peut-être d’autres … Pour les premiers pas, je vais essayer “DialogFlow” pour deux raisons: un c’est l’ordre alphabétique et deux: c’est le premier qui sort dans les recherchers (Google ? ;)). Une autre raison est que je également trouvé un plugin cordova pour cette API.

Dialog Flow

Création d’un agent

Pour commencer, il faut créer un agent. Personnellement, je vois un agent comme un “projet”. Cet agent va recueillir les données entrantes ‘input’ et les faire passer dans les différentes règles mises en place. Au niveau interface, c’est simple, il faut cliquer sur “CREATE AGENT”. Un formulaire va apparaître vous permettant de paramétrer la langue par défaut, la timezone et de lier au projet Google. Je me suis pas embêter: France, Madrid et nouveau projet.

Une fois l’agent crée …

Il est possible de créer directement des “Intents”. Les “Intents” comme le nom l’indique doivent être vus comme les intentions de l’utilisateur. Du moins, celle que l’on essaye de déterminer. Il est également possible de créer des entités. Suite aux différentes lectures, je vais commencer par créer des entités.

Pourquoi ? Parce que ?

Je commence par cela car lors de la création des intents, il est possible de “mapper” certains entrants avec justement des entités. Donc il me semble assez logique de commencer par cela.

Création de deux entités

Pour mon test, je crée deux entités : @quartier et @numero_animal. Voici la définition de quartier :

La première colonne correspond à la valeur qui sera recherchée et retournée. La deuxième colonne présente les différents synonymes possible. Cette liste est importante car même si DialogFlow propose des entités par défaut (country, last_name, date, nombre, …), il ne peut pas tout détecter et spécialement quelque chose d’aussi métier que le quartier …

.

Le numéro d’animal reprend le même principe. Au final, je n’étais pas obligé de créer cette entité car j’aurais pu demander à rechercher un nombre. Mais l’idée était de l’aider à sélectionner les bons nombres et pas se mélanger avec éventuellement d’autres informations.

Et maintenant l’intent

Dans le cas du test, je n’ai crée qu’un seul Intent qui permet d’aider à la saisie d’une mammite. Pour commencer, il faut mettre des phrases (Training Phrases) qui correspondent à des entrées possibles d’un utilisateur. Sur cette base d’exemples, DialogFlow sera capable de comprendre d’autres formats d’entrées plus ou moins correspondant :

Pour chaque phrase, il est possible (souhaitable) d’indiquer les champs qui vont être les différents paramètres attendus pour l’action finale (ici, la saisie d’une mammite). Dans l’exemple de la dernière phrase, j’ai mappé sur un numéro d’animal, une date et différents quartiers. Cela renseigne directement le tableau des paramètres :

J’ai marqué tous les champs comme étant obligatoire (required). Cela permet d’avoir une fonctionnalité très pratique : si les données ne sont présentes dans la première phrase saisie par l’utilisateur, il sera possible d’avoir directement une question pour chaque paramètre manquant. D’où le fait de pouvoir saisir un libellé (prompts) pour les paramètres obligatoires

Il faut également noter que le paramètre “quartier” est une liste pour pouvoir gérer qu’une mammite est potentiellement sur plusieurs quartiers…

Tests

L’interface permet de tester directement l’agent :

Dès le premier test, il est possible de voir que la phrase d’entrée ne correspond pas tout à fait aux phrases mais le système est quand même capable de faire le lien et d’extraire les informations.

Intégration dans le chat

Plugin

Comme indiqué dans le début de l’article, il existe un plugin cordova pour communiquer avec DialogFlow. Pour l’installer, la commande habituelle :

ionic cordova plugin add cordova-plugin-apiai

NOTE: le plugin est pour le moment compatible uniquement avec la version 1 de l’API. Une V2 est disponible. Il faut aller modifier cela dans les paramètres de l’agent.

Mise en place et utilisation

Simple !

Il faut commencer par activer le plugin avec la clé (qui se trouve dans les paramètres de l’agent) :

platform.ready().then(() => {
            ApiAIPromises.init({
                clientAccessToken: "[AGENT_TOKEN]"
            })
                .then((result) => console.log(result))
        });

puis il faut faire appel aux services avec l’input de l’utilisateur :

ApiAIPromises.requestText({
     query: message
   })
   .then((data) => {
      this.zone.run(()=> {
          let answer;
          console.log(data);
          if(data.result.actionIncomplete) { 
              // l'action n'est pas complète donc on simplement pose la question
             answer = data.result.fulfillment.speech;
          } else {
             // l'action est complète : on retourne un résultat
             answer = this.chatService.getBotAnswer(data.result);
          }
          this.sendSystemMessage(answer);
          this.tts.speak({
                      text: answer
                      , locale: 'fr-FR'
                      , rate: 0.85
                  });
      });

La complexité n’est pas là :)

Tests

Les images suivantes vous montrent différents tests réalisés

A noter la gestion des dates : il y a 2 jours fonctionne bien !

Un souci de liste

Un point que sur lequel j’ai buté : la détection d’une liste de quartiers. Sur l’interface de test :

Il semble être en mesure de détecter les quartiers … Par contre, sur l’application :

Pourquoi : je ne sais pas encore …

Bilan : mitigé

Honnêtement, je suis assez bluffé par le capacité d’adaptation du système. Par contre, je suis déçu de la partie documentation: je n’ai pas trouvé d’information ni de guide sur des choses qui me paraissent important :

  • Comment chaîner des actions ?
  • Comment permettre l’identification selon deux critères: numéro et nom animal par exemple ?
  • Comment reprendre un échange ? revenir en arrière dans la discussion ?

Mais bon… je n’ai fait qu’une journée …

Update 1

Action suivante

Bon forcément j’ai fini par trouver comment faire une action suivante : il existe les “Follow-up intents” qui permettent de faire la suite d’un intent de départ.

L’élément intéressant est la notion de contexte. En effet, en créant ce nouvel “Intent”, DialogFlow ajoute automatiquement un context en sortie du premier Intent et un context en entrée du second :

Le contexte contient les données ce qui permet de les utiliser dans le second Intent

Récupération de valeurs

Transition : la récupération des valeurs se fait par le contexte ! Et là, il est encore possible de les passer en réponses de plusieurs manières !

Il est possible de remettre comme des paramètres :

Comme Payload dans la réponse:

Mais également dans le contexte :

Bref … on peut la trouver à plein d’endroits !

Adaptation du code

Avec les avancés, je peux modifier le code de mon application Android qui devient simplement :

ApiAIPromises.requestText({
           query: message
         })
         .then((data) => {
            this.zone.run(()=> {
                console.log(data);
                const answer = data.result.fulfillment.speech;
                this.sendSystemMessage(answer);
                this.tts.speak({
                            text: answer
                            , locale: 'fr-FR'
                            , rate: 0.85
                        });
            });

En effet, je me suis arrangé pour que les réponses soient directement dans envoyé par l’Intent :

Liens