Contexte

Dans ce billet, nous allons parcourir le projet Voicebot, et nous attarder sur le contexte, les problématiques, les choix des technologies et le développement réalisé.
Nous allons nous intéresser aux parties qui ont posé des problèmes à l’équipe de développement / design, afin de décrire les points de difficultés que peuvent présenter ces différentes combinaisons de technologies en tenant compte du contexte.
Le projet Voicebot a été initié dans un contexte bancaire, et dans le but d’identifier la façon la plus optimale de construire un agent vocal avec les technologies existantes, contraint par les problématiques suivantes.

Problématiques

Métier

Benchmark des NLP

Architecture

Développement

Pour résumer

Problématiques

Langues

Ce Voicebot doit être multilingue. Non pas anglais et espagnol, mais Italien, Allemand et Français. Autant dire que le choix des technologies de language processing gérant ces langues se comptent déjà sur les doigts de la main.
Une fois le NLP (Natural Language Processor) choisi, cette problématique implique également que l’entièreté du bot doit être multilingue. Nous allons donc voir comment nous avons géré cette problématique, et les difficultés rencontrées.

Sécurité

Le Voicebot traitant de données bancaires, la sécurité est un must. Il a donc fallu réfléchir aux problématiques d’ authentification, faible et forte. Les informations doivent en outre transiter en SSL, et, dans la mesure du possible rester au sein de l’union européenne.

Devices

Le Voicebot doit être accessible depuis une application mobile cross-plateforme, et sa partie publique depuis un device Google Home.

Métier

FAQ

La partie FAQ est la partie publique du Voicebot. C’est-à-dire qu’elle doit être accessible sans authentification depuis l’application mobile, et depuis le Google Home.

Authentification

L’authentification a été un sujet de discussion animé dans l’équipe durant la phase de conception technique.
Comment faire une authentification forte par la voix, qui soit aussi optimale qu’une authentification type User / mot de passe avec JWT token ? Spoiler : On ne peut pas. Mais voici quelques idées parmi d’autres qui ont surgi lors de nos discussions.
– La génération d’un code à lire par la voix, après l’instauration d’une relation de confiance (par une authentification forte préalable par exemple).
– L’identification d’une image précédemment communiquée à l’utilisateur – à l’issue d’une authentification forte – parmi un lot généré aléatoirement (modulo ladite image).
– Les méthodes d’authentification biométriques. Cette méthode n’a pas été abandonnée, nous y reviendrons plus bas.

Benchmark des NLP

Dialogflow

Dialogflow vient tout de suite se présenter comme le NLP le plus performant et le plus à même de répondre à toutes nos problématiques.
Cet acteur incontournable qu’est Google dans presque tous les domaines, permet de gérer toutes les langues qu’il nous faut gérer, et cela dans un environnement prêt à la mise en production.
Seul problème, Google est américain, Dialogflow est hébergé sur Google Cloud Platform (GCP) qui n’est pas forcément en Europe (et encore moins en France). Ce qui ne respecte pas les normes de sécurité du Groupe en terme de données sensibles.
Désolé DialogFlow, mais tu ne nous seras bon qu’à gérer notre FAQ publique 🙁 .

Amazon Lex

Comment parler d’acteur incontournable comme Google, et ne pas parler du second géant du web qu’est Amazon.
Amazon Lex est la solution de NLP d’Amazon Web Services (AWS) et, avec un fonctionnement certes différent des NLP plus classiques comme Dialogflow ou Recast, mais il reste performant et prometteur.
Mais pourquoi Lex n’a pas été choisi comme NLP de référence me demanderez-vous ? Lex ne supporte simplement pas les langues que nous voulons gérer (au moment de la réalisation du Voicebot).

Recast

Enfin, Recast. Un des principaux acteur français de création de chat bot, pure player, multilingue (avec ses limites). Ce NLP a tout pour nous séduire et a finalement été notre choix final pour ce projet.
Il va sans dire qu’au bout de notre expérience avec Recast, et du fait que ce produit est en développement, nous allons pointer du doigt quelques limites de la solution et mettre en évidence quelques solutions de contournement à des problèmes découverts au court de la construction du Voicebot.

Architecture

Le Frontend

L’exploration de l’architecture du Voicebot débute par un frontend mobile cross-plateforme codé avec Ionic et Cordova.

Je le code

