IA et Bot Framework : apprendre à créer un agent conversationnel en utilisant FormFlow
Un billet d'Hinault Romaric

Le , par Hinault Romaric, Responsable .NET
Il y a de nos jours un réel engouement pour les chats bots. Ils sont utilisés dans les applications pour par exemple guider les utilisateurs à effectuer des achats, comme s’ils s’adressaient à un être humain, effectuer des réservations, fournir des conseils, etc.

Microsoft offre le bot framework pour permettre aux développeurs d’intégrer facilement les bots dans leurs solutions.

Dans ce billet de blog, nous verrons comment mettre en place un agent conversationnel en utilisant Bot Framework et FormFlow.

Prérequis

Pour la bonne compréhension de cet article, vous devez avoir des connaissances en :

  • Programmation C# ;
  • ASP.NET Web API ;
  • Visual Studio ;
  • Bot Framework.


Outils à installer

Cet article suppose que vous disposez des outils suivants sur votre ordinateur :

  • Visual Studio 2017 ;
  • Bot Framework emulator ;
  • Les templates pour Bot Application, Bot Controller et Bot Dialog installés.


Si votre environnement n’est pas encore configuré, vous pouvez consulter l’article suivant pour voir comment procéder. https://docs.microsoft.com/en-us/bot...net-quickstart

Introduction à FormFlow

Imaginez que vous devez mettre en place un bot qui va guider un client dans la commande d’une Pizza à partir d’un large catalogue de choix avec des options : quelles questions doivent être posées, quelles questions ne doivent pas être posées en fonction des réponses du client, quel doit être la prochaine question en fonction du choix du client, quand revenir en arrière, comment permettre au client de modifier ses choix, quand est-ce que la conversation doit être interrompue, etc. La mise sur pied d’un algorithme qui permettra de guider l’utilisateur de façon optimale en utilisant Dialogs peut s’avérer assez complexe.

C’est pour fournir une solution à cette problématique que Microsoft a mis en place FormFlow. Il s’agit d’une fonctionnalité disponible avec le SDK Bot Builder pour .NET, qui permet de générer automatiquement « les dialogues » qui sont nécessaires pour mettre en place une conversation guidée.

Selon Microsoft, le recours à FormFlow peut réduire de façon significative le temps nécessaire à la création d’un Bot. Par ailleurs, FormFlow peut s’intégrer facilement avec les autres types de dialogues disponibles.

Création de l’application

Voyons maintenant comment mettre en place un Bot avec FormFlow. Nous allons développer un bot en mesure de procéder à une enquête. Le bot doit donc être capable de poser des questions à l’utilisateur et récupérer ses réponses. Il doit permettre à celui-ci de modifier ses réponses ou encore afficher un résumé des réponses de ce dernier. Bref, il doit offrir la meilleure expérience utilisateur possible.

Nous allons commencer par créer l’application en utilisant Visual Studio et le modèle BotApplication :


Création du questionnaire avec FormFlow

Notre questionnaire va être représenté par une classe SurveyForm. Cette classe aura des propriétés qui définiront les informations que le bot aura besoin de collecter dans le cadre de notre enquête. Les types supportés par FormFlow sont les suivants :

  • Integral (sbyte, byte, short, ushort, int, uint, long, ulong)
  • Floating point (float, double)
  • String
  • DateTime
  • Enumeration
  • List of enumerations


Cette classe doit également disposer d’une fonction BuildForm. Elle doit retourner un Iform. Dans cette méthode, vous devez créer et retourner une nouvelle instance de FormBuilder.

Pour mettre cela en place, nous allons donc créer un nouveau fichier SurveyForm.cs dans le dossier Forms (que vous devez créer).

Nous devons dans un premier temps définir les différentes réponses à nos questions. Nous allons utiliser des énumérations :

