Fermer

janvier 6, 2021

Construire un chatbot pour commander une pizza


Nous construisons un PizzaBot en utilisant le Bot Framework v4 de Microsoft pour aider à prouver que les chatbots sont passés d'un projet secondaire astucieux à un nouveau canal de marketing et de vente.

Les chatbots sont passés d'un simple modèle d'entrée / sortie à un outil automatisé pour le marketing, les ventes et les opérations (ChatOps). Une partie de cette croissance est due au désir de faire plus avec moins de monde en automatisant, et je pense que l'autre partie est alimentée par des films populaires qui montrent des super-héros assistés par des IA. Quelle que soit la raison, les frameworks de bots ont évolué pour correspondre aux utilisations croissantes des bots complexes.

Nous allons concevoir un chatbot pour commander une pizza à l'aide du SDK Bot Framework v4 de Microsoft. Le Bot Framework de Microsoft fournit de nombreuses fonctionnalités permettant de créer un chatbot modulaire ainsi que des utilitaires permettant de le déployer facilement dans Azure. Nous allons utiliser certains des modèles modulaires du framework pour concevoir notre chatbot et implémenter des mécanismes de stockage pour le stockage au niveau de la conversation et le stockage au niveau de l'utilisateur.

Bot Framework Background

Microsoft a publié la version 4 de son Bot Framework. en septembre 2018. La version V4 a mis l'accent sur l'utilisation d'ASP.NET Core, ainsi que sur l'ajout de meilleures façons de gérer l'état et les dialogues séquentiels par rapport à la v3. Microsoft a fait un excellent travail en créant un cadre extensible pour la création, le test et le déploiement de votre chatbot, ainsi que pour fournir les bons crochets pour l'intégration avec d'autres fournisseurs. L'un des principaux avantages du Bot Framework de Microsoft est qu'il héberge son bot via une API REST, qui vous permet d'héberger votre bot dans une application ou un site Web.

Configuration de votre environnement

Avant de nous lancer dans la conception du chatbot ou en codant quoi que ce soit, nous devons mettre en place notre environnement de développement. Visual Studio n'est pas fourni avec le Bot Framework installé ou en option lors de l'installation, vous devrez donc l'installer via le menu Extensions. Une fois Visual Studio installé, vous devrez télécharger l'extension Bot Framework V4 Templates pour Visual Studio à partir du menu Extensions -> Manage Extensions .

Après avoir obtenu le Bot Framework Extension téléchargé, vous pourrez créer des projets Bot à partir du menu Nouveau projet. Une fois que vous avez créé votre nouveau projet Bot, vous souhaiterez ajouter le package Microsoft.Bot.Builder.Dialogs via NuGet. Cela vous permettra de créer des boîtes de dialogue réutilisables pour votre chatbot.

À ce stade, vous serez en mesure de créer des projets Bot dans Visual Studio. Passons à la conception de notre chatbot.

Étapes de configuration de l'environnement

  • Étape 1: Téléchargez Extension Bot Framework V4 pour Visual Studio dans Visual Studio
  • Étape 2: Créez un projet de bot
  • Étape 3: Ajouter Microsoft.Bot.Builder.Dialogs de NuGet

Conception de l'interface pour l'utilisateur

L'une des étapes les plus importantes lors de la création d'un chatbot est la conception du flux de conversation . Le flux de conversation et les questions détermineront la structure du code, les invites et la validation rapide. Un chatbot mal conçu peut être repensé, mais le code sera certainement plus difficile à refactoriser et il peut se transformer en une réécriture complète.

Pour notre chatbot, nous allons commencer avec un chatbot séquentiel qui guide un utilisateur à travers la pizza- processus de commande avec une certaine validation. Une fois que nous avons notre chatbot de base en place, nous pouvons commencer à remplacer des étapes ou des dialogues entiers par LUIS (Language Understanding) pour un meilleur flux de conversation. Sur la base de la dernière fois que j'ai appelé une pizza, voici les étapes de base:

