Fermer

juillet 28, 2020

Création d'un CRM avec Xamarin.Forms et Azure, partie 3


Dans la troisième partie de cette série de blogs, nous expliquerons comment entraîner un modèle LUIS AI personnalisé pour avoir des conversations de chat naturelles à l'aide de l'interface utilisateur Telerik pour le contrôle de l'interface utilisateur conversationnelle de Xamarin.

Vous pouvez trouver Première partie de notre series ici où nous avons construit le backend. Dans La deuxième partie de la série nous avons créé l'interface utilisateur avec Telerik UI pour Xamarin.

Dans ce dernier épisode de cette série de blogs, nous verrons comment créer une interface utilisateur conversationnelle à l'aide de RadChat et d'une modèle de compréhension du langage naturel Azure formé (aka LUIS). Ces articles peuvent être lus indépendamment, mais si vous voulez rattraper le retard, lisez la première et la deuxième partie.

Alimenter la conversation

L'interface utilisateur Telerik pour Xamarin Le contrôle RadChat est intentionnellement conçu pour être indépendant de la plate-forme. Bien que j'utilise Azure pour ce projet, vous pouvez utiliser tout ce que vous voulez ou avez actuellement.

Je voulais être sûr que l'application disposait d'un service dynamique et intelligent communiquant avec l'utilisateur, c'est là qu'Azure entre en scène encore. Nous pouvons former un modèle LUIS pour identifier certains contextes pour comprendre ce que l'utilisateur demande. Par exemple, demandent-ils les détails du produit ou les informations de livraison?

Pour commencer, suivez le Démarrage rapide: créez une nouvelle application dans le didacticiel du portail LUIS . Il est rapide et facile de lancer un projet et de commencer à entraîner le modèle avec vos intentions personnalisées.

À ce stade, vous voudrez peut-être réfléchir si vous souhaitez utiliser Intents Entities ou les deux. La page d'assistance ArtGallery CRM est mieux servie avec l'utilisation d'intentions. Pour vous aider à choisir la bonne approche pour votre application, Microsoft propose un joli tableau de comparaison – Entity par rapport à Intent .

Intentions

Dans la page de discussion de l'application CRM, l'utilisateur interagit avec un bot d'assistance. Ainsi, nous devons principalement déterminer si l'utilisateur demande des informations sur un produit, un employé, une commande ou un client. Pour ce faire, j'ai décidé d'utiliser les intentions suivantes:

 LUIS Intents "title =" LUIS Intents "data-openoriginalimageonclick =" true "/> </a> </p>
<p>
 Pour entraîner le modèle à détecter un intent, vous lui donnez un aperçu des choses que l'utilisateur pourrait dire. C'est ce qu'on appelle un <a href= énoncé . Jetons un coup d'œil aux énoncés pour l'intention Product .

 Product utterances "title = "Product utterances" data-openoriginalimageonclick = "true" /> </a> </p>
<p>
 Sur le côté gauche, vous pouvez voir les exemples d'énoncés que j'ai entrés. Il n'est pas nécessaire que ce soit des phrases complètes, mais simplement quelque chose que vous vous attendez à voir dans la question de l'utilisateur. Sur le côté droit, vous voyez le score de détection actuel de l'énoncé après le dernier entraînement.
</p>
<h3> Formation </h3>
<p>
 Une fois que vous avez terminé de saisir toutes les intentions et tous les énoncés pour ces intentions, il est temps de former le modèle. vous pouvez le faire en cliquant sur le bouton "Train" dans la barre de menu en haut du portail: </p>
<p><a href= Train button "title =" Train button "data-openoriginalimageonclick =" true "/> </a> </p>
<h3> Test </h3>
<p>
 Une fois LUIS entraîné avec l'ensemble actuel d'intentions et d'énoncés, il est temps de voir ses performances. Sélectionnez le bouton <strong> Test </strong>: </p>
<p><a href= Test button "title =" Test button "data- openoriginalimageonclick = "true" /> </a> </p>
<p>
 Vous verrez un fly-out, entrez votre question de test pour voir un résultat: </p>
