IBM Watson 为认知技术提供了强大的平台,它具备理解,学习和推理能力,实现更智能的人机互动,帮助人们做更好的决策。IBM Watson 广泛应用于认知商业,通过获取海量数据,利用数据以及和人的交互进行学习,结合具体的商业应用场景,从海量数据中洞察问题,帮助解决商业问题,给企业提供商业预测以及更好的决策。
本文着重介绍 IBM Watson Dialog Service 的应用, 开发者可以通过调用 RESTful API 方式构建自动生成用户和应用之间对话的平台,该服务帮助应用软件使用自然语言,用与人类极其相近的对话和客户交互,应用在各式各样的场景,比如:提供产品建议以及支持,指引客户购买产品,实时回答问题等等。原理在于 Dialog service 可以跟踪并且存储用户信息去学习他们的行为,性格,在不同的场景下,根据用户提出的问题或者提供的信息作出智能反馈。
在页面右侧添加服务,在 Service name 选项中填写名称,其余选项可使用默认值。填完信息后点击 Create 按钮进行创建。如图 2 所示。
复制您的 Dialog service 凭证。创建完 service 之后,请在页面左侧凭证信息中复制您的用户名和密码,在开发代码在使用。凭证信息参考图 3.
完成以上几步就可以开始开发工作了。
Dialog Service 的对话流程必须通过 XML 文件来定义,然后通过调用创建 Dialog 的 API 来上传 XML 并生成一个 dialog。另外,Dialog Service 还提供了一些 API 来更新、删除 dialog,创建会话,获取会话历史以及获取、设置变量值。本章节讲介绍 XML 的基本格式和语法,Dialog service API 在本文中不会详细介绍,可以参考: https://watson-api-explorer.mybluemix.net/apis/dialog-v1#!/Conversation/obtainResponse
清单 1 中定义了一个最基本的 XML 文件。XML 文件最外层是一个 dialog 标签,dialog 标签里面创建一个 flow 标签,flow 标签里面定义了所以对话的流程。flow 标签里面可以创建几个 folder 标签,用来根据不同的功能分开定义对话流程。其中,main folder 是必须创建的,这里定义了初始化输出(创建 conversation 时,输出给用户的第一句话),以及默认输出(无法理解用户输入是时候,输出的内容)。另外,library folder 一般给用户自定义对话流程,concepts folder 用来定义 concept。XML 所有标签的语法和意义可以参考:
https://www.ibm.com/smarterplanet/us/en/ibmwatson/developercloud/doc/dialog/reference_nodes.shtml
<dialog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="WatsonDialogDocument_1.0.xsd"> <flow> <folder label="Main" id="Main"></folder> <folder label="Library" id="Library"> <folder label="Live Content" id="Live Content"></folder> <folder label="Storage" id="Storage"></folder> </folder> <folder label="Concepts" id="Concepts"></folder> </flow> </dialog>
清单 2 列出了 main folder 的格式和语法。其中,第一个 output 标签中的 Hello, I'm your shopping assistant. What do you need? 是创建对话时候,输出的第一句话,用来提示用户这个 dialog service 的作用。另外,default 标签里面的 I don’t understand it. 是在 dialog service 无法理解用户输入时,输出的内容,用来提示用户输入可能没有在此 Dialog 的 XML 文件中定义。
<folder label="Main"> <output id="output_main"> <prompt selectionType="RANDOM"> <item>Hello, I'm your shopping assistant. What do you need?</item> </prompt> <goto ref="getUserInput_000000"/> </output> <output> <prompt selectionType="RANDOM"> <item>Do you need any other thing?</item> </prompt> <getUserInput id="getUserInput_000000"> <search ref="folder_000001"/> <default> <output> <prompt selectionType="RANDOM"> <item>I don't understand it.</item> </prompt> </output> </default> </getUserInput> </output> </folder>
清单 3 中定义了一组输入输出对,当用户输入是 What type of computers do you have? 时候,dialog service 就会输出 We have Dell, IBM and HP. 由于$是通配符,当用户输入 David,what type of computers do you have? 时候也会有同样输出。通过迭代定义,在 output 里面再定义 input 的方式,可以创建一系列的会话流程。
<folder label="Library"> <folder label="Live Content"> <input> <grammar> <item>What type of computers do you have?</item> <item>$ what type of toppings do you have?</item> </grammar> <output> <prompt selectionType="RANDOM"> <item>We have Dell, IBM and HP.</item> </prompt> </output> </input> </folder> </folder>
清单 4 中是一个 Dialog service 的完整实例,定义了一个智能导购的角色,当用户需要购买一台电脑的时候,智能导购会询问用户一些关键的属性,比如电脑品牌、屏幕尺寸、使用者性别等问题。Dialog service 中定义了整个对话流程,并记录用户回答的问题。若进一步开发,可以通过这些属性到商品库中进行搜索,推荐某几个商品给用户。
<dialog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="WatsonDialogDocument_1.0.xsd"> <flow> <folder label="Main">(此处参考清单 2)</folder> <folder label="Library" id="Library"> <folder label="Live Content" id="folder_000001"> <input> <grammar><item>$ computer</item></grammar> <goto ref="output_computer_connect_type"/> </input> </folder> <folder id="folder_computer_connect_type"> <output id="output_computer_connect_type"> <prompt selectionType="RANDOM"> <item>What brand of computer do you link?</item> <item>What is the brand?</item> </prompt> <getUserInput> <input> <grammar><item>$ (entity_attr1)={var_attr1}</item></grammar> <action varName="var_attr1" operator="SET_TO">{var_attr1.value:main}</action> <goto ref="output_computer_size"/> </input> </getUserInput> </output> </folder> <folder id="folder_computer_size"> <output id="output_computer_size"> <prompt selectionType="RANDOM"> <item>What's screen size?</item> </prompt> <getUserInput> <input> <grammar><item>$ (entity_attr2)={var_attr2}</item></grammar> <action varName="var_attr2" operator="SET_TO">{var_attr2.value:main}</action> <goto ref="output_computer_gender"/> </input> </getUserInput> </output> </folder> <folder id="folder_computer_gender"> <output id="output_computer_gender"> <prompt selectionType="RANDOM"> <item>Do you want to specify gender?</item> </prompt> <getUserInput> <input> <grammar><item>$ no</item></grammar> <action varName="var_attr3" operator="SET_TO">Not set</action> <goto ref="folder_computer_connector_pins"/> </input> <input> <grammar> <item>$ (entity_attr3)={var_attr3}</item> </grammar> <action varName="var_attr3" operator="SET_TO">{var_attr3.value:main}</action> <goto ref="folder_computer_recommend"/> </input> </getUserInput> </output> </folder> <folder id="folder_computer_recommend"> <output> <prompt selectionType="RANDOM"> <item>Here is your choice: </item> </prompt> <goto ref="output_attrs"/> </output> <output id="output_attrs"> <prompt selectionType="RANDOM"> <item>Connect type:{var_attr1}, Screen size:{var_attr2}, Gender type:{var_attr3}.</item> </prompt> </output> </folder> </folder> </flow> <variables> <var_folder name="Home"> <var name="var_attr1" type="TEXT" description=""/> <var name="var_attr2" type="TEXT" description=""/> <var name="var_attr3" type="TEXT" description=""/> </var_folder> </variables> <entities> <entity name="entity_attr1"> <value name="Lenovo" value="Lenovo"/> … …(可以添加更多类似定义) </entity> <entity name="entity_attr2"> <value name="19 inch" value="19 inch"/> … …(可以添加更多类似定义) </entity> <entity name="entity_attr3"> <value name="Male" value="Male"/> <value name="Female" value="Female"/> </entity> </entities> </dialog>
XML 文件中可以在<variables>定义该 dialog 使用的变量,例如:<var name="var_attr1" type="TEXT" description=""/> 可以通过提取用户输入信息给变量赋值,也可以通过直接调用 Dialog service 提供的 API 给变量赋值。
Entity 用来匹配和提取用户输入中的一些信息,可以通过定义一系列 entity 值,进而避免在 input 节点中定义一大堆的用户输入。例如定义:
<entity name="entity_attr1"> <value name="Lenovo" value="Lenovo"/> <value name="Dell" value="Dell"/> <value name="IBM" value="IBM"/> </entity>
所有 Lenovo、Dell 和 IBM 都属于 entity_sttr1 这个实体。
那么在定义 input 节点的时候:
<item>(entity_sttr1)<item>
等同于:
<item>Lenovo <item> <item>Dell<item> <item>IBM<item>
Demo 实例中一个定义:<item>$ (entity_attr1)={var_attr1}</item> 该定义是用来判断用户输入是否符合$ (entity_attr1) 定义(由于$是通配符,只要用户输入中有 entity_attr1 中定义得实体,就算匹配成功)。如果符合,就将该实体的信息复制给 var_attr1 这个变量值。例如:当用户输入是 I want IBM computer,那么 IBM 实体的相关信息 (主要包括 value 和 name) 就会赋值给 var_attr1。
Action 标签用来给变量赋值,例如:<action varName="var_attr1" operator="SET_TO">{var_attr1.value:main}</action>,就是将 var_attr1.value:main 的值复制给 var_attr1 变量。其中,var_attr1.value:main 是匹配到的实体对应的 value 值。
Dialog Service 提供了很多 API 来管理和操作 dialog 和会话。同时,为了进一步方便管理和使用 dialog,dialog service 的开发团队还提供了一个 dialog service tool 来可视化管理 dialog 和进行会话。该工具通过 node.js 开发,可以通过下面这个地址下载,参照工程中的 Readme.md 文件进行部署。部署成功以后,通过浏览打开管理界面,如图 4 所示。
下载地址: https://github.com/watson-developer-cloud/dialog-tool
将 Demo 实例中的代码保存到 dialog.xml 文件中,点击加号上传该 xml 文件。如果定义中没有语法问题,就会出现该 dialog 对应的卡片。如图 5 所示的。如果定义中有语法错误,会有红色的错误提示语,根据错误提示语定位到 xml 文件中进行修改。
点击卡片,就可以创建一个会话,如图 6 所示。会话的第一句话就是 xml 中定义的初始化输出内容。可以在聊天框中输入任何语句,点击 send 提交给 dialog service。Dialog service 会根据 xml 中定义的输入输出对,来搜索对应的 output 输出给用户。当用户输入的内容该 dialog 无法理解的时候,会返回 xml 中定义的默认输出值。一个完整的对话流程参考图 7。
此外,IBM Watson Dialog service 官方网站提供了很全面的教程以及案例,初次使用参考指南tutorial可以清楚的了解如何使用 dialog 的元素。有了初步的了解之后,除了通过本文的讲解开始开发工作,还可以参考 Watson 提供的示例应用 What's in Theaters ,阅读其源代码可有效帮助开发人员构建完整应用。当然,您还可以通过 GitHub 上的其他案例 sample Node.js code on GitHub 学习 Dialog service 的使用。开发过程中,需要查看所有元素请查阅all elements。
综上,Dialog service 为客户提供简易,友善的人机交互体验,为开发人员提供方便健壮的 API,使开发人员更好的专注在业务逻辑以及应用代码的开发。Bluemix 为认知计算提供的可快速开发,部署和管理应用的平台,更是开发者爱不释手的宝贝,同时使得最大受益者客户得到最佳的体验。Bluemix 日渐壮大的服务为认知技术提供更丰富以及更具有创造性的舞台。