Code c# : Sélectionner tout
1
2
3
4
5
6
   public enum JobOptions {Developpeur_junior=1, Developpeur_senior, Architecte, Autre}; 
    public enum ExperienceOptions {Moins_de_5_ans=1, De_5_a_10_ans, Plus_de_10_ans}; 
    public enum PlatformOptions {Web =1, Mobile, Cloud, Desktop}; 
    public enum LanguageOptions {Csharp=1, Java, JavaScript, C, Ruby, Python,  Autre}; 
    public enum WebFrameworkOptions { ASPNET_Core = 1, AngularJS, Laravel, ReactJS, NodeJS, Autre}; 
    public enum CloudOptions {Microsoft_Azure=1, Google_Cloud_platform, Amazon_Web_Services, IBM_Cloud, Autre};

Il faut noter qu’avec FormFlow, lorsque vous utilisez une énumération pour définir une propriété, la valeur 0 représente par défaut nul. Si votre propriété n’a pas de valeur nulle, l’énumération doit commencer à 1.

Ensuite, nous devons définir les propriétés de notre SurveyForm :

Code c# : Sélectionner tout
1
2
3
4
5
6
     public JobOptions Job; 
        public ExperienceOptions Experience; 
        public PlatformOptions Platform; 
        public List<LanguageOptions> Language; 
        public WebFrameworkOptions WebFramework; 
        public CloudOptions Cloud;

Et afin, ajouter la méthode BuildForm qui permettra de générer un formulaire FormFlow :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
  
public static IForm<SurveyForm> BuildForm() 
        { 
            return new FormBuilder<SurveyForm>() 
                    .Message("Merci de prendre quelques minutes pour répondre aux questions de cette enquête.") 
                    .Build(); 
        }

Le code complet de cette classe est le suivant :

Code c# : Sélectionner tout
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
27
28
29
30
31
32
33
34
35
using System; 
using System.Collections.Generic; 
using Microsoft.Bot.Builder.FormFlow; 
  
namespace FormFowBasic.Forms 
{ 
    [Serializable] 
    public class SurveyForm 
    { 
                 public JobOptions Job; 
        public ExperienceOptions Experience; 
        public PlatformOptions Platform; 
        public List<LanguageOptions> Language; 
        public WebFrameworkOptions WebFramework; 
        public CloudOptions Cloud; 
  
        public static IForm<SurveyForm> BuildForm() 
        { 
            return new FormBuilder<SurveyForm>() 
                    .Message("Merci de prendre quelques minutes pour répondre aux questions de cette enquête.") 
                    .Build(); 
        } 
  
    } 
  
  
    public enum JobOptions {Developpeur_junior=1, Developpeur_senior, Architecte, Autre}; 
    public enum ExperienceOptions {Moins_de_5_ans=1, De_5_a_10_ans, Plus_de_10_ans}; 
    public enum PlatformOptions {Web =1, Mobile, Cloud, Desktop}; 
    public enum LanguageOptions {Csharp=1, Java, JavaScript, C, Ruby, Python,  Autre}; 
    public enum WebFrameworkOptions { ASPNET_Core = 1, AngularJS, Laravel, ReactJS, NodeJS, Autre}; 
    public enum CloudOptions {Microsoft_Azure=1, Google_Cloud_platform, Amazon_Web_Services, IBM_Cloud, Autre}; 
  
  
}

Mise à jour de la classe MessagesController

Notre bot est une WebAPI. Le point d’entrée de toute communication avec le bot est le contrôleur MessagesController. Nous allons modifier son code pour utiliser SurveyForm.

La première chose à faire sera d’ajouter une méthode statique MakeRootDialog(). Cette méthode doit permettre de générer un nouveau dialogue en utilisant la méthode BuildForm de notre classe SurveyForm. Nous devons utiliser la classe Chain qui est utilisée pour le chainage des dialogues, ensuite faire appel à sa méthode From pour construire notre dialogue. La méthode From crée une nouvelle copie d’un autre dialogue. C’est pourquoi nous devons utiliser la fabrique FromDialog pour créer un dialogue à partir de notre SurveyFrom.

