讲清了一些最最基本的概念

Intents(意图)Entities(关键字)

基于意图(Intent-based)的对话 基于流程(Flow-based)的对话 

聊天机器人教学:使用Dialogflow (API.AI)开发 iOS Chatbot App

 

image

随著苹果Core ML的最新版本发佈,开发人员更容易构建人工智能应用程式,除了图像识别和文本检测是利用AI建置APP的好例子,另一种善于展现机器学习Power的应用程式类型则是chatbots。在本教程中,我们将使用Google的Dialogflow(以前称为API.AI)构建在iOS上运行的chatbot应用程式!

听起来很酷吧!接下来开始进入本教程的重点。

Intents(意图)和Entities(关键字)快速概览

在开始之前,我先解释Dialogflow和chatbots的一般基本知识。 在构建chatbots时,你必须知道两个术语:Intents(意图)Entities(关键字)

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代表名词。)

来看一个例子,在我们的项目中,可能会告诉我们的机器人以下声明:

“Book me a room at the La Grande Hotel”(替我在La Grande Hotel订一间房)

在这句话中,我们的intent(意图)是”预定一个房间”,entity(关键字)是”La Grande Hotel”,现在,自然语言处理(NLP)算法可以计算两种不同类型的对话内容。

  1. 基于意图(Intent-based)的对话:这是当NLP算法使用intents和entities进行对话时,通过识别用户声明中的名词和动词,然后与它的dictionary交叉引用,让bot可以执行有效的操作,这种类型的对话是Dialogflow使用的。
  2. 基于流程(Flow-based)的对话:基于流程的对话是智能通信的下一个级别。在这里,我们会给予两个人之间对话的许多不同样本的RNN(循环神经网络),创建的机器人将根据你训练的ML模型进行响应。Wit.ai是在这个领域取得巨大进展的少数网站之一,不用担心,我们不需要做到这个程度。

注意:如果想了解更多有关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

进入到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,如果你还记得,entities就像NLP算法可以理解的名词,拿出一个可能经常用于我们机器人的entities名单,我已经把我整理的list放在下面,并且随时可以添加它。

  • Hotel
  • Room
  • Payment

选择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

进入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

最后,让机器人回应一些确认讯息。以下是一些范例:

  • Done! You have rent the rooms!
  • Success! We received your payment.

就是这样!请记住保存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代码!

使用API.AI SDK连接到Dialogflow

现在我们移动到本教程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,已经有一个UILabelUIButtonUITextField,它们的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代理回应的任何内容,有两种可能性:successfailure,如果代理程序返回成功讯息,那么我们希望应用程式说出回应并将其显示在萤幕上,如果出现失败讯息,那么应用程式只是打印错误到控制台,我们可以通过使用下面的代码来实现:

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 天


