From 79e641c4a892f7fb19b7fcb6ed764fd48dc9ebaa Mon Sep 17 00:00:00 2001 From: Oceania2018 Date: Thu, 24 May 2018 08:10:10 -0500 Subject: [PATCH] Supportt Rasa NLU 0.12.x --- BotSharp.Core/BotSharp.Core.csproj | 3 +- BotSharp.Core/Engines/RequestExtension.cs | 76 +++++++++---------- BotSharp.UnitTest/AgentTest.cs | 1 - BotSharp.UnitTest/IntentTest.cs | 4 + .../Settings/config_jieba_mitie_sklearn.yml | 13 ++++ 5 files changed, 56 insertions(+), 41 deletions(-) create mode 100644 BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml diff --git a/BotSharp.Core/BotSharp.Core.csproj b/BotSharp.Core/BotSharp.Core.csproj index ce66c15c..ab625d88 100644 --- a/BotSharp.Core/BotSharp.Core.csproj +++ b/BotSharp.Core/BotSharp.Core.csproj @@ -17,7 +17,8 @@ MIT https://github.com/Oceania2018/BotSharp NLU, Chatbot, Bot, AI Bot - 1.0.0 + 1.1.0 + Support Rasa NLU 0.12.x diff --git a/BotSharp.Core/Engines/RequestExtension.cs b/BotSharp.Core/Engines/RequestExtension.cs index eef9045b..346ae0d1 100644 --- a/BotSharp.Core/Engines/RequestExtension.cs +++ b/BotSharp.Core/Engines/RequestExtension.cs @@ -32,14 +32,13 @@ namespace BotSharp.Core.Engines var result = CallRasa(rasa.agent.Id, request.Query.First(), rasa.agent.Id); RasaResponse response = result.Data; - var intentResponse = HandleIntentPerContextIn(rasa, request, result.Data); - aiResponse.Id = Guid.NewGuid().ToString(); aiResponse.Lang = rasa.agent.Language; aiResponse.Status = new AIResponseStatus { }; aiResponse.SessionId = rasa.AiConfig.SessionId; aiResponse.Timestamp = DateTime.UtcNow; + var intentResponse = HandleIntentPerContextIn(rasa, request, result.Data); HandleParameter(rasa.agent, intentResponse, response, request); HandleMessage(intentResponse); @@ -48,13 +47,13 @@ namespace BotSharp.Core.Engines { Source = "agent", ResolvedQuery = request.Query.First(), - Action = intentResponse.Action, - Parameters = intentResponse.Parameters.ToDictionary(x => x.Name, x=> x.Value), + Action = intentResponse?.Action, + Parameters = intentResponse?.Parameters?.ToDictionary(x => x.Name, x=> x.Value), Score = response.Intent.Confidence, - Metadata = new AIResponseMetadata { IntentId = intentResponse.IntentId, IntentName = intentResponse.IntentName }, + Metadata = new AIResponseMetadata { IntentId = intentResponse?.IntentId, IntentName = intentResponse?.IntentName }, Fulfillment = new AIResponseFulfillment { - Messages = intentResponse.Messages.Select(x => { + Messages = intentResponse?.Messages?.Select(x => { if (x.Type == AIResponseMessageType.Custom) { return (new @@ -115,21 +114,31 @@ namespace BotSharp.Core.Engines }; } response.IntentRanking = response.IntentRanking.Where(x => intents.Select(i => i.Name).Contains(x.Name)).ToList(); - response.Intent = response.IntentRanking.First(); - var intent = (dc.Table().Where(x => x.Name == response.Intent.Name) - .Include(x => x.Responses).ThenInclude(x => x.Contexts) - .Include(x => x.Responses).ThenInclude(x => x.Parameters) - .Include(x => x.Responses).ThenInclude(x => x.Messages)).First(); + if (response.IntentRanking.Count == 0) + { + return null; + } + else + { + response.Intent = response.IntentRanking.First(); - var intentResponse = ArrayHelper.GetRandom(intent.Responses); - intentResponse.IntentName = intent.Name; + var intent = (dc.Table().Where(x => x.Name == response.Intent.Name) + .Include(x => x.Responses).ThenInclude(x => x.Contexts) + .Include(x => x.Responses).ThenInclude(x => x.Parameters) + .Include(x => x.Responses).ThenInclude(x => x.Messages)).First(); - return intentResponse; + var intentResponse = ArrayHelper.GetRandom(intent.Responses); + intentResponse.IntentName = intent.Name; + + return intentResponse; + } } private static void HandleParameter(Agent agent, IntentResponse intentResponse, RasaResponse response, AIRequest request) { + if (intentResponse == null) return; + intentResponse.Parameters.ForEach(p => { string query = request.Query.First(); var entity = response.Entities.FirstOrDefault(x => x.Entity == p.Name); @@ -164,6 +173,8 @@ namespace BotSharp.Core.Engines private static void HandleMessage(IntentResponse intentResponse) { + if (intentResponse == null) return; + intentResponse.Messages = intentResponse.Messages.OrderBy(x => x.UpdatedTime).ToList(); intentResponse.Messages.ToList() .ForEach(msg => @@ -196,6 +207,8 @@ namespace BotSharp.Core.Engines private static void HandleContext(Database dc, RasaAi rasa, IntentResponse intentResponse, AIResponse aiResponse) { + if (intentResponse == null) return; + // Merge context lifespan // override if exists, otherwise add, delete if lifespan is zero dc.DbTran(() => @@ -444,30 +457,12 @@ namespace BotSharp.Core.Engines public static string Train(this RasaAi console, Database dc) { + var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Nlu").Value}"); + var rest = new RestRequest("train", Method.POST); + rest.AddQueryParameter("project", console.agent.Id); + var corpus = console.agent.GrabCorpus(dc); - // Add some fake data - if(corpus.UserSays.Count < 3) - { - corpus.UserSays.Add(new RasaIntentExpression - { - Intent = "Welcome", - Text = "Hi" - }); - - corpus.UserSays.Add(new RasaIntentExpression - { - Intent = "Welcome", - Text = "Hey" - }); - - corpus.UserSays.Add(new RasaIntentExpression - { - Intent = "Welcome", - Text = "Hello" - }); - } - string json = JsonConvert.SerializeObject(new { rasa_nlu_data = corpus }, new JsonSerializerSettings { @@ -475,10 +470,13 @@ namespace BotSharp.Core.Engines NullValueHandling = NullValueHandling.Ignore }); - var client = new RestClient($"{Database.Configuration.GetSection("Rasa:Nlu").Value}"); - var rest = new RestRequest("train", Method.POST); - rest.AddQueryParameter("project", console.agent.Id); +#if RASA_NLU_0_11 rest.AddParameter("application/json", json, ParameterType.RequestBody); +#else + string body = File.ReadAllText($"{Database.ContentRootPath}{Path.DirectorySeparatorChar}Settings{Path.DirectorySeparatorChar}config_jieba_mitie_sklearn.yml"); + body = body.Replace("@data", json); + rest.AddParameter("application/x-yml", body, ParameterType.RequestBody); +#endif var response = client.Execute(rest); diff --git a/BotSharp.UnitTest/AgentTest.cs b/BotSharp.UnitTest/AgentTest.cs index 7a3f11f2..21b25ff0 100644 --- a/BotSharp.UnitTest/AgentTest.cs +++ b/BotSharp.UnitTest/AgentTest.cs @@ -66,7 +66,6 @@ namespace BotSharp.UnitTest config.SessionId = Guid.NewGuid().ToString(); var rasa = new RasaAi(dc, config); - rasa.agent = rasa.LoadAgent(dc, config); string msg = rasa.Train(dc); Assert.IsTrue(!String.IsNullOrEmpty(msg)); diff --git a/BotSharp.UnitTest/IntentTest.cs b/BotSharp.UnitTest/IntentTest.cs index 16f6b7f5..533e65f4 100644 --- a/BotSharp.UnitTest/IntentTest.cs +++ b/BotSharp.UnitTest/IntentTest.cs @@ -18,6 +18,10 @@ namespace BotSharp.UnitTest config.SessionId = Guid.NewGuid().ToString(); var rasa = new RasaAi(dc, config); + + // Round 1 + var response = rasa.TextRequest(new AIRequest { Query = new String[] { "Hi" } }); + Assert.AreEqual(response.Result.Metadata.IntentName, "greet"); } } } diff --git a/BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml b/BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml new file mode 100644 index 00000000..b49a4e34 --- /dev/null +++ b/BotSharp.UnitTest/Settings/config_jieba_mitie_sklearn.yml @@ -0,0 +1,13 @@ +language: "zh" + +pipeline: +- name: "nlp_mitie" + model: "data/total_word_feature_extractor_zh.dat" +- name: "tokenizer_jieba" +- name: "ner_mitie" +- name: "ner_synonyms" +- name: "intent_entity_featurizer_regex" +- name: "intent_featurizer_mitie" +- name: "intent_classifier_sklearn" + +data: @data