<p><a href= Test result "title =" Test result "data-openoriginalimageonclick =" true " /> </a> </p>
<p>
 Dans le test ci-dessus, j'essaie de rechercher "<em> où est l'œuvre d'art? </em>" et le résultat était une correspondance de 73% pour une intention <strong> Produit </strong>. Si vous souhaitez améliorer le score, ajoutez plus d'énoncés pour l'intention et réentraînez-le. </p>
<h3> Publication </h3>
<p>
 Lorsque vous êtes satisfait des scores obtenus pour les intentions, il est temps de publier le modèle. Utilisez le [1 9459022] Bouton Publier </strong>: </p>
<p><a href= Bouton Publier "title =" Bouton Publier "data-openoriginalimageonclick =" true "/> </a> </p>
<p>
 Cela ouvrira une boîte de dialogue avec les paramètres de la fente de libération pour appliquer les modifications à. Vous pouvez mettre en scène les nouvelles modifications ou les pousser en production: </p>
<p><a href= Publier l'emplacement de destination "title =" Publier l'emplacement de destination "data-openoriginalimageonclick =" true "/> </a> </p>
<h3> API Endpoints </h3>
<p>
 Lorsque la publication est terminé, vous verrez un bouton dans la notification pour accéder à l'onglet Gérer où vous pouvez voir les URL REST de votre version: </p>
<p><a href= Voir API Endpoints button "title =" Voir le bouton API Endpoints "data-openoriginalimageonclick =" true "/> </a> </p>
<p>
 Une fois que vous accédez à l'onglet Gérer, le volet Ressources Azure sera présélectionné. Dans le volet, vous verrez les points de terminaison de l'API et d'autres informations importantes. </p>
<p><a href= Onglet Ressources Azure "title =" Onglet Ressources Azure "data-openoriginalimageonclick =" true "/> </a></p>
<blockquote>
<p> Nous reviendrons ici pour ces valeurs plus tard ou vous pouvez les stocker temporairement dans un emplacement sécurisé. Ne pas partager votre clé primaire ou exemple de requête (elle a la clé primaire dans les paramètres de requête). </p>
</blockquote>
<p>
Nous avons maintenant terminé avec le portail LUIS, et il est temps de passer à la création de l'application de bot ASP.NET qui effectuera la communication réelle entre l'utilisateur et LUIS. </p>
<h2> Azure Bot Service </h2>
<p>Suivez <a href= le didacticiel de démarrage rapide d'Azure Bot pour savoir comment créer un nouveau service de bot dans votre portail Azure. Lorsque vous suivez les étapes de configuration, veillez à choisir le modèle de bot C # afin que le back-end du bot soit une application ASP.NET:

 CSharp template "title =" CSharp template "data-openoriginalimageonclick =" true "/> </a></p>
<h3> Première utilisation – Test avec WebChat </h3>
<p>
 Pour vous assurer que tout fonctionne après avoir publié le projet sur Azure, ouvrez la lame du bot et vous verrez une option "Tester dans le chat Web": </p>