Étape 1 – Utilisateur de bienvenue [Message]
Étape 2 – Invite pour la livraison ou pour emporter [Choice Prompt]
Étape 3 – Demande de type de pizza [Choice Prompt]
Étape 4 – Demande de taille de pizza [Choice Prompt]
Étape 5 – Demande de nombre de pizzas [Number Prompt with validation]
Étape 6 – Confirmation de la commande (Passez à l'étape 7) ou Modifier l'ordre (Passez à l'étape 2) [Confirm Prompt]
Étape 7 – Passer la commande [Message]

Invites

Le Bot Framework nous donne un certain nombre d'invites que nous pouvons utiliser immédiatement sans trop de installer. Nous allons seulement passer en revue les quelques éléments dont nous avons besoin pour notre chatbot – Invite de choix, Invite de numéro et Invite de confirmation. Consultez la documentation de Microsoft pour obtenir la liste complète des invites .

Pour une invite de choix, nous pouvons restreindre l'utilisateur à un ensemble connu de bonnes réponses. Dans un environnement Web, où le client peut présenter à l'utilisateur les options, l'utilisateur aura le choix des boutons à sélectionner. Dans un client de chat, leurs options leur seront simplement envoyées par SMS.

L'invite de numéro analysera l'entrée de l'utilisateur en un nombre. Nous pouvons vérifier la validité du numéro ou vérifier que le numéro se trouve dans une plage spécifique avant de continuer. Cela empêche l'utilisateur de commander -100 pizzas.

Enfin, l'invite de confirmation nous permet d'inviter l'utilisateur avec une question oui / non, le résultat étant converti en booléen.

Il existe peu d'autres types d'invite, mais ce sont les principales invites sur lesquelles nous allons nous concentrer pour notre robot.

Flux séquentiel

Nous avons conçu le flux initial de la conversation que nous voulons avoir avec nos utilisateurs lorsqu'ils interagissent avec notre robot de pizza avec le type d'informations que nous attendons d'eux. Il est temps pour nous de commencer à traduire une partie de ceci en code psuedo.

Structurellement, nous allons concevoir ce chatbot avec deux niveaux. Le premier niveau sera chargé de démarrer la cascade de commande de pizza et de passer la commande une fois que l'utilisateur a terminé. La raison derrière les deux niveaux est que le modèle Waterfall dans le framework permet un flux séquentiel, nous voulons donc recommencer la cascade Order Pizza si l'utilisateur veut apporter une modification à sa pizza.

Top Waterfall

  • Welcome [19659012] Commander Pizza Waterfall
  • Passer la commande

Commander Pizza Waterfall

  • Livraison ou à emporter
  • Type de pizza
  • Taille de la pizza
  • Nombre de pizzas
  • Confirmation

Codage

Maintenant que nous avons défini notre flux de conversation, les types d'invite et la structure de la conversation, il est temps de commencer à écrire du code. Tout d'abord, nous allons commencer par notre code de dialogue. Nous allons construire les invites, puis nous ajouterons le stockage et les hooks d'API pour compléter le chatbot

Bot Flow

Puisque nous avons conçu le flux de conversation que nous voulons que nos utilisateurs passent, nous pouvons commencer par le PizzaDialog. Si vous remarquez, la classe PizzaDialog hérite de ComponentDialog. Si vous étiez curieux et que vous aviez cliqué sur la liste complète des PromptTypes plus tôt, vous auriez vu ComponentDialog répertorié comme faisant partie de la hiérarchie de classes pour les invites. La brève description est que ComponentDialog est une invite plus complexe qui peut être réutilisée. Pour une explication plus détaillée, consultez ce lien .

 public   class   PizzaDialog  :  ComponentDialog
 {
     private   readonly  IStatePropertyAccessor  < UserData >  _userDataAccessor ; 
     private   readonly ISAccessor  private   readonly ISAccessorate  ] < ConversationData >  _conversationDataAccessor ; 

     private   static   string  TOP_LEVEL_WATERFALL_NAME  = [1965905890"INITIAL"; ;  ] private   static  String NUM_PIZZA_DIALOG_PROMPT_NAME  =   "NUM_PIZZA_PROMPT" ; 

     public   PizzaDialog  ( UserState userState [19459334] ConversationState  UserState userState [19459334] conversationState ) 
        :   base  ( nameof  ( PizzaDialog ) ) 
     {
        _userDataAccessor  =  userState .  CreateProperty  < UserData >   ( "UserData" ) ; 
        _conversationDataAccessor  =  conversationState .  CreateProperty  < ConversationData >   ( "ConversationData" ) ; 

         var  topLevelWaterfallSteps  =   new   WaterfallStep  [] 
         {
            StartAsync
        } ; 

        
         var  waterfallSteps  =   new   WaterfallStep  [] 
         {
            TakeoutOrDeliveryStepAsync 
            PizzaTypeStepAsync 
            PizzaSizeStepAsync 
            NumberOfPizzasStepAsync 
            ConfirmOrderStepAsync 
            PlaceOrderStepAsync
        } ; 

        
         AddDialog  ( new   WaterfallDialog  ( TOP_LEVEL_WATERFALL_NAME  waterfallSteps ) ) ) ]; 
         AddDialog  ( new   WaterfallDialog  ( nameof  ( WaterfallDialog )  waterfallSteps )) ) ; 
         AddDialog  ( new   TextPrompt  ( nameof  ( TextPrompt ) ) [19659059]) ; 
         AddDialog  ( new   NumberPrompt  < int >  ( NUM_PIZZA_DIALOG_PROMPT_NAME [19459004alididator] ) ) ; 
         AddDialog  ( new   ChoicePrompt  ( nameof  ( ChoicePrompt ) [19659059]) ) ; 
         AddDialog  (  nouveau   ConfirmPrompt  ( nom de  ( ConfirmPrompt ) ) ) ; 

        
        InitialDialogId  =  TOP_LEVEL_WATERFALL_NAME ; 
    } }  