Ensuite, nous allons utiliser le delegate Do de la classe Chain pour définir ce qui sera exécuté à la fin du dialogue. Elle peut être due :

  • à une exception ;
  • à un arrêt volontaire de l’utilisateur ;
  • ou à l’atteinte de la fin du questionnaire.


Nous allons donc implémenter ce qui sera affiché à l’utilisateur dans les différents scénarios ci-dessus. Le code de MakeRootDialog est le suivant :

Code c# : Sélectionner tout
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
internal static IDialog<SurveyForm> MakeRootDialog() 
        { 
            return Chain.From(() => FormDialog.FromForm(SurveyForm.BuildForm)) 
                .Do(async (context, survey) => 
                { 
                    try 
                    { 
                        var completed = await survey; 
                       await context.PostAsync("Merci pour votre participation !"); 
                    } 
                    catch (FormCanceledException<SurveyForm> e) 
                    { 
                        string reply; 
                        if (e.InnerException == null) 
                        { 
                            reply = "Vous n’avez pas complété l’enquête !"; 
                        } 
                        else 
                        { 
                            reply = "Erreur. Essayez plus tard !."; 
                        } 
                        await context.PostAsync(reply); 
                    } 
                }); 
        }

Nous devons maintenant modifier la méthode Post pour utiliser makeRootDialog :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public async Task<HttpResponseMessage> Post([FromBody]Activity activity) 
        { 
            if (activity.Type == ActivityTypes.Message) 
            { 
                await Conversation.SendAsync(activity, MakeRootDialog); 
            } 
  
            else 
            { 
               await HandleSystemMessage(activity); 
            } 
            var response = Request.CreateResponse(HttpStatusCode.OK); 
            return response; 
        }

Pour finir, nous souhaitons que le bot soit en mesure d’afficher un message pour engager la conversation avec un utilisateur. Pour le faire, nous devons modifier la méthode HandleSystemMessage comme suit :

Code c# : Sélectionner tout
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
27
28
29
30
31
32
33
34
35
private async Task HandleSystemMessage(Activity message) 
        { 
            if (message.Type == ActivityTypes.DeleteUserData) 
            { 
                // Implement user deletion here 
                // If we handle user deletion, return a real message 
            } 
            else if (message.Type == ActivityTypes.ConversationUpdate) 
            { 
                if (message.MembersAdded.Any(o => o.Id == message.Recipient.Id)) 
                { 
                    var reply = message.CreateReply("Bonjour"); 
  
                    ConnectorClient connector = new ConnectorClient(new Uri(message.ServiceUrl)); 
  
                    await connector.Conversations.ReplyToActivityAsync(reply); 
                } 
  
            } 
  
            else if (message.Type == ActivityTypes.ContactRelationUpdate) 
            { 
  
            } 
  
            else if (message.Type == ActivityTypes.Typing) 
            { 
                // Handle knowing tha the user is typing 
            } 
            else if (message.Type == ActivityTypes.Ping) 
            { 
            } 
  
  
        }

En effet, au démarrage d’une nouvelle session de chat, le type de message sera ConversationUpdate. Si c’est un nouvel utilisateur qui rejoint la section, nous devons lui afficher le message Bonjour. Nous devons éviter que le message soit affiché plusieurs fois pour le même utilisateur.

Si vous exécutez l’application et testez ce dernier en utilisateur le bot emulator, vous obtiendrez ce qui suit :





Vous pouvez répondre en cliquant directement sur votre réponse dans le texte, ou en saisissant votre réponse. Une fois la réponse à une question obtenue, le bot affiche la prochaine question. Si vous saisissez une réponse qui n’est pas valide, il vous affiche un message :



Il est aussi capable de filtrer ses choix de réponses, pour afficher uniquement ce qui correspond à ce que vous avez saisi si votre réponse est incomplète :



À la fin du sondage, il affiche le récapitulatif de vos réponses, afin que vous puissiez les valider :





