2017-12-28 12 views
2

私はMicrosoftボットフレームワークを使用して、ユーザーに質問して回答を理解するためのボットを作成しています。ボットフレームワークでFormFlow APIを使用して質問され、回答が取得されます。ここでformflowのコードは次のとおりです。C#のFormFlowからLUISを呼び出してください

public enum Genders { none, Male, Female, Other}; 

[Serializable] 
public class RegisterPatientForm 
{ 

    [Prompt("What is the patient`s name?")] 
    public string person_name; 

    [Prompt("What is the patients gender? {||}")] 
    public Genders gender; 

    [Prompt("What is the patients phone number?")] 
    [Pattern(@"(<Undefined control sequence>\d)?\s*\d{3}(-|\s*)\d{4}")] 
    public string phone_number; 

    [Prompt("What is the patients Date of birth?")] 
    public DateTime DOB; 

    [Prompt("What is the patients CNIC number?")] 
    public string cnic; 


    public static IForm<RegisterPatientForm> BuildForm() 
    { 
     OnCompletionAsyncDelegate<RegisterPatientForm> processHotelsSearch = async (context, state) => 
     { 
      await context.PostAsync($"Patient {state.person_name} registered"); 
     }; 

     return new FormBuilder<RegisterPatientForm>() 
      .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(); 
    } 

} 

名前を尋ねられたときに、ユーザが入力することがあります。

私の名前は名前が可変長のものであってもよい。また

ジェームズ・ボンド

です。私はここからルイスに電話し、その意図の実体(名前)を得る方が良いでしょう。私は現在、フォームフローからluisダイアログをどのように呼び出すことができるかを認識していません。

+0

'FormFlow'は本当に最善の解決策ではないかもしれませんか? –

+0

を行いたい場合

エミュレータレスポンス enter image description here

+0

たとえば、FormFlowを使用する代わりにダイアログを実装します。それはもっと長いですが、あなたは何でもしても構いません。 –

答えて

4

ダイアログメソッドではなく、LUISのAPIメソッドを使用することができます。

あなたのコードは次のようになります - RegisterPatientFormクラス:

public enum Genders { none, Male, Female, Other }; 

[Serializable] 
public class RegisterPatientForm 
{ 

    [Prompt("What is the patient`s name?")] 
    public string person_name; 

    [Prompt("What is the patients gender? {||}")] 
    public Genders gender; 

    [Prompt("What is the patients phone number?")] 
    [Pattern(@"(<Undefined control sequence>\d)?\s*\d{3}(-|\s*)\d{4}")] 
    public string phone_number; 

    [Prompt("What is the patients Date of birth?")] 
    public DateTime DOB; 

    [Prompt("What is the patients CNIC number?")] 
    public string cnic; 


    public static IForm<RegisterPatientForm> BuildForm() 
    { 
     OnCompletionAsyncDelegate<RegisterPatientForm> processHotelsSearch = async (context, state) => 
     { 
      await context.PostAsync($"Patient {state.person_name} registered"); 
     }; 

     return new FormBuilder<RegisterPatientForm>() 
      .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((string)response); 

       //Now you have the intents and entities in LuisOutput object 
       //See if your entity is present in the intent and then retrieve 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<LUISOutput> GetIntentAndEntitiesFromLUIS(string Query) 
    { 
     Query = Uri.EscapeDataString(Query); 
     LUISOutput luisData = new LUISOutput(); 
     try 
     { 
      using (HttpClient client = new HttpClient()) 
      { 
       string RequestURI = WebConfigurationManager.AppSettings["LuisModelEndpoint"] + Query; 
       HttpResponseMessage msg = await client.GetAsync(RequestURI); 
       if (msg.IsSuccessStatusCode) 
       { 
        var JsonDataResponse = await msg.Content.ReadAsStringAsync(); 
        luisData = JsonConvert.DeserializeObject<LUISOutput>(JsonDataResponse); 
       } 
      } 
     } 
     catch (Exception ex) 
     { 

     } 
     return luisData; 
    } 
} 

ここGetIntentAndEntitiesFromLUIS方法は、お使いのルイス・アプリによって公開されたエンドポイントを使用してLUISに照会を行います。この

<appSettings> 
    <!-- update these with your BotId, Microsoft App Id and your Microsoft App Password--> 
    <add key="BotId" value="YourBotId" /> 
    <add key="MicrosoftAppId" value="" /> 
    <add key="MicrosoftAppPassword" value="" /> 
    <add key="LuisModelEndpoint" value="https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/YOUR_MODEL_ID?subscription-key=YOUR_SUBSCRIPTION_KEY&amp;verbose=true&amp;timezoneOffset=0&amp;q="/> 
</appSettings> 
ようになり、あなたのルイスアプリで

あなたのweb.configファイルをタブを公開に行くことによって、あなたのルイス・エンドポイントを検索キーLuisModelEndpoint

であなたのWeb.configファイルにエンドポイントを追加します。

応答を逆シリアル化するLUISOutputクラスを作成しました。

public class LUISOutput 
{ 
    public string query { get; set; } 
    public LUISIntent[] intents { get; set; } 
    public LUISEntity[] entities { get; set; } 
} 
public class LUISEntity 
{ 
    public string Entity { get; set; } 
    public string Type { get; set; } 
    public string StartIndex { get; set; } 
    public string EndIndex { get; set; } 
    public float Score { get; set; } 
} 
public class LUISIntent 
{ 
    public string Intent { get; set; } 
    public float Score { get; set; } 
} 
あなたは何をすべきか@NicolasRいくつかのカスタムトリートメント
+0

[Git Hub](https://github.com/Kumar-Ashwin-Hubert/LuisInsideFormFlow)と同じものを確認してください。 –

2

このような状況では、フォームフローの外でルイスインテントを呼び出すのが最適かもしれません。あなたが探している機能は、正確には存在しません。

[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<PizzaOrder>(new PizzaOrder(), this.MakePizzaForm, FormOptions.PromptInStart, entities); 
    context.Call<PizzaOrder>(pizzaForm, PizzaFormComplete); 
    context.Wait(this.MessageReceived); 
} 
関連する問題