BOT FRAMEWROK技术白皮书 第三章 将Bot与LUIS结合

第三章 将BotLUIS结合

微软认知服务中的语义理解服务—LUIS:即自然语言处理,是基于在线的大量语料库进行集成,可以提取出用户的意图。举个简单的例子,日常对话中很多人去打招呼,方式也各不相同:你好, hi, hello,甚至是你吃了吗,传统的制作机器人的套路是以穷尽问题的方式去回答,让程序员在大量语料库中进行判断。微软的研究员同学这么多年的研究终于实现了产品化,可以通过微软提供的LUIS服务,将这些具体的问法归结为同一个意图“打招呼”,这我们的程序员就可以不需要考虑大量实际的问法,只针对于意图回复。我们可以将用户的需求通过意图提取跟我们的业务相互对应,使得用户可以通过简单对话的方式,完成之前可能需要打开网页,点击或者touch操作才能完成的人机交互。

1.     新建LUIS服务

打开链接https://www.luis.ai/ 并注册一个新账号,然后点击“New App”创建新应用:

 

 

在“Add a new application”对话框中,输入应用程序名称、用途等基本信息,然后在“Choose Application Culture”中选择中文,然后点击“Add app”

 

 

在界面左侧的Tab中,点击“Entities”旁边的+,并为新建的Entity起名为“地点”,然后点击Save,如下图

 

点击“Intents”旁边的+,在新建Intent界面中,输入“查询天气”作为Intent名称,然后输入例句,如下图所示:

 

 

点击Save之后,用鼠标选择例句中的“北京”二字,并将其标注为“地点”,然后点击“Submit”,如下图所示:

 

 

在“New utterances”标签下再输入一些查询天气的例句

 

 

点击左下角的“Train”按钮

训练完成之后,点击左上角的“Publish”按钮,然后点击“Publish web service”

 

 

将URL中的ID和subscription-key记下来,后面需要用到

 

 

然后输入例句进行测试,并查看API调用后所返回的JSON信息,如下图所示:

 

 

2.     在Bot中集成LUIS服务

回到Visual Studio,打开Controllers\MessagesController.cs文件。将

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)中的代码替换为如下内容:

public virtual async Task<HttpResponseMessage> Post([FromBody] Activity activity)

       {

            if (activity.Type == ActivityTypes.Message)

            {

                await Conversation.SendAsync(activity, () => new WeatherDialog());

            }

            else

            {

                //add code to handle errors, or non-messaging activities

            }

 

            return new HttpResponseMessage(System.Net.HttpStatusCode.Accepted);

   }

 

 

新建名为WeatherDialog的类,粘贴如下代码:

namespace WeatherSample

{

    using System;

    using System.Collections.Generic;

    using System.Linq;

    using System.Threading.Tasks;

    using Microsoft.Bot.Builder.Dialogs;

    using Microsoft.Bot.Builder.Luis;

    using Microsoft.Bot.Builder.Luis.Models;

    using Newtonsoft.Json;

    using Newtonsoft.Json.Linq;

    using System.Xml;

    using System.Net.Http;

 

    [LuisModel("LUIS的ID", "LUIS的Key")]

    [Serializable]

    public class WeatherDialog : LuisDialog<object>

    {

        public const string Entity_location = "Location";

 

        [LuisIntent("")]

        public async Task None(IDialogContext context, LuisResult result)

        {

            string message = $"您好,我还年轻,目前只能提供中国地区天气查询功能";

            await context.PostAsync(message);

            context.Wait(MessageReceived);

        }

   

 

       

 

        [LuisIntent("查询天气")]

        public async Task QueryWeather(IDialogContext context, LuisResult result)

        {

            string location = string.Empty;

            string replyString = "";

 

            if (TryToFindLocation(result, out location))

            {

                replyString = GetWeather(location);

 

                JObject WeatherResult = (JObject)JsonConvert.DeserializeObject(replyString);

                var weatherinfo = new

                {

                    城市 = WeatherResult["weatherinfo"]["city"].ToString(),

                    温度 = WeatherResult["weatherinfo"]["temp"].ToString(),

                    湿度 = WeatherResult["weatherinfo"]["SD"].ToString(),

                    风向 = WeatherResult["weatherinfo"]["WD"].ToString(),

                    风力 = WeatherResult["weatherinfo"]["WS"].ToString()

                };

 

 

                await context.PostAsync(weatherinfo.城市 + "的天气情况: 温度" + weatherinfo.温度 + "度;湿度"+weatherinfo.湿度+";风力"+weatherinfo.风力+";风向"+weatherinfo.风向);

            }

            else

            {

 

                await context.PostAsync("亲你要查询哪个地方的天气信息呢,快把城市的名字发给我吧");

            }

            context.Wait(MessageReceived);

 

        }

 

        private  string GetWeather(string location)

        {

            string weathercode = "";

            XmlDocument citycode = new XmlDocument();

            citycode.Load("https://wqbot.blob.core.windows.net/botdemo/CityCode.xml");

            XmlNodeList xnList = citycode.SelectNodes("//province//city//county");

            foreach (XmlElement xnl in xnList)

            {

                if (xnl.GetAttribute("name").ToString() == location)

                    weathercode = xnl.GetAttribute("weatherCode").ToString();

            }

            HttpClient client = new HttpClient();

            string result = client.GetStringAsync("http://www.weather.com.cn/data/sk/" + weathercode + ".html").Result;

            return result;

        }

        private bool TryToFindLocation(LuisResult result, out String location)

        {

            location = "";

            EntityRecommendation title;

            if (result.TryFindEntity("地点", out title))

            {

                location = title.Entity;

            }

            else

            {

                location = "";

            }

            return !location.Equals("");

        }

    }

}

右键点击项目,然后点击Publish进行发布。发布完成后,即可实现与机器人的简单对话,如下图所示:

 

 

posted @ 2016-11-22 13:43  YuhengDing  阅读(238)  评论(0)    收藏  举报