Appelez LUIS depuis FormFlow en C #

J’utilise le framework de bot Microsoft pour créer un bot permettant d’interroger l’utilisateur, puis de comprendre la réponse. L’utilisateur est interrogé à l’aide de l’API FormFlow dans la structure de bot et les réponses sont récupérées. Voici le code pour le formflow:

public enum Genders { none, Male, Female, Other}; [Serializable] public class RegisterPatientForm { [Prompt("What is the patient`s name?")] public ssortingng person_name; [Prompt("What is the patients gender? {||}")] public Genders gender; [Prompt("What is the patients phone number?")] [Pattern(@"(\d)?\s*\d{3}(-|\s*)\d{4}")] public ssortingng phone_number; [Prompt("What is the patients Date of birth?")] public DateTime DOB; [Prompt("What is the patients CNIC number?")] public ssortingng cnic; public static IForm BuildForm() { OnCompletionAsyncDelegate processHotelsSearch = async (context, state) => { await context.PostAsync($"Patient {state.person_name} registered"); }; return new FormBuilder() .Field(nameof(person_name), validate: async (state, value) => { //code here for calling luis }) .Field(nameof(gender)) .Field(nameof(phone_number)) .Field(nameof(DOB)) .Field(nameof(cnic)) .OnCompletion(processHotelsSearch) .Build(); } } 

L’utilisateur peut entrer lorsqu’il est demandé son nom:

je m’appelle James Bond

De plus, le nom pourrait être de longueur variable. Je ferais mieux d’appeler Luis d’ici et d’obtenir l’entité (nom) pour l’intention. Je ne sais pas pour l’instant comment appeler un dialog depuis le stream de travail.

Vous pouvez utiliser la méthode API de LUIS au lieu de la méthode de dialog.

Votre code serait – RegisterPatientForm Class:

 public enum Genders { none, Male, Female, Other }; [Serializable] public class RegisterPatientForm { [Prompt("What is the patient`s name?")] public ssortingng person_name; [Prompt("What is the patients gender? {||}")] public Genders gender; [Prompt("What is the patients phone number?")] [Pattern(@"(\d)?\s*\d{3}(-|\s*)\d{4}")] public ssortingng phone_number; [Prompt("What is the patients Date of birth?")] public DateTime DOB; [Prompt("What is the patients CNIC number?")] public ssortingng cnic; public static IForm BuildForm() { OnCompletionAsyncDelegate processHotelsSearch = async (context, state) => { await context.PostAsync($"Patient {state.person_name} registered"); }; return new FormBuilder() .Field(nameof(person_name), validate: async (state, response) => { var result = new ValidateResult { IsValid = true, Value = response }; //Query LUIS and get the response LUISOutput LuisOutput = await GetIntentAndEntitiesFromLUIS((ssortingng)response); //Now you have the intents and entities in LuisOutput object //See if your entity is present in the intent and then resortingeve the value if (Array.Find(LuisOutput.intents, intent => intent.Intent == "GetName") != null) { LUISEntity LuisEntity = Array.Find(LuisOutput.entities, element => element.Type == "name"); if (LuisEntity != null) { //Store the found response in resut result.Value = LuisEntity.Entity; } else { //Name not found in the response result.IsValid = false; } } else { //Intent not found result.IsValid = false; } return result; }) .Field(nameof(gender)) .Field(nameof(phone_number)) .Field(nameof(DOB)) .Field(nameof(cnic)) .OnCompletion(processHotelsSearch) .Build(); } public static async Task GetIntentAndEntitiesFromLUIS(ssortingng Query) { Query = Uri.EscapeDataSsortingng(Query); LUISOutput luisData = new LUISOutput(); try { using (HttpClient client = new HttpClient()) { ssortingng RequestURI = WebConfigurationManager.AppSettings["LuisModelEndpoint"] + Query; HttpResponseMessage msg = await client.GetAsync(RequestURI); if (msg.IsSuccessStatusCode) { var JsonDataResponse = await msg.Content.ReadAsSsortingngAsync(); luisData = JsonConvert.DeserializeObject(JsonDataResponse); } } } catch (Exception ex) { } return luisData; } } 

Ici, la méthode GetIntentAndEntitiesFromLUIS effectue la requête à LUIS à l’aide du sharepoint terminaison exposé par votre application Luis. Ajoutez le sharepoint terminaison à votre LuisModelEndpoint avec la clé LuisModelEndpoint

Trouvez votre point final luis en cliquant sur l’onglet Publier de votre application luis.

Votre web.config ressemblerait à ceci

        

J’ai créé une classe LUISOutput pour désérialiser la réponse:

 public class LUISOutput { public ssortingng query { get; set; } public LUISIntent[] intents { get; set; } public LUISEntity[] entities { get; set; } } public class LUISEntity { public ssortingng Entity { get; set; } public ssortingng Type { get; set; } public ssortingng StartIndex { get; set; } public ssortingng EndIndex { get; set; } public float Score { get; set; } } public class LUISIntent { public ssortingng Intent { get; set; } public float Score { get; set; } } 

Réponse de l’émulateur entrez la description de l'image ici

Dans cette situation, il peut être préférable d’appeler une intention intentionnelle en dehors du stream de données. La fonctionnalité que vous recherchez n’existe pas exactement. Vous pouvez appeler une intention “Nom” puis vous appeler comme suit:

 [LuisIntent("Name")] public async Task Name(IDialogContext context, LuisResult result) { //save result in variable var name = result.query //call your form var pizzaForm = new FormDialog(new PizzaOrder(), this.MakePizzaForm, FormOptions.PromptInStart, entities); context.Call(pizzaForm, PizzaFormComplete); context.Wait(this.MessageReceived); }