<p><a href= Test dans le chat Web button "title =" Tester dans le bouton Web Chat "data-openoriginalimageonclick =" true "/> </a></p>
<p> Cela va s'ouvrir une lame et initialisez le bot. Lorsqu'il est prêt, vous pouvez tester la communication. Le modèle de bot par défaut utilise une boîte de dialogue «écho» (nous aborderons ce sujet plus loin dans l'article). </p>
<p>
 Testez ceci en envoyant n'importe quel message, vous devriez voir votre message, précédé d'un nombre de comptage. Ensuite, essayez d'envoyer le mot «réinitialiser». Une boîte de dialogue s'affiche pour réinitialiser le nombre de messages. </p>
<p><h3> Explorez le code </h3>
</p>
<p>
 Une fois que vous avez confirmé que le robot répond et fonctionne, examinons le code en téléchargeant une copie de l'application ASP.NET: </p>
<p><a href= Téléchargez le modèle de projet "title =" Téléchargez le modèle de projet "data-openoriginalimageonclick =" true "/> </a></p>
<ol>
<li> Ouvrez le panneau de construction </li>
<li> Cliquez sur le lien" Télécharger le fichier zip "(cela générera le zip) </li>
<li> Cliquez sur le bouton" Télécharger le fichier zip "(cela téléchargera le zip) </li>
</ol>
<p> À à ce stade, vous aurez un fichier zip nommé quelque chose comme «YourBot-src». Vous pouvez maintenant décompresser et ouvrir le <em> Microsoft.Bot.Sample.SimpleEchoBot.sln </em> dans Visual Studio. Effectuez une reconstruction pour restaurer les packages NuGet. </p>
<p> Commençons par examiner le flux de travail en ouvrant le <strong> MessagesController .cs </strong> dans le dossier <strong> Controllers </strong> et regardez la méthode `Post`. La méthode a un paramètre Activity, qui est envoyé au contrôleur par l'application cliente. Nous pouvons vérifier quel type d'activité </p>
<pre><code class=

Dans le cas de notre bot d'écho, il s'agit de ActivityType.Message auquel cas la logique détermine que nous répondons avec une instance de EchoDialog .

Maintenant, regardons la classe EchoDialog . Ceci se trouve dans le dossier Dialogs :

 EchoDialog Class "title =" EchoDialog Class "data-openoriginalimageonclick =" true "/> </a></p>
<p> Il existe quelques méthodes dans le class, mais nous ne sommes actuellement concernés que par la méthode <strong> MessageReceivedAsync </strong>: </p>
<pre><code class=

C'est la logique que le bot utilisait lorsque vous discutiez simplement dans le chat Web! Ici, vous pouvez voir comment tous les messages que vous avez envoyés ont été répercutés et pourquoi il a été précédé d'un nombre de messages.

Service de discussion Xamarin.Forms

Maintenant qu'un simple bot d'écho est en cours d'exécution, il est temps de configurer le côté client. Pour ce faire, nous aurons besoin de quelques éléments:

Faisons d'abord la classe de service, puis passons ensuite au XAML.

Bot Service Class et l'API DirectLine

En plus du contrôle WebChat qui est intégrable, le Bot Service vous permet d'interagir directement avec lui en utilisant des requêtes réseau via DirectLine API .

Bien que vous puissiez créer et envoyer manuellement des requêtes HTTP, Microsoft a fourni un SDK client .NET qui rend très simple et indolore la connexion et l'interaction avec le service Bot via le Microsoft.Bot.Connector.DirectLine NuGet package .

Avec cela, nous pourrions techniquement simplement l'utiliser directement dans le modèle de vue (ou code derrière) de la page Xamarin.Forms, mais je voulais avoir une certaine séparation des préoccupations. Nous allons donc créer une classe de service qui n'est pas étroitement liée à cette page spécifique.
Voici la classe de service:

utilisant System;

using System.Linq;

using System.Threading.Tasks;

using ArtGalleryCRM.Forms.Common;

using Microsoft.Bot.Connector. DirectLine;

using Xamarin.Forms;

namespace ArtGalleryCRM.Forms .Services

{

public class ArtGallerySupportBotService

[194550] {

private readonly string _user;

privé Action _onReceiveMessage;

private readonly DirectLineClient _client;

[1945908]

[1945908] ] private Conversation _conversation;

private string _watermark;

public ArtGallerySupportBotService ( string userDisplayName) [1965944390]

[194550] {

// Créer un DirectLineClient avec votre App Secret

[19659187] this ._ client = new DirectLineClient (ServiceConstants.DirectLineSecret);

this ._ user = userDisplayName;

}

[19659177]

internal void AttachOnReceiveMessage (Action onMessageReceived)

[1945519050]

[1945519050]

[1945519050] {

this ._ onReceiveMessage = onMessageReceived;

}

public async Task StartConversationAsync ()
{

this ._ conversation = wait _client.Conversations.StartConversationAsync ();

}

// Envoie le message au bot

public async void SendMessage ( string text)

{

var userMessage = new Activity

{

From = new ChannelAccount ( this ._user),

Text = text,

Type = ActivityTypes.Message [19659443]

};

wait this ._ client.Conversations.PostActivityAsync ( this ._ conversation.ConversationId, userMessage);

attend this .ReadBotMessagesAsync ();

}

// Affiche le message entrant à l'utilisateur

private async Task ReadBotMessagesAsync ()

{

var activitySet = wait this [19659053] ._ client.Conversations.GetActivitiesAsync ( this ._ conversation.ConversationId, _watermark);

[19659187] if (activitySet! = null )

{

this ._ watermark = activitySet.Watermark;

var activities = activitySet.Activities.Where (x => x.From.Id == ServiceConstants.BotId);

Device.BeginInvokeOnMainThread (() = >

{

foreach (Activité d'activité dans activités)

{

this ._onReceiveMessage? .Invoke (activité);

}

}); [19659443]

}

}

}

}

Il n'y a vraiment que deux responsabilités, envoyer des messages au bot et afficher les messages du bot entrants à l'utilisateur. Dans le constructeur de classe, nous instancions un objet DirectLineClient. Notez qu'il a besoin d'un paramètre App ID vous pouvez le trouver dans la page Paramètres du portail Azure pour l'application bot

Voici une capture d'écran pour vous guider. L'ID est le champ "Microsoft App ID":

 Emplacement de l'ID de l'application du service de bot "title =" Emplacement de l'ID de l'application du service de bot "data-openoriginalimageonclick =" true "/> </a></p>
<p> D'accord, il est temps de connecter l'interface utilisateur et connectez le contrôle RadChat à la classe de service.
</p>
<h3> Voir le modèle </h3>
<p>Pour tenir les messages de conversation, nous allons utiliser une <strong> ObservableCollection <TextMessage></strong>. Le contrôle RadChat prend en charge les scénarios MVVM. Pour en savoir plus, consultez la <a href= documentation RadChat MVVM Support .

public ObservableCollection ConversationItems { get ; réglé ; } = new ObservableCollection ();

L'instance de service peut être définie comme un champ privé qui est créé lorsque le modèle de vue est initialisé:

classe publique SupportViewModel: PageViewModelBase

{

private ArtGallerySupportBotService ArtGallerySupportServiceBotService 19659443]

public async Task InitializeAsync ()

{

this .botService = new ArtGallerySupportBotService ( "Lance" ); [19659443]

this .botService.AttachOnReceiveMessage ( this .OnMessageReceived); [1965509050] }

...

}