Après avoir créé notre conversation dans PizzaDialog, nous devons la connecter à notre Bot qui gérera les événements lorsque les messages vont et viennent de notre bot.

J'ai divisé notre Bot en deux classes distinctes. L'un d'eux est un runner de base pour nous permettre de créer d'autres dialogues, et l'autre est spécifiquement pour gérer l'aspect Commande de pizza de notre chatbot. En le décomposant, nous pouvons facilement créer des robots supplémentaires pour gérer des conversations distinctes qui ne sont pas liées à Order Pizza sans construire le même passe-partout.

BasePizzaBot.cs

 namespace  PizzaBot .  Bots
 {





 public   class   BasePizzaBot  < T >  :  ActivityHandler  T :  Dialogue
 {
     protected   readonly  Dialog Dialog ; 
     protected   readonly  BotState ConversationState ; 
     protected   readonly  BotState UserState ; 
     protected   readonly  ILogger Logger ; 

     public   BasePizzaBot  ( ConversationState conversationState  UserState userState  ] T dialogue  ILogger  < BasePizzaBot  < T > >  logger ) 
     {
        ConversationState  =  conversationState ; 
        UserState  =  userState ; 
        Dialog  =  dialogue ; 
        Logger  =  logger ; 
    } 

    
     public   override   async  Task  OnTurnAsync  ( ITurnContext turnContext  AnnulationToken CancellationToken  =   default  ( CancellationToken ) ) 
     {
         wait   base .  OnTurnAsync [19659059] ( turnContext  cancelToken ) ; 

        
         await  ConversationState .  SaveChangesAsync  ( turnContext  turnContext  turnContext  turnContext] ,   false  cancelToken ) ; 
         wait  UserState .  SaveChangesAsync  ( turnContext [19659048] false  cancelToken ) ; 
    } 

     protected   override   async  Task  OnMessageActivityAsync  ( ITurnContext  < IMessageActivity >  turnContext  CancellationToken cancelToken ) 
     {
        Logger .  LogInformation  ( "Running dialog with Message Activity." ) ; 

        
         wait  Dialog .  Run  ] ( turnContext  ConversationState .  CreateProperty  < DialogState >   ( nameof  ( DialogState ) )  cancelToken ) ; 
    } 
} 
} 

PizzaBot.cs

 namespace  PizzaBot .  Bots
 {
     public   class   PizzaBot  < T >  :  BasePizzaBot  < T > [19659048] où  T :  Dialogue
     {
         public   PizzaBot  ( ConversationState conversationState  UserState userState  T dialog  ILogger  < BasePizzaBot  < T > >  logger )  
            :   base  ( conversationState  userState  dialog  logger ) 
         {
        } 

         protected   override   async  Task  OnMembersAddedAsync  (
            IList  < ChannelAccount >  membersAjouté 
            ITurnContext  < IConversationUpdateActivity >  turnContext 
            AnnulationToken AnnulationToken ) 
         {
             foreach   ( var  member  in  membersAdded ) 
             {
                
                
                 if   (  membre .  Id ! =  turnContext .  Activity .  Recipient .  Id ) [19659257] {
                     var  reply  =  MessageFactory .  Text  ( $  "Bonjour {member.Name} et Bienvenue dans Pizza Bot . "  + 
                        " Tapez n'importe quoi pour commencer. ") ; 
                     wait  turnContext .  SendActivityAsync  ( reply  AnnulationToken ) ; 
                } 
            } 
        } 
    } 
} 