Ionic est un Framework qui permet de développer des applications mobiles en Typescript. Certains ajustements doivent être faits pour assurer quelques spécificités liées à chacune des deux plateformes, mais le tronc commun permet de grandement optimiser le temps de développement.
La seule chose que Ionic ne permet pas, c’est l’accès aux parties Hardware du téléphone, ou à tout ce qui réside en dehors du scope de l’application. Pour cela, nous utilisons Cordova.
Grâce à ce dernier, nous avons pu accéder à l’authentification par empreinte digitale ou au code pin présent sur le téléphone, mais également aux fonctionnalités de Speech to Text, et Text to Speech d’Android et IOS.
C’est également grâce à Cordova que nous avons détecté la langue de configuration du téléphone. C’est à partir de cette détection qu’une variable de langue va être passée dans les requêtes à toutes les couches et spécifier la langue à utiliser. Côté Front, des fichiers JSON propres à chaque langue contiennent tous les labels à afficher sur l’application.
Le Speech to Text est le procédé consistant à retranscrire un flux audio (la voix de l’utilisateur) en identifiant les mots dans une langue donnée en texte. C’est grâce à ce processus que nous allons pouvoir traiter la demande de l’utilisateur pour ensuite en déterminer le sens.
Le Text to Speech, à l’inverse (vous l’aurez compris) permet à un programme de transformer un texte en flux audio selon un algorithme de synthèse vocale dans une langue donnée.

Je l’utilise

Un voicebot, ce n’est que de la voix, pas besoin d’interface graphique

Certes, mais pas vraiment.
Même sur un Google Home, le retour lumineux indique si l’appareil est en état de processing, de réponse, d’écoute, ou s’il est simplement éteint.
Dans notre cas, il nous fallait également penser à un moyen de rendre naturel l’action de parler avec le bot ainsi que de savoir quand écouter ou quand attendre une réponse etc.
Pour cela, la petite mascotte O de Sofinco a été conçue et animée en fonction des états du bot.

TutorialDiscussionIddleConnexion

L’API Voicebot

Une fois que l’utilisateur a parlé à notre mascotte et que le frontend a transformé sa voix en texte (Speech to Text), ce dernier est fin prêt à être traité par le NLP. Mais avant ça, la requête va passer par une API intermédiaire.
Cette API va permettre au frontend de recevoir un message formatté constamment de la même manière (détection d’un code d’erreur dans le protocole mis en place, ou reformatage de la réponse si elle stipule un statut code 200), et de mettre en forme le texte d’entrée pour le NLP, ou dans certains cas, pour passer outre le NLP.
Cette API, petite mais nécessaire, est l’orchestrateur des requêtes partant du front, et revenant du NLP.

Le NLP

Le Natural Language Processor (NLP), est le cœur du bot. L’intelligence qui va être capable de lire une suite de caractères, et d’en déterminer le sens.
Le sens, ou l’intention de la phrase est représenté par un bloc logique qui pointe vers une entrée de l’API Webhook. Cette API va fournir une réponse au format texte dans un langage donné afin que le NLP puisse la retourner à son tour à l’API Voicebot.
Afin de déterminer une intention, un bot doit être entraîné. Une intention se déclenche lorsqu’un mot, une série de mots, un synonyme ou une phrase présente dans un champ lexical prédéfini va être détecté. Afin de déterminer ces champs lexicaux, pas de secret, il va falloir parler au bot. S’il ne comprend pas (ne rentre pas dans l’intention), alors il faut le recadrer, et lui dire qu’il avait tort : c’est l’entraînement.
Plus un bot est entrainé, moins il sera susceptible de ne pas comprendre le sens d’une phrase.
Par exemple si je dis « Bonjour », alors le bot doit rentrer dans l’intention « Salutation » et retourner « Bonjour, que puis-je faire pour vous ».
Maintenant, donnons notre Voicebot à un(e) utilisateur(trice) lambda : « Dia ! Comment va ? ». Le bot ne repère pas « Bonjour » et ne rentre pas dans l’intention souhaitée, laissant l’utilisateur perplexe. C’est alors au développeur d’aller dire au bot que c’est une autre manière de dire bonjour dans le sud de la France, et qu’elle doit être considérée comme telle.

L’API Webhook

A quoi sert-il de détecter une intention s’il n’y a rien à répondre ? Notre API est là pour ça.
L’API Webhook spécifie une série de points d’entrée (des routes) qui ont chacun une logique dite « métier » derrière. Cette logique va avoir accès aux données utilisateur, au contexte fourni par le NLP, et va pouvoir formatter une phrase de réponse dans une langue donnée.
La langue est récupérée depuis le front et va déterminer dans quel fichier de langue piocher la phrase de réponse (un fichier par langue).
Cette API va également juger si ce que lui dit l’utilisateur mérite que celui-ci soit authentifié pour accéder à la réponse. C’est le rôle du middleware.

Le middleware

Le middleware est chargé de décoder et d’analyser le token que chaque requête de l’utilisateur porte dans son header. Ce token, généré par Amazon Cognito lors de l’authentification de l’utilisateur en front, a une date de validité. Si elle est expirée, la requête ne passera pas. Si le token n’est pas conforme au token attendu, la requête ne passera pas. S’il n’y a pas de token dans le header, vous l’aurez deviné, la requête ne passera pas … enfin pas vraiment.
En effet, certaines requêtes ne nécessitent pas forcément une authentification. Ce sont les routes publiques. Ces routes, traitant généralement de la discussion de tous les jours avec le Voicebot ne font pas appel au middleware.
Par exemple, je peux très bien dire bonjour au bot, ou lui demander le temps qu’il fait ou sa couleur préférée. Mais pas question d’accéder à quelconques données métier (bancaire ou utilisateur dans notre cas) sans être authentifié.