Si vous répondez Non, il va afficher l’ensemble des questions avec les réponses que vous avez choisies, en vous donnant la possibilité de modifier celles que vous souhaitez changer.

Il est intéressant de noter, comme vous l’avez probablement remarqué, que FormFlow supporte le français. Pour déterminer le langage à utiliser, FormFlow utilise CurrentUICulture et CurrentCulture du thread courant.

Imaginez le degré de complexité de notre application si c’était à nous de développer ce comportement. FormFlow nous rend la vie beaucoup plus facile.

C’est tout pour ce billet. Dans le prochain billet, nous verrons les options de personnalisation que nous pouvons utiliser pour améliorer le texte et le rendu de notre questionnaire.

Le code source de cet exemple est disponible sur mon GitHub


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :


 Poster un commentaire

Avatar de aissatoudado aissatoudado - Nouveau Candidat au Club https://www.developpez.com
le 23/04/2018 à 22:31
bonjour je suis un nouveau sur la plateforme j'aimerai avoir une aide, j'ai un projet de developpement d'une plateforme de reservation d'hotel en ligne mais je ne sais pas quelles sont les fontionnalités qui sont indispensables donc je solicite d'aide pour les personne qui s'y connaissent un px
Avatar de Dewey12 Dewey12 - Membre régulier https://www.developpez.com
le 28/04/2018 à 19:36
Super article ! Merci

Ca soulève des questions :
1) Utilisation de données présentes en base
2) Utilisation (simple) hors de l'émulateur, notamment sur un site web dédié
3) Je l'impression, qu'il n'y a une dépendance avec des services Microsoft ?

A suivre
Avatar de Hinault Romaric Hinault Romaric - Responsable .NET https://www.developpez.com
le 03/05/2018 à 0:13
Citation Envoyé par aissatoudado Voir le message
bonjour je suis un nouveau sur la plateforme j'aimerai avoir une aide, j'ai un projet de developpement d'une plateforme de reservation d'hotel en ligne mais je ne sais pas quelles sont les fontionnalités qui sont indispensables donc je solicite d'aide pour les personne qui s'y connaissent un px
Bonjour,

Le forum est le meilleur endroit pour obtenir une réponse à ta question. Par ailleurs, je vais souligner que c'est un lieu pour aider et non pour faire le travaille des autres à leur place. Tu dois faire les premières recherches sur le projet que tu souhaites développer avant de demander de l'aide.
Avatar de Hinault Romaric Hinault Romaric - Responsable .NET https://www.developpez.com
le 03/05/2018 à 0:20
Citation Envoyé par Dewey12 Voir le message
Super article ! Merci

Ca soulève des questions :
1) Utilisation de données présentes en base
2) Utilisation (simple) hors de l'émulateur, notamment sur un site web dédié
3) Je l'impression, qu'il n'y a une dépendance avec des services Microsoft ?

A suivre
1) Utilisation de données présentes en base

Un bot est avant tout une application Web, dont il est possible d'accéder aux données d'une BD comme on le fait de façon standard pour une application web ASP.NET.

2) Utilisation (simple) hors de l'émulateur, notamment sur un site web dédié

L'émulateur permet de tester son bot en local. Dès lors que ce dernier est déployé, vous pouvez intégrer une fenêtre de chat à*un site web, par exemple, pour converser avec le bot, ou configurer tout autre canal de communication : Skype, Facebook Messenger, etc.

3) Je l'impression, qu'il n'y a une dépendance avec des services Microsoft ?

Une fois votre bot développé, vous pouvez le déployer sur n'importe quelle plateforme d'hébergement offrant une prise en charge de ASP.NET. Par contre, pour que votre bot soit accessible via une interface de chat (web, mail, Skype, Facebook, etc.), vous devez créer un service Azure (Bot Channel Registration) et configurer vos canaux de communication.

Donc, oui il y a une forte dépendance avec des services Microsoft.
Contacter le responsable de la rubrique Accueil