Bot State Storage

Maintenant que nous avons notre conversation écrit, nous devons ajouter d'une manière ou d'une autre pour stocker les données. Si vous regardez le code que nous avons écrit pour le BasePizzaBot.cs vous verrez deux lignes liées à BotState:

     protected   readonly  BotState ConversationState ; [19659051] protected   readonly  BotState UserState ; 

Avec ces deux lignes, nous stockons l'état de l'utilisateur et l'état de la conversation, le moment est donc venu d'expliquer ces concepts. Il existe deux types de stockage en ce qui concerne votre chatbot, l'état de la conversation et l'état de l'utilisateur. L'état de conversation dure toute la vie de la conversation en cours. Il est idéal pour conserver la mémoire à court terme et se souvenir de ce que dit votre utilisateur avec la possibilité d'oublier facilement si rien ne se passe pour le convertir en stockage à long terme. L'état de l'utilisateur correspond à des informations à long terme sur l'utilisateur, telles que son nom d'utilisateur, sa date d'inscription et toute autre information spécifique au domaine que vous souhaitez conserver plus longtemps que la conversation. L'état de conversation est stocké dans la mémoire, tandis que l'état utilisateur est généralement stocké dans une base de données.

Pour notre bot, nous utilisons la mémoire locale pour notre état utilisateur. Vous pouvez facilement échanger cela via l'interface IStorage pour une base de données ou un magasin de données plus long.

Startup.cs

…
    
    
    services .  AddSingleton  < IStorage  MemoryStorage >   () ; 

    
    
    services .  AddSingleton  < UserState >   () ; 

    
    
    services .  AddSingleton  < ConversationState >   () ; 

. . . 

. ] Test de votre chatbot

À ce stade, nous avons un chatbot entièrement fonctionnel, mais nous ne l'avons pas encore testé. Heureusement, le Bot Framework est livré avec un émulateur qui se connecte bien à notre chatbot lorsqu'il est exécuté localement pour nous permettre de tester notre bot. Vous pouvez télécharger l’émulateur sur la page Github de Microsoft .

Une fois que vous avez téléchargé le binaire approprié pour votre système d’exploitation, vous devriez pouvoir exécuter l’émulateur. Une fois l'émulateur opérationnel, vous pouvez accéder à Visual Studio et appuyer sur Exécuter (démarrer avec le débogage). Votre navigateur par défaut devrait apparaître avec un lien vers l'API de votre chatbot. L'URL et le port par défaut du PizzaBot ressemblent à ceci: http: // localhost: 3978 / api / messages . Vous pouvez créer une nouvelle configuration de bot à l'aide de l'URL et interagir avec votre bot.

Bien que l'émulateur ne soit qu'un environnement unique et ne représente aucun autre client ou application de chat, il vous montre comment le bot traite les informations de la perspective du client, idéale pour les itérations rapides.

Étapes suivantes

Nous avons construit notre chatbot, mais il y a quelques améliorations pour faire passer ce chatbot au niveau supérieur. Pour commencer, nous avons construit notre chatbot avec un flux séquentiel de commande. Nous pouvons étendre cela en utilisant permettre à l'utilisateur de former librement sa commande et d'analyser le texte et de ne poser des questions de suivi que pour les données manquantes. Nous pouvons y parvenir en utilisant le service LUIS (Language Understanding) d'Azure. De plus, nous pouvons construire sur des robots supplémentaires qui peuvent permettre à l'utilisateur de poser des questions sur l'état de sa commande sans réécrire le bot de commande actuel.

Bien que la commande d'une pizza soit une utilisation très spécifique et ciblée d'un chatbot, j'espère que vous pouvez voir comment Il est facile de créer et de tester un chatbot pour aider votre entreprise dans sa marche vers l'automatisation. Que vous fassiez partie de l'équipe de développement essayant de créer un bot FAQ pour votre application ou de l'équipe marketing essayant de qualifier les prospects, les chatbots viennent vous aider et ils sont faciles à utiliser. Happy Coding!

Pour le code source complet, consultez le repo .





Source link