Développement

Contournements / Solutions

Le NLP reformate tous les headers

Chaque requête qui transite par le NLP en ressort démunie de son header http. Difficile alors de transmettre le token d’identification à l’API Webhook.
Afin de pallier ce problème, nous avons mis en place une base Redis, chargée de stocker différentes données en cache. Parmi ces données : le JWT token et l’ID de conversation. Grâce à ces deux valeurs, l’API webhook sera en mesure de vérifier l’identité de l’utilisateur, ainsi que de récupérer l’état actuel de sa conversation avec le bot.

Le NLP ne renvoie que le statut 200

Quand une requête est envoyée, elle porte dans son header un statut, représenté par un code http. Le statut 200 indique que tout s’est bien passé.
Cependant, lorsqu’une erreur ou un manque d’autorisation émerge du côté de l’API Webhook, il faudrait qu’un statut d’erreur soit envoyé.
La résolution : mettons le statut dans le corps (body) de la requête et laissons l’API Voicebot se charger de le traiter comme il se doit. Le body de la requête de retour contient alors un JSON avec 2 clefs, une clef texte, et une clef statusCode.

Mon I-Phone m’écoute à l’infini

Sur Android, la fonction de Speech to Text gère toute seule la fin d’une phrase, et le fait savoir avec des signaux sonores qui indiquent l’écoute, et la fin de l’écoute.
Sur IOS, ce fonctionnement doit être développé.
La solution : détecter le bruit en décibels et créer des règles qui estiment qu’à partir d’un certain nombre de Dbs, l’utilisateur parle au téléphone, et passé en dessous, sa phrase et terminée.
Ce système mérite un temps de fine tuning pour gérer les situations où le bruit environnant dépasse le seuil défini.

Recast ne versionne pas ses bots

C’est peut-être le problème le plus handicapant de la liste.Sur Recast, 2 choses indispensables ne sont pas possibles :
• Revenir en arrière en cas d’erreur de modification du bot
• Exporter le bot (en une série de fichiers JSON comme le fait DialogFlow par exemple) afin de l’uploader sur une plateforme de versioning comme Git
Ces 2 lacunes font se poser la question de la viabilité de l’utilisation de Recast pour quelconques solutions ayant la prétention d’être utilisé en production pour une industrialisation.

Bugs et hacks notable

Mon I-Phone est timide

Sur IOS, un bug récurant a été constaté : le son (la réponse du bot) sortait dans la sortie du combiné (comme si l’utilisateur avait le téléphone à l’oreille) rendant le résultat inaudible.
Le hack de résolution consiste à appeler la fonction de lecture d’une phrase avec une chaîne contenant un espace avant de l’appeler avec la phrase voulue.
A noter que ce bug n’est présent que sur IOS

Recast ne parle pas Italien

Recast catégorise sa gestion de l’Italien comme « Standard ».
Dans les faits, Recast propose de rentrer des champs lexicaux en Italien, qui déclenchent les bonnes intentions. Jusque-là, tout va bien.
Cependant, quand il s’agit de voir un caractère, et d’identifier que c’est un chiffre, une date, un nom, un verbe etc, ne comptez pas sur lui.
Le Hack : créer un champ lexical « Nombre Italien », rentrer les nombres de 1 à 1 million en tirant un case Excel, et identifier les nombres italiens comme tels.

Pour résumer

Nous avons étudié le contexte et les problématiques liées au développement du Voicebot. Nous avons constaté des lacunes parmi les géants du web dans leur proposition d’une solution à même de servir des données bancaires.
Nous avons décrit une architecture type pour la construction d’un Voicebot et listé les composants essentiels dans chacune des briques la constituant.
Nous nous sommes attardés sur les problématiques qu’ont posées le choix de l’acteur qu’est Recast, et les solutions de contournement qui ont été nécessaires pour répondre aux problématiques de langue et d’industrialisation.
Nous tirons de ce prototype et de ces benchmarks que le Voicebot a de beaux jours devant lui tant il reste de choses à faire et à améliorer dans le domaine. En effet, même à l’échelle du temps de création de ce prototype, des fonctionnalités ont été ajoutées à Recast, Amazon a lui aussi ajouté des gestions de langues à sa collection etc.
A l’heure où Google prévoit une explosion des recherches par la voix dans les prochaines années, nous espèrons voir se multiplier et se standardiser les différentes technologies de language processing, au plus grand bonheur des développeurs, et nous attendons l’arrivée à maturité pour les utilisateurs d’une nouvelle manière de communiquer avec ses devices.