在16年3月30号微软的全球开发者大会Build上发布了Bot Framework,微软认为下一个big thing是Conversation as a Platform,简称CaaP,中文应该叫做"对话即平台"。在我们的下个时代,我们将会处在对话即平台的时代,不管是一个屏幕,一个桌子,一个冰箱,甚至是人,都是一个app,都是一个对话的窗口,所有的交互都通过对话来完成。起床,你用自然语言唤起梳妆台的镜子显示今日的天气,还有新闻。家里的小娜(Cortana)提醒你要赶紧出门,路上因为限号4,9,根据历史的预测,会提早堵车,需要提前20分钟出发。
那这个时代,将是如何实现的呢?人工智能不是简单一个团队,一小段时间就能完成的,需要经过大量的科研人员,进行大量的研究才能实现的。那怎么样才能实现物物智能,智能众生的构想呢?微软将微软亚太研究院多年的研究技术开放出来,让各个开发者,不管是大公司,小公司甚至是个人都可以借助"智能"的"洪荒之力",实现智能对话平台的未来。
打造这样的智能服务需要涉及到微软的两个技术,Bot Framework和Cognitive Services(认知服务)。
Bot Framework就是帮你快速搭建智能服务的后端,快速在各种终端和服务上提供服务。包括三大组件。
Bot Builder SDKs:
这个是Bot的生成器,快速生成一个ASP.NET和Node.js的后端服务,提供了像Dialog、FormFlow帮你管理与用户的会话。
Bot Connector:
这是个Bot的Channel,帮你把你的服务快速发布到各个渠道,比如说Skype,Facebook Messager等等。这样用户就可以在Skype等Channel上使用你的服务了。
Bot Directory:
这个算是Bot 的商店,在这里可以找到各个bot,你也可以把自己的Bot发布出来,从而大家都可以看到你的Bot。
Cognitive Services(认知服务)的前身是Project Oxford(牛津计划),正式发布的时候更名的。这是微软将研究院研究的技术以API和SDK的形式开放给开发者的一系列智能化服务。
主要包括5大类的服务:视觉、语言、语言、知识和搜索。
其实就包括我们今天要讲的"语言理解(Language Understanding Intelligent Service,简称LUIS)"。
我们今天以一个例子举例,来详细介绍怎么利用Bot Framework和LUIS("撸以si")打造一个智能陪护机器人。
一、下载Bot Framework的SDK
首先,请下载Bot Framework的SDK,建议下载Bot Framework的Visual Studio的模板Bot Application。
下载下来的模板(不用解压)请直接放置到C:Users你的用户名DocumentsVisual Studio 2015TemplatesProjectTemplatesVisual C# 下面,这样你在C#下面就可以看到有Bot Application的模板了。
如果是使用NuGet来下载SDK,请参考:
-
右键你的C#项目,选择"Manage NuGet Packages".
-
在"Browse"的tab页,输入"Microsoft.Bot.Builder".
-
点击"Install"的按钮.
如果你使用的是Node.js,请使用以下命令:
npm install botbuilder
二、在Azure上创建bot服务
咱们现在创建一个Bot Application的应用。我准备创建一个叫做"萌萌"的机器人。
在Azure上创建Bot服务:搜索bot,选择"Web App Bot"。
点击创建,填写相关的信息:
选择基本模板即可,其他默认选项即可。
配置完成后,点击创建,等待几分钟即可创建完成。
创建完成你可看到Bot服务帮你创建了5个相关服务。
点击第一个Web App Bot服务,即可配置Bot相关服务。
"Name":你的bot的名字,比如我的叫做"萌萌"。
"句柄(Bot Handle)":比如我的写"mengmeng",其实就是你的Bot的id,记下来。
"Description":你的Bot的描述,会在你的publish之后主页上显示。
点击"信道",其实就是配置各个平台,里头可以看到"Web Chat",这个是网页端的channel,已经帮你写好的一个iframe,咱们点击"Edit"。
生成Web Chat的密钥之后,把密钥复制,点击"I'm done configuring Web Chat"。
在资源组中,选择你创建的资源组,点击"部署":
请记下APPID和AppSecret两个参数,后面会用到。
三、准备你的机器人后端服务代码
从我的GitHub地址下载代码:https://github.com/cheneyszp/MengmengBot
在你的Web.config里,填上你的BotId,刚才创建的App ID和AppSecret。
打开网站的起始页default.htm
复制以下代码:
<!DOCTYPE html>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<html>
<head>
<title>萌萌</title>
<meta charset="utf-8" />
</head>
<body style="font-family:'Segoe UI'">
<iframe name="myframe" scrolling="auto" width="100%" height="100%"
onload="document.all['myframe'].style.height=myframe.document.body.scrollHeight"
src="https://webchat.botframework.com/embed/你自己的Bot句柄?s=你 自 己 的 Web Chat 密 钥 " style="height: 502px; max-height: 502px;"></iframe>
</body>
</html>
然后右键项目工程,点击"publish",之后你就可以拥有一个简单的Bot啦。
四、新建LUIS服务
请先登录:https://www.luis.ai/ ,这是语言理解服务的portal。如果还没注册的话用live id注册以下就可以了。
点击"App"这一栏,咱们先点击"new App"新建一个app。
新建完成后,点击应用的名称,进入编辑这个应用。
我们先看以下左边的tab,可以看到有仪表盘,意图(Intents),实体(Entities),功能。。。。
Intents:就是意图,比如咱们现在要提供天气查询的服务,那么咱们就创建一个"查询天气"的Intent。
实体里头有两类:
Entities:实体,比如在查询天气的时候需要有地理位置信息,需要把用户的语言里头的地点提取出来,这个地点就是这个句子里头的实例,咱们创建一个"地点"的实例。
Pre-built Entities(预建实体):这个是预置好的实例,比如说时间,数字等等,我加了一个datetime的预置实例。
在功能里头会有:
Phrase List(短语列表功能):固定的一些短语,能够直接识别,比如说航空公司的名字等已知信息
Pattern Features(模式功能):正则表达式,可以匹配出相应的一些字段,比如说航班号。
咱们现在来创建一个能够识别查询天气的语言理解服务。
首先,查询天气需要地点信息,咱们先创建一个"地点"的实例。
点击到"实体"里头,"添加自定义实体":
添加一个"预建实体" datetime:
再创建一个叫做"查询天气"的Intent。
点击Done之后,点击"查询天气"会进入以下界面:
输入几个例子,比如说"北京天气怎么样",可以多输入几个句子的类型,比如"北京今天有雾霾吗?"等等,每输入完一句按一下回车。
如果北京等地点信息没有显示标记的话,选中北京两个字,然后选择"地点"标注。然后点击"保存"。
随手点击该界面右上角的"Train"按钮进行训练。
可以点击Test进行测试。
随手点击"Publish"的tab页面,进入到一下界面,点击"Publish to production slot"
点击Publish之后,你可以在Publish的tab页面底下,可以看到"Resources and Keys" ,
试用的话会给你自动生成一个Starter Key,右边的链接就是Publish出来的链接地址啦
如:https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/LUIS_APP_ID?subscription-key=LUIS_subscription-key&timezoneOffset=0.0&verbose=true&q=
如果商用的话,需要在Azure Portal创建一个LUIS服务,然后点击"Add Key",把LUIS的Key添加进来。
url后面加上查询语句就是API了。
https://westus.api.cognitive.microsoft.com/luis/v2.0/apps/LUIS_APP_ID?subscription-key=LUIS_subscription-key&timezoneOffset=0.0&verbose=true&q=北京今天天气怎么样?
把LUIS的ID(就是apps后面那串字符)和subscription-key记下来,后面需要用到。
在URL后面可以输入相关的语句,然后回车,就可以看到返回的json字符串了。
四、在Bot中集成LUIS服务
现在我们就把LUIS集成到你的Web服务里头来就可以了。
咱们用Dialog的方式来完成,比较好管理会话。
在MessagesController.cs里头的public class MessagesController : ApiController添加MengmengDialog的类。
[LuisModel("你LUIS的ID", "你LUIS的subscription-key ")]
[Serializable]
public class MengmengDialog : LuisDialog<object>
{
public MengmengDialog()
{
}
public MengmengDialog(ILuisService service)
: base(service)
{
}
[LuisIntent("")]
public async Task None(IDialogContext context, LuisResult result)
{
string message = $"萌萌不知道你在说什么,面壁去。。。我现在只会查询股票和查询天气。。T_T" + string.Join(", ", result.Intents.Select(i => i.Intent));
await context.PostAsync(message);
context.Wait(MessageReceived);
}
public bool TryToFindLocation(LuisResult result, out String location)
{
location = "";
EntityRecommendation title;
if (result.TryFindEntity("地点", out title))
{
location = title.Entity;
}
else
{
location = "";
}
return !location.Equals("");
}
[LuisIntent("查询天气")]
public async Task QueryWeather(IDialogContext context, LuisResult result)
{
string location = "";
string replyString = "";
if (TryToFindLocation(result, out location))
{
replyString = await GetWeather(location);
await context.PostAsync(replyString);
context.Wait(MessageReceived);
}
else
{
await context.PostAsync("亲你要查询哪个地方的天气信息呢,快把城市的名字发给我吧");
context.Wait(AfterEnterLocation);
}
}
}
GetWeather这个函数需要自己实现,调用相关的API返回相应的天气信息。
然后在Task<HttpResponseMessage> Post([FromBody]Activity activity)下创建MengmengDialog来处理对话的内容。
public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
if (activity.Type == ActivityTypes.Message)
{
await Conversation.SendAsync(activity, () => new MengmengDialog());
}
else
{
HandleSystemMessage(activity);
}
var response = Request.CreateResponse(HttpStatusCode.OK);
return response;
}
然后发布,这样我们的天气查询机器人就完成啦!
测试一下:
换着问法问天气,发现都没问题,都能够正确地识别出来。
在LUIS Portal里头,点击"Review endpoint utterances",可以看到所有调用LUIS API发过来的消息,也就是说,你可以在这里看到所有用户发来的消息。
你可以看看LUIS标注得对不对,如果错了勾选,然后选择"重新分配意图",然后保存,之后LUIS会学习到这个知识,变得越来越准。
重新标注之后记得重新train一下然后publish哈。
比如说,输入"北京现在天气怎么样",发现只识别出来Intent,但是没有识别出来地点。
重新标注,train,重新publish一下。
发现已经能够正确识别。
试试吧,有问题留言:)
代码已经发布到GitHub,请参考:https://github.com/cheneyszp/MengmengBot