Quand un message vient de th e bot, le service appellera la méthode OnMessageReceived du modèle de vue et transmettra un paramètre d'activité. avec ces informations, vous pouvez ajouter un message à la collection ConversationItems:

private void OnMessageReceived (Activité d'activité)

{

ConversationItems.Add ( ] nouveau TextMessage

{

Author = this [19659053] .SupportBot, // l'auteur du message

Text = activity.Text // the message

});

}

Pour le message sortant de l'utilisateur, nous utiliserons les éléments de conversation Événement CollectionChanged . Si le message qui a été ajouté provient de l'utilisateur, nous pouvons le donner à la classe de service pour qu'il soit poussé vers le bot.

private void ConversationItems_CollectionChanged ( object expéditeur, NotifyCollectionChangedEventArgs e)

{

{

[19455090] if (e.Action == NotifyCollectionChangedAction.Add)

{

// Récupère le message qui vient d'être ajouté à la collection

var chatMessage = (TextMessage) e.NewItems [0];

// Vérifier l'auteur du message

if (chatMessage.Author == this .Me)

{

// Minuterie anti-rebond

Device.StartTimer (TimeSpan.FromMilliseconds (500), () => [19659050] {

Device.BeginInvokeOnMainThread (() =>

{

// Envoyez la question de l'utilisateur au bot!

this .botService.SendMessage (chatMessage.Text);

});

return false ;

});

}

}

}

Le XAML

Dans la vue, tout ce que vous avez à faire est de lier la propriété ConversationItems à la propriété ItemsSource de RadChat. Lorsque l'utilisateur entre un message dans la zone de discussion, un nouveau TextMessage est créé par le contrôle et inséré automatiquement dans le ItemsSource (déclenchant CollectionChanged).

< conversationnelUi: RadChat ItemsSource = "{Binding ConversationItems}" Author = "{Binding Me}" />

Indicateurs de saisie

Vous pouvez montrer qui est en train de taper avec une ObservableCollection dans le modèle de vue. Celui qui se trouve dans cette collection sera affiché par le contrôle RadChat comme typage actuel.

< conversationalUi: RadChat ItemsSource = "{Binding ConversationItems}" Author = "{Binding Me}" > [19659443]

< conversationnelUi: RadChat.TypingIndicator >

< conversationUi: TypingIndicator ItemsSource = "{Binding TypingAuthors}" />

</ [19659052] conversationnelUi: RadChat.TypingIndicator >

</ conversationationalUi: RadChat >

Consultez le didacticiel Typing Indiciators pour plus d'informations. Vous pouvez également consulter cet article de la base de connaissances dans lequel j'explique comment avoir une expérience de salle de chat en temps réel avec les indicateurs.

Style de message

RadChat lui-même vous offre des fonctionnalités prêtes à l'emploi et est livré avec des styles à utiliser tels quels. Cependant, vous pouvez également personnaliser les éléments pour répondre à vos directives de marque ou créer de superbes effets tels que des messages consécutifs groupés. Pour plus d'informations, consultez le didacticiel ItemTemplateSelector .

Connexion du bot à LUIS

Vous pouvez exécuter l'application à ce stade et confirmer que le bot fait écho à vos messages. Cependant, il est maintenant temps de connecter la logique du serveur de bot à LUIS afin que vous puissiez renvoyer des messages significatifs à l'utilisateur!

Pour ce faire, nous devons retourner au projet de bot et ouvrir la classe EchoDialog. Vous pouvez renommer cette classe pour mieux correspondre à ce qu'elle fait, par exemple, la boîte de dialogue de la démo CRM s'appelle "SupportDialog".

 support dialog class "title =" support dialog class "data-openoriginalimageonclick =" true "/> </a> </p>
<p>
 En revenant à la tâche MessageReceived, nous avons accès à ce que l'utilisateur Xamarin.Forms a tapé dans le contrôle RadChat! Donc, la prochaine chose logique à faire est de l'envoyer à LUIS pour analyse et de déterminer comment nous allons répondre à l'utilisateur. </p>
<p>
 Microsoft a de nouveau simplifié l'utilisation des services Azure en fournissant le SDK .NET pour LUIS. Installez le <strong> Microsoft.Azure.CognitiveServices.Language.LUIS.Runtime </strong> Package NuGet vers le projet bot: </p>
<p> <a href=  Package LUIS "title =" LUIS package "data-openoriginalimageonclick =" true "/> </a> </p>
<p>
 Une fois installé, vous pouvez revenir à la boîte de dialogue classe et remplacez la logique d'écho par un LUISRuntimeClient qui envoie le message de l'utilisateur à LUIS. Les intentions détectées seront renvoyées à votre bot et vous pourrez alors faire le bon choix pour la manière de répondre. </p>
<p>
 Voici un exemple qui ne prend que l'intention de score la plus élevée et remercie l'utilisateur: </p>
<pre><code class=

The Primary KeyEndpoint and LUIS App ID values are found in the luis.ai portal. (different than the Microsoft App ID for the bot project). Learn more here Quickstart: SDK Query Prediction Endpoint.

The code above uses a very simple check for a "Product" intent and just replies with a statement. If there was no match, there's no reply. The takeaway here is though you are in control over what gets sent back to the user, with LUIS helping you make intelligent decisions, you can provide for the user's needs better than ever.

Conclusion

I hope, though the course of this series, I was able to help show you that with the power of Telerik UI for Xamarin doing the heavy lifting in the UI category, and Azure powering intelligent backend services, you can build a enterprise ready, scalable, application with Xamarin Forms.

The Art Gallery CRM demo has a much more robust solution in place that has many intents and detects user sentiment. For example, if the user is mad or happy, the bot will comment on it in addition to answering their question!

More Resources

Missed part of the series? You can find Part One herewhere we built the backend. In Part Twowe built the UI with Telerik UI for Xamarin.

Complete Source Code

Now that you're familiar with the structure of the application, I highly recommend taking a look through the ArtGallery CRM source code on GitHub as you will recognize all the parts we discussed in this series. 

Install the App

You can also install app for yourself, available in the:

Further Support

If you have any trouble with the Telerik UI for Xamarin controls, you can open a Support Ticket and get help from the Xamarin team directly (you get complete support with your trial). You can also search and post the UI for Xamarin Forums to discuss with the rest of the community.

If you have any questions about this series, leave a comment below or reach out to me on Twitter @lancewmccarthy.







Source link