讲清了一些最最基本的概念ios
- Intents(意图)和Entities(关键字)git
- 基于意图(Intent-based)的对话 和 基于流程(Flow-based)的对话 github
imageweb
随著苹果Core ML的最新版本发佈,开发人员更容易构建人工智能应用程式,除了图像识别和文本检测是利用AI建置APP的好例子,另外一种善于展示机器学习Power的应用程式类型则是chatbots。在本教程中,咱们将使用Google的Dialogflow(之前称为API.AI)构建在iOS上运行的chatbot应用程式!算法
听起来很酷吧!接下来开始进入本教程的重点。编程
在开始以前,我先解释Dialogflow和chatbots的通常基本知识。 在构建chatbots时,你必须知道两个术语:Intents(意图)和Entities(关键字)。swift
An entity represents a term or object in the user’s input that provides clarification or specific context for a particular intent. (entity表示用户输入中的术语或对象,为intent提供说明或使用情境。) An intent, on the other hand, represents something that the user wants to do. If intents represent verbs, then entities represent nouns. (另外一方面,intent表明用户想要作的事情,若是intent表明动词,则entities表明名词。)api
来看一个例子,在咱们的项目中,可能会告诉咱们的机器人如下声明:网络
“Book me a room at the La Grande Hotel”(替我在La Grande Hotel订一间房)闭包
在这句话中,咱们的intent(意图)是”预约一个房间”,entity(关键字)是”La Grande Hotel”,如今,天然语言处理(NLP)算法能够计算两种不一样类型的对话内容。
注意:若是想了解更多有关Intent-based和Flow-based的对话信息,能够查看这篇文章。
在本教程中,咱们将建立一个可帮助你预订hotel的机器人。
One of the most important rules when developing a chatbot is that it MUST have a personna. This means that it must behave like a real person. Therefore, let’s name out bot – Chip! (开发chatbot最重要的规则之一,就是它必须有一个personna,意味著它必须像真人同样行事。 所以,让咱们来替bot命名 – Chip!)
接下来,就进入本文重点!
进入到Dialogflow,在右上角点击”Go to Console(前往控制台)”。
Dialogflow
系统会要求你使用Google账户登陆,并受权使用Dialogflow在Google云端平台服务中查看和管理你的资讯,接受条款,你应该看到一个初始啟动页面。
Dialogflow-console
观看介绍影片可让你更快速了解Dialogflow,但若是你不想花时间看也没关係!点击”Create Agent”按钮,在Dialogflow中,一个agent(代理)意味著iOS应用将使用chatbot经过无线方式进行通信以接收回应。
填写代理名称(好比Chip),而后点击Create按钮进行下一步,Dialogflow将为你建立agent。如今,让咱们来确认一下,你应该有2个预设intents:”Default Welcome Intent”和”Default Fallback Intent”。在左侧栏位中,你应该能够看到Intents和Entities的tabs(选项)。
Create Agent in Dialogflow
咱们也会在下方看到其余tabs。如今,该开始建立机器人了!
首先,让咱们开始添加entities,若是你还记得,entities就像NLP算法能够理解的名词,拿出一个可能常常用于咱们机器人的entities名单,我已经把我整理的list放在下面,而且随时能够添加它。
选择entities选项,而后点击”Create Entity”按钮。并将这个entity命名为”Hotel”,并点击第一行,输入”Hotel”当作参考值,当用户使用你的机器人时,他们可能会使用Hotel之外的其余名称。 所以,应该输入关键字的一些同义词,即便用户使用”Hotel”之外的字,机器人仍然能够理解用户在说什么,看下面的图片,我使用了一些同义词。
Dialogflow-add-entity
如今,储存你的entity,并按照刚才建置Hotel entity的步骤建立如下的entities。
Dialogflow-entity-payment
Dialogflow-entity-room
小建议:要查找单词的同义词,只需Google搜寻”synonyms of [word]”。
如今咱们已经建立了entities,接著来讨论intents。
进入Intents页面并点击Default Welcome Intent,这个intent就是咱们机器人在第一次啟动时会抓取的东西,你应该看到网页呈现以下:
Dialogflow-intent
咱们能够制定用户应该说出哪一个字去触发intent。在本页面的最底部,咱们也能够制定回应的文本内容,因为这是一个Welcome intent,用户可能会说”Hello!”或”How’s it going?” 所以,让咱们将这些短语(和任何相似的同义词)添加到’User says’部分,如下是一些范例,你能够随意地添加更多的讯息,设定你的用户可能会对机器人说的字汇。
Dialogflow-welcome-intent
若是向下滚动,会找到* Response *部分。intent带有一些内置的回应,咱们添加一个follow up question(关联性问题):”What can I do for you?”,咱们最终Welcome intent应该是这样的:
Dialogflow-welcome-intent-response
在咱们开始建立下一个intent以前,若是你想在任什么时候候测试你的agent,请查看右侧栏位,你能够输入想要的任何内容,而后查看你的agent是否回应。输入”Hello”,而后检查agent是否回应了预期的回应。
到目前为止,agent只有一个intent,因为咱们的机器人是为处理预订hotel而设计的,所以咱们必须建立另外一个处理intent这些查询,用户可能会问:“能替我预订一家旅馆吗?” 或相似的问句。
让咱们建立一个新的intent,并将其命名Begin Order。在User says栏位中,添加上面的表达式而后按下enter。一旦你输入了这个表达式,将会看到agent已经在该语句中识别了一个@Hotel
关键字。与entities相似,用户不会只用这个问句来表达预订酒店的需求。因此这里添加一些变化,以agent理能够了解用户的意思,增长的变化越多,agent也就越聪明,如下是一个范例展现。
Dialogflow Begin Order Intent
agent应该作的下一件事是搜索附近的hotel,并询问用户他/她须要几间房。可是,若是咱们要真正搜寻附近的酒店,则须要调用API并使用JavaScript将webhook与api.ai整合在一块儿,这超出了本教程的范围,因此让咱们在Response栏位建立一些虚拟酒店,这是我建立的回应内容:
Dialogflow-begin-order-response
储存intent并返回到主页面,在右侧栏位中测试你的agent,到目前为止,若是读者有跟著前面的步骤,它应该按预期工做!正如你所看到的,没必要提出确切的问题,Dialogflow将从你的陈述中学习并理解变化。
test-agent
如今,咱们来添加一些follow-up intent,将鼠标移动在你刚建立的intent上,你应该看到一个选项”Add follow-up intent”,选择它并点击Custom,将產生一个新的intent,并显示”Begin Order – custom”,让咱们编辑这个intent!
Dialogflow-add-follow-intent
请记住,咱们agent对咱们说的最后一件事情是”How many rooms do we want?”,用户可能会回覆一个数字,他/她可能会说:”I would like 1 room”或简单地回答”4″,你应该要预测用户会说什么,并填写全部可能的答案,请参考如下我填写的范例:
begin-order-followup-intent
正如你所看到的,Dialogflow有一个内置的数字entity,无论你输入一个数字仍是一个单词,它都可以处理它并理解它的含义。
接下来,咱们要让机器人回应确认价格总额,并询问用户喜欢什么付款方式。一样的,于这些是hotel虚拟资料,咱们能够在机器人的反应中添加虚拟的价格。
begin-order-followup-response
保存这个intent,如今给读者一个挑战,建立最后一个intent,即询问用户使用何种付款方式付款,这应该是很是简单的,由于咱们已经作了两次!
因此咱们将回到intent的主页面,而后点击Create Intent。
注意: 没有建立另外一个follow-up intent,由于当机器人第一次触发时,用户不太可能会说出付款方式的名称,这就是为何我要创造一个normal intent,就像咱们在刚开始时所作的。
将这个intent命名为Payment并添加用户可能会说的内容,这是咱们的Payment关键字(entity)使用的地方!
Dialogflow-payment-intent
最后,让机器人回应一些确认讯息。如下是一些范例:
就是这样!请记住保存Payment意图,Chip如今可使用了,在咱们转到本教程的iOS端以前,你能够在右侧栏位中对其进行测试。
在开始真正的编程以前,让我花点时间来解释Dialogflow控制台左侧栏位中的其余tabs,在Entities下,有一个名为Training的tab,若是点击此选项,你将收到全部发送给agent的回覆讯息以及agent回覆的内容,若是你告诉你的agent一些回应文本,但它回应你不喜欢的输出,这就很是有用,若你稍后意识到忘记了某个关键字的同义词,而且用户正在使用这个关键字,那么也可能会有所帮助,能够去告诉你的代理在这种状况下应该作什么。
在Training下方,你能够看到Integrations。在这里,能够管理你的agent去串接不一样的服务,例如Google Assistant,Twitter,Slack,Messenger,Cortana,Alexa等等。Integrations以后,还有Analytics,基本上用来显示建议名称,以后还有Fulfillment,若是你要调用一个API并实现一个webhook,这就是你会须要来的地方。
Dialogflow-integration
最后两个选项功能很是简单,但颇有用。第一个是Prebuilt Agents,在这里,你能够import一个预先存在的代理框架,有不少例子,如食物传递机器人,音乐机器人,甚至(抱歉,但你真的须要知道这个)hotel预订机器人! 最后一个选项是Small Talk,若是你将代理设计为像Siri或Google Assistant这样的每日伙伴(daily companion),这个选项很是有用,Small Talk容许你添加常见问题的答案,咱们都喜欢问咱们的机器人,如”你几岁?”或”你住哪里?”,以及更热门的问题”你愿意嫁给我吗?”
如今你已经知道Dialogflow是什么,而且对于如何操做有很好的观念了,如今是时候移动到另外一端,开始编写Swift代码!
如今咱们移动到本教程Swift的部分,首先[下载初始项目](https://github.com/appcoda/ChatbotHotel/raw/master/ChatbotStarter.zip),我已经构建了基本的UI并绑定了API.AI SDK。若是你从头构建应用程序,则可使用CocoaPods安装API.AI SDK(这是用于链接到Dialogflow的SDK),只需在Podfile中添加如下讯息:
pod 'ApiAI'
一旦你unzip初始项目,确保你打开了Chatbot Starter Project.xcworkspace
文件。进入Main.storyboard
,已经有一个UILabel
,UIButton
和UITextField
,它们的outlets也链接到ViewController.swift
。
demo-app-main-storyboard
先来看看AppDelegate.swift
,咱们须要让APP链接到Dialogflow的servers,在import UIKit
的正下方,输入如下代码来导入framework:
import ApiAI
如今,须要使用client access token来初始化咱们的配置,请参照下面范例更新didFinishLaunchingWithOptions
方法:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { let configuration = AIDefaultConfiguration() configuration.clientAccessToken = "YOUR_CLIENT_ACCESS_TOKEN" let apiai = ApiAI.shared() apiai?.configuration = configuration return true }
将字符串”YOUR_CLIENT_ACCESS_TOKEN”替换你本身的机器人的client access token,若是你不知道在哪里能够找到,请移动到Dialogflow中的chatbot settings。 在”General”选项下,你应该在”API keys栏位下找到client access token。
Dialogflow-api-key
如今,当咱们的应用程式啟动时,它将使用client access token链接到Chip bot。
前往ViewController.swift
,而且在import UIKit
之下,import ApiAI和AVFoundation框架:
import ApiAI import AVFoundation
咱们须要导入AVFoundation
框架,由于咱们须要bot与用户交谈,该框架附带了可以从文本转为合成语音的“AVSpeechSynthesizer”类别,为了让装置与咱们的用户交谈,在ViewController
类中插入如下几行代码:
let speechSynthesizer = AVSpeechSynthesizer() func speechAndText(text: String) { let speechUtterance = AVSpeechUtterance(string: text) speechSynthesizer.speak(speechUtterance) UIView.animate(withDuration: 1.0, delay: 0.0, options: .curveEaseInOut, animations: { self.chipResponse.text = text }, completion: nil) }
让我告诉你上面的代码作了哪些事。首先,咱们定义一个常数speechSynthesizer
,并初始化一个 AVSpeechSynthesizer
的实例。AVSpeechSynthesizer是一个提供自文本转换为语音的object,并容许存取控制正在进行的访问,而后建立一个新的函数speechAndText(text: String)
,根据用户输入的内容执行更改。
在函数内部,咱们建立一个AVSpeechUtterance的实例,最简单的说,它是一个将被宣读的文本块。而后,咱们要求装置读出这段文字,同时,咱们想向用户展现机器人的response,这就是为何咱们将label的text设置为机器人的response。
我使用UIView.animate
方法为label转换为微妙的动画,当你正在开发本身的应用程式,但不具有建立高品质的动画知识,则这种方法能够实现这一效果。
咱们只剩下最后一部分,当用户点击按钮时,应发送request给咱们的代理,让咱们看看咱们该怎么作!在sendMessage
操做方法中插入如下几行代码:
let request = ApiAI.shared().textRequest() if let text = self.messageField.text, text != "" { request?.query = text } else { return }
这段code是至关基本的,可是可能部分读者不太理解这段代码,仍是让我解释一下。基本上,咱们以用户提供的query条件来準备API.AI文本请求,从messageField
中检索文本并执行基本验证,确保文本字段不是空白,一旦咱们获得了这段text,就将它丢给request的query
属性。
好的,文本request已经準备好了,下一步是发起请求并发送给机器人。固然,咱们须要处理API.AI代理回应的任何内容,有两种可能性:success或failure,若是代理程序返回成功讯息,那么咱们但愿应用程式说出回应并将其显示在萤幕上,若是出现失败讯息,那么应用程式只是打印错误到控制台,咱们能够经过使用下面的代码来实现:
request?.setMappedCompletionBlockSuccess({ (request, response) in let response = response as! AIResponse if let textResponse = response.result.fulfillment.speech { self.speechAndText(text: textResponse) } }, failure: { (request, error) in print(error!) })
request执行完成后,应用程式须要作什么,你能够调用setMappedCompletionBlockSuccess
方法并在闭包中指定动做,一旦请求完成,完成处理程序将被调用,并将回应做为参数传递,在闭包中,咱们调用前面建立的speechAndText(text: )
方法来讲出并显示回应内容,若是response显示失败,咱们只需将其打印到logs便可。
剩下最后一件事,咱们尚未发起对API.AI的request,为此,咱们调用enqueue
函数并放入指定request,这能够经过使用下面代码来完成:
ApiAI.shared().enqueue(request) messageField.text = ""
咱们将请求发送到API.AI并清除textfield中的文字,你的整个sendMessage
方法应该以下所示
@IBAction func sendMessage(_ sender: Any) { let request = ApiAI.shared().textRequest() if let text = self.messageField.text, text != "" { request?.query = text } else { return } request?.setMappedCompletionBlockSuccess({ (request, response) in let response = response as! AIResponse if let textResponse = response.result.fulfillment.speech { self.speechAndText(text: textResponse) } }, failure: { (request, error) in print(error!) }) ApiAI.shared().enqueue(request) messageField.text = "" }
是时候了!如今运行应用程式(在iPhone X上),一切都应该按预期工做!
chatbot-demo-hotel-booking
本教程包含不少的资讯,但愿对读者会是很是有益的,那么,接下来你应该作什么?我会建议你继续扩展这个机器人,甚至建立你本身的机器人,期待你分享如何建立本身的机器人,欢迎发表在下面的评论!
以供参考,你能够在Github下载完成的项目。
关于Dialogflow的更多资讯,你你能够参考他们的documentation。
勇敢大胆的尝试吧!你能够在Dialogflow上建立本身的聊天机器人,并把它放在Google Assistant上。若是你想尝试一下,请查看这个影片,能够打开Google Assistant并透过”Talk to Max the Programmer”来测试我用Dialogflow製做的聊天机器人!鼓励你们继续研究Dialogflow,由于你能够在Google Assistant,Alexa,Twitter,Cortana,Facebook Messenger,Telegram等平台部署聊天机器人!
原文:Building a Chatbot App for iOS with Dialogflow (API.AI) and Text-to-Speech
简宝玉写做群日更打卡第 29 天