Chatbot:的更多相关文章

  1. 检索式chatbot:

    小夕从7月份开始收到第一场面试邀请,到9月初基本结束了校招(面够了面够了T_T),深深的意识到今年的对话系统/chatbot方向是真的超级火呀.从微软主打情感计算的小冰,到百度主打智能家庭(与车联网? ...

  2. 所有selenium相关的库

    通过爬虫 获取 官方文档库 如果想获取 相应的库 修改对应配置即可 代码如下 from urllib.parse import urljoin import requests from lxml im ...

  3. java web 开发三剑客 -------电子书

    Internet,人们通常称为因特网,是当今世界上覆盖面最大和应用最广泛的网络.根据英语构词法,Internet是Inter + net,Inter-作为前缀在英语中表示“在一起,交互”,由此可知In ...

  4. 聊天机器人(chatbot)终极指南:自然语言处理(NLP)和深度机器学习(Deep Machine Learning)

    在过去的几个月中,我一直在收集自然语言处理(NLP)以及如何将NLP和深度学习(Deep Learning)应用到聊天机器人(Chatbots)方面的最好的资料. 时不时地我会发现一个出色的资源,因此 ...

  5. (转)Three challenges you’re going to face when building a chatbot

        转自:https://blog.infermedica.com/three-challenges-youre-going-to-face-when-building-a-chatbot/   ...

  6. 王垠:完全用Linux工作

    来自: Zentaur(alles klar) 录一篇旧文 作者:王垠 完全用Linux工作,抛弃windows 我已经半年没有使用 Windows 的方式工作了.Linux 高效的完成了我所有的工作 ...

  7. 智能机器人chatbot论文集合

    机器不学习 jqbxx.com-专注机器学习,深度学习,自然语言处理,大数据,个性化推荐,搜索算法,知识图谱 今年开始接触chatbot,跟着各种专栏学习了一段时间,也读了一些论文,在这里汇总一下.感 ...

  8. seq2seq-chatbot:200 行代码实现聊天机器人

    Chatbot in 200 lines of code CPU 跑不动 github:https://github.com/zsdonghao/seq2seq-chatbot 更多英文,中文聊天机器 ...

  9. 我用 tensorflow 实现的“一个神经聊天模型”:一个基于深度学习的聊天机器人

    概述 这个工作尝试重现这个论文的结果 A Neural Conversational Model (aka the Google chatbot). 它使用了循环神经网络(seq2seq 模型)来进行 ...

随机推荐

  1. 201871010113-刘兴瑞《面向对象程序设计(java)》第七周学习总结

    项目 内容 这个作业属于哪个课程 <任课教师博客主页链接> https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 <作业链接地址>htt ...

  2. AcWing 799. 最长连续不重复子序列

    网址  https://www.acwing.com/solution/AcWing/content/2069/ 题目描述给定一个长度为n的整数序列,请找出最长的不包含重复数字的连续子序列,输出它的长 ...

  3. ubuntu下使用redshift开启护眼模式

    前面提到flux这东西在一些机器上并不能work,而且也找到了一些关于他不能work的线索(戳这里看原因).根据这些线索我们发现用flux不行了,得换用redshift,那好吧,我们就来装redshi ...

  4. pytest框架优化——清理历史截图图片和allure报告文件

    痛点分析: 当我们每次执行完用例的时候,如果出现bug或者是测试脚本出了问题,一般会通过测试报告.异常截图.日志来定位分析,但是我们发现运行次数多了之后,异常截图和测试报告会不停地增多,对我们定位分析 ...

  5. 使用os模块动态获取目录或文件路径

    在接口自动化测试框架中,我们的代码除了能在本地运行,也能在不在修改代码的前提下在其他的环境下能够运行,这样才能达到高复用性和低维护成本,我们在接口测试的模块调用中,会定义很多相关路径,而这些路径必须使 ...

  6. swoole中使用task进程异步的处理耗时任务

    我们知道,swoole中有两大进程,分别是 master 主进程和 manager 管理进程. 其中 master 主进程中会有一个主 reactor 线程和多个 reactor 线程,主要的作用就是 ...

  7. 这篇文章带你彻底理解synchronized

    本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取.传送门:h ...

  8. css精灵图&字体图标

    精灵图 为什么需要精灵图 为了有效的减少服务器接收和发送请求的次数,提高页面的加载速度.出现了CSS精灵技术 精灵图(sprites)的使用 精灵技术主要针对背景图片.就是把多个小背景图片整合到一张大 ...

  9. 多个浏览器下应用前端JS实现一键导出excel表

    自己试验了几种方法,找到一种较为全面的一种方式一键输出Excel表格,代码如下 <!DOCTYPE html> <html> <head lang="en&qu ...

  10. 关于OC中直接打印结构体(CGRectCGSize、CGPoint、UIOffset)等数据类型

    关于OC直接打印结构体,点(CGRect,CGSize,CGPoint,UIOffset)等数据类型,我们完全可以把其转换为OC对象来进项打印调试,而不必对结构体中的成员变量进行打印.就好比我们可以使 ...