[聚合文章] Watson Conversation 服务,第 1 部分: Watson Conversation 对话原理以及高级应用

.Net 2018-01-03 18 阅读

Watson Conversation 服务,第 1 部分

Watson Conversation 对话原理以及高级应用

曾 滔

2018 年 1 月 03 日发布

系列内容:

此内容是该系列 # 部分中的第 # 部分: Watson Conversation 服务,第 1 部分

https://www.ibm.com/developerworks/cn/views/global/libraryview.jsp?sort_by=&show_abstract=true&show_all=&search_flag=&contentarea_by=%E6%89%80%E6%9C%89%E4%B8%93%E5%8C%BA&search_by=Watson+Conversation+%E5%AF%B9%E8%AF%9D%E5%8E%9F%E7%90%86%E4%BB%A5%E5%8F%8A%E9%AB%98%E7%BA%A7%E5%BA%94%E7%94%A8&product_by=-1&topic_by=-1&type_by=%E6%89%80%E6%9C%89%E7%B1%BB%E5%88%AB&ibm-search=%E6%90%9C%E7%B4%A2

敬请期待该系列的后续内容。

此内容是该系列的一部分: Watson Conversation 服务,第 1 部分

敬请期待该系列的后续内容。

IBM 云平台提供了认知计算的解决方法,其中 Watson Conversation 提供了构建聊天机器人的服务,本系列文章主要介绍了 Conversation 服务中的 dialog 的原理以及高级应用构建。

Watson Conversation 对话介绍

对话功能是 Watson Conversation 里的又一特点,对话与简单的 QA 问答不太一样,它是一个系列的对话组合,并且要理解上下文,而如何定义一个对话,以及如何理解上下文是 Watson Conversation Dialog 的处理重点。对话系统是根据用户输入的意图和实体,根据上下文与用户交互,并返回用户有用的信息。 Watson 返回给用户的结果可能是类似于"where can I get some gas?"的结果或者是一些类似于命令的执行,比如"打开收音机"。意图和实体的丰富程度决定了 Watson 回答问题的准确程度,或者 Watson 通过与用户的更多交互来自我学习,使机器越来越智能。例如:一个用问: "Where can I get some food?" ,你需要明确是需要找一个餐厅还是找一个快餐店打包。

对话框概览

对话通过一个树形结构来标示逻辑关系的。一个分支表示一个意图。分支由对话节点、对话流等内容构成:

对话节点

每一个对话节点至少包括一个条件和一个返回内容。

图 1. 对话节点示意图 1

我们可以把上面的条件和返回内容看成是 if / then 的形式,如果条件为真,就返回内容。

例如,当用户输入的内容通过 NLP 处理后包含 #cupcake-menu 意图就会触发以下节点。

图 2. 对话节点示意图 2

一个条件和返回内容的单节点可以处理简单的内容。但是更多的时候并不是这样,用户有更多复杂的请求内容,此时我们需要新增更多的子节点来满足问题的复杂性处理。

图 3. 对话节点示意图 3

对话流

对话流的处理流程如下:

图 4. 对话流示意图 1

当它沿树向下行时,如果服务找到满足的条件,它将触发该节点。 然后,它在触发节点上从左到右移动,以针对任何子节点条件检查用户输入。 当它检查子节点时,它会从上到下再次移动。

服务继续通过对话框从上到下,从左到右,从上到下,从左到右,直到它到达分支中的最后一个节点。

图 5. 对话流示意图 2

当您开始构建对话框时,必须确定要包括的分支以及放置它们的位置。 分支的顺序很重要,因为节点是从上到下进行评估。 使用条件匹配输入的第一个基本节点; 任何树中较低的节点都不会被触发。

条件

节点条件确定会话中是否使用该节点。 响应条件决定向用户显示哪个响应。 您可以使用任何组合中的一个或多个以下工件来定义条件:

  • 上下文变量:如果您指定的上下文变量表达式为 true,则使用该节点。 使用语法 $variable_name:value or $variable_name == 'value';
  • 实体:当在用户输入中识别实体的任何值或同义词时,将使用该节点。 使用语法 @{entity_name};
  • 实体值:如果在用户输入中检测到实体值,则使用该节点。 使用语法 @ {entity_name} : {value} 。 为实体指定一个定义的值,而不是同义词。如果您检查对等节点中的关联实体,请确保将检查此特定实体值的节点放在其上。
  • 意图:最简单的条件是单一意图。 如果用户的输入映射到该意图,则使用该节点。 使用 sytnax#{intent-name}。 例如,#weather 检查用户输入中检测到的意图是否为天气。 如果是,则处理该节点。
  • 特殊条件:可用于执行常用对话功能的服务提供的条件。

特殊条件内容描述

条件名 描述
anything_else 您可以在对话框的末尾使用此条件,当用户输入与任何其他对话框节点不匹配时进行处理。 任何其他节点由此条件触发。
conversation_start 在第一个对话转弯期间,这个条件被评估为真。 与欢迎不同,无论应用程序的初始请求是否包含用户输入都是真实的。 具有 conversation_start 条件的节点可用于初始化上下文变量或在对话框开头执行其他任务。
false 这个条件总是被评估为 false。 您可能会在正在开发中的分支的顶部使用它,以防止它被使用,或者作为提供通用功能的节点的条件,并且仅用作跳转到动作的目标。
irrelevant 如果用户的输入被确定为与会话服务无关,则此条件将被判定为真。
true 这个条件总是被评估为真。 您可以在节点或响应列表的末尾使用它来捕获与以前任何条件不匹配的任何响应。
welcome 在第一个对话框转换(对话开始时),只有来自应用程序的初始请求不包含任何用户输入时,此条件被评估为真。 在随后的对话转弯中,它被评估为 false。 Welcome 节点由此条件触发。 通常,具有该条件的节点用于向用户打招呼,例如,显示诸如"欢迎来到我们的比萨订购应用程序"的消息。

条件语法

使用以下语法选项之一在条件中创建有效的表达式:

Spring Expression (SpEL) language : 它是一种表达式语言,支持在运行时查询和操作对象图。 有关更多信息,请参阅 http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html

指向意图,实体和上下文变量的简短符号。 请参阅 https://console.bluemix.net/docs/services/conversation/expression-language.html

使用正则表达式检查。 例如 , 要找到匹配的字符串,可以使用 String.find 方法。 有关详细信息,请参阅方法

条件使用提示

  • 如果仅评估实体类型的第一个检测到的实例的值,则可以使用语法 @entity == 'specific-value' 替换  @entity:(specific-value) 格式。例如,当您使用 @appliance ==' 空调 ' 时,您只评估第一个检测到的 @appliance 实体的值。 但是,使用 @appliance :( 空调)扩展到实体 ['appliance'] ,包含( " 空调 " ),只要在用户输入中检测到至少一个价值 " 空调 " 的 @appliance 实体就匹配。
  • 使用数值变量时,请确保变量有值。 如果变量没有值,则在数值比较中将其视为空值(0)。 例如,如果您检查条件@price <100 的变量的值,并且@price 实体为空,则该条件将被计算为 true,因为 0 小于 100,即使价格未设置。 为了防止检查 null 变量,请使用@price AND @price <100 等条件。如果@price 没有值,则此条件正确返回 false。
  • 如果您使用实体作为条件并启用了模糊匹配,则只有匹配的置信度大于 30%时,@entity_name 才会计算为真。 也就是说,只有当@ entity_name.confidence> .3。

响应

简单文本响应

如果要提供文本响应,只需输入您希望该服务向用户显示的文本。

图 6. 简单文本响应示意图

增加变量

如果您的用户经常返回您的对话服务,每次听到同样的问候和回答。 您可以向响应添加变体, 他们可能会感到无聊, 以便您的对话可以以不同的方式响应相同的条件。

图 7 . 添加变量界面

在这个例子中,服务提供的响应关于商店位置的问题的答案不同于一个交互到下一个:

图 8. 添加变量示意图

您可以选择按顺序或随机顺序返回响应变体。 默认情况下,响应顺序返回 ,就像从有序列表中选择一样。

多重条件响应

单个对话节点可以提供不同的响应,每个响应由不同的条件触发。 使用此方法来解决单个节点中的多个场景。

图 9. 多重条件响应界面

节点仍然具有主要条件,这是使用节点并处理其所包含的条件和响应的条件。

在此示例中,服务使用先前收集的关于用户位置的信息来定制其响应,并提供关于最靠近用户的商店的信息。 有关如何存储从用户收集的信息的更多信息,请参阅上下文变量。

图 10. 多重条件响应示意图

此单节点现在提供了四个独立节点的等效功能。

复杂响应

要指定更复杂的响应,可以使用 JSON 编辑器在"输出":{}属性中指定响应。

要在响应中包含上下文变量值,请使用语法 $ variable-name 来指定它。 有关更多信息,请参阅上下文变量

图 11. 复杂响应 1

要指定要在不同行上显示的多个语句,请将输出定义为 JSON 数组。

图 12. 复杂响应 2

第一句显示在一行,第二句显示为下面的新行。

要实现更复杂的行为,可以将输出文本定义为复杂的 JSON 对象。 例如,您可以使用 JSON 输出中的复杂对象来模拟将响应变体添加到节点的行为。 您可以在复杂对象中包含以下属性:

  • value:一个 JSON 数组的字符串,其中包含该对话框节点可以返回的输出文本的多个版本。 返回数组中的值的顺序取决于属性 selection_policy。
  • selection_policy: 以下值有效
  • random: 系统从值数组中随机选择输出文本,不会连续重复。 例如,考虑包含三个值的 output.text。 对于前三次,选择随机值,但不会再次重复。 在给出所有输出值之后,系统随机选择另一个值并重复该过程。

图 13. 复杂响应 3

系统从随机选择的这三个选项返回一个问候语。下一次触发响应时,会显示列表中的另一个问候语。

Sequential: 系统在第一次触发对话框节点时返回第一个输出文本,第二次输出文本第二次触发该节点,依此类推。

图 14. 复杂响应 4

Append: 指定是追加数组还是使用新值或值覆盖数组中的值。 当设置为 false 时,先前执行的对话框节点中收集的输出将被该特定节点中指定的文本值覆盖。

图 15. 复杂响应 5

在这种情况下,所有其他输出文本将被此输出文本覆盖。

默认行为为 selection_policy = random 和 append = true。 当值数组包含多个项目时,从其元素中随机选择输出文本。

定义 what to do next

作出指定的响应后,您可以指示服务执行以下操作之一:

  • Wait for user input: 该服务等待用户提供响应引发的新输入。 例如,响应可能会询问用户是是或否。 在用户提供更多输入之前,该对话框将不会进行。
  • Jump to another dialog node: 当您想绕过等待用户输入并希望会话直接进入子节点或完全不同的对话框节点时,请使用此选项。 例如,您可以使用"跳转到动作"将流从树中的多个位置路由到公共对话框节点。

配置 Jump to another dialog node

如果您选择跳转到另一个节点,则必须指定该操作是针对所选对话框节点的响应还是条件:

响应:如果语句指向所选对话框节点的响应部分,则会立即运行。 也就是说,系统不评估所选对话节点的条件部分并立即运行所选对话节点的响应部分。忽略响应对于将多个对话节点链接在一起很有用。 处理所选对话框节点的响应部分,就好像该对话框节点的条件为真。 如果所选择的对话框节点具有另一个"跳转到"动作,该操作也将立即运行。

条件:如果语句指向所选对话节点的条件部分,则服务首先检查目标节点的条件是否计算为 true。

  1. 如果条件计算结果为 true,则系统通过使用对话框节点上下文更新上下文,并通过对话节点输出输出来立即处理此节点。
  2. 如果条件不为真,则系统继续对目标对话节点的下一个兄弟节点的条件的评估过程等等,直到找到具有评估为真的条件的对话节点。
  3. 如果系统处理所有兄弟姐妹,并且没有条件评估为真,则使用基本的回退策略,并且对话框也评估顶层的节点。
  4. 定位条件对于链接对话节点的条件很有用。 例如,您可能希望首先检查输入是否包含意图,例如#turn_on,如果是,则可能需要检查输入是否包含实体,例如@lights,@radio 或@wipers。 链条件有助于构建更大的对话树。

上下文变量

对话框是无状态的,这意味着它不会将信息从用户的一个交换中保留到下一个。 您的应用程序负责维护所需的任何持续信息。 但是,应用程序可以将信息传递给对话框,对话框可以更新此信息并将其传递给应用程序。 它通过使用上下文变量来实现。

上下文变量是您在节点中定义的变量,并且可选地为其指定默认值。 其他节点或应用程序逻辑可随后设置或更改上下文变量的值。

您可以通过从对话框节点条件引用上下文变量来判断上下文变量值,以确定是否执行节点。 您可以从对话框节点响应条件引用上下文变量,以根据外部服务或用户提供的值显示不同的重复次数。

从应用程序传递上下文

通过设置上下文变量并将上下文变量传递给对话框,将信息从应用程序传递到对话框

例如,您的应用程序可以设置 $ time_of_day 上下文变量,并将其传递给可以使用该信息来定制向用户显示的问候语的对话框。

图 16. 例子

在此示例中,对话框知道应用程序将变量设置为以下值之一:上午,下午或晚上。 它可以检查每个值,并根据存在的值返回适当的问候语。 如果变量未被传递或者具有与预期值不匹配的值,则向用户显示更通用的问候语。

传递上下文从节点到节点

对话框还可以添加上下文变量,以将信息从一个节点传递到另一个节点,或更新上下文变量的值。当对话框询问并从用户那里获取信息时,它可以跟踪信息,并在会话中稍后参考。

例如,在一个节点中,您可能会询问用户的姓名,并在稍后的节点中按名称对它们进行寻址。

图 17. 例子

在本示例中,系统实体 @ sys-person 用于从用户提供用户的名称中提取用户名。 在 JSON 编辑器中,用户名上下文变量被定义并设置为@ sys-person 值。 在后续节点中,$ username 上下文变量包含在响应中,以按名称对用户进行寻址。

定义上下文变量

通过向 JSON 对话框节点定义的{context}部分添加名称和值对来定义上下文变量。 配对必须符合以下要求:

该名称可以包含任何大小写字母字符,数字字符( 0-9),下划线和句点。

该值可以是任何支持的 JSON 类型,例如简单的字符串变量,数字,JSON 数组或 JSON 对象。

以下 JSON 示例定义 $ dessert 字符串 $ toppings_array 数组和 $ age 数字上下文变量的值:

图 18. 上下文变量 1

要定义上下文变量,请完成以下步骤:

  1. 从节点的编辑视图中,通过单击高级响应图标,然后选择 JSON 来打开 JSON 编辑器。
  2. 在"output":{}块的前方,如果不存在,则添加一个"context":{}块。

图 19. 上下文变量 2

3. 在上下文块中,为要定义的每个上下文变量添加名称和值对。

图 20. 上下文变量 3

要引用上下文变量,请使用语法 $ name,其中 name 是您定义的上下文变量的名称。

其他常见任务包括:

1. 要存储用户输入的整个字符串,请使用 input.text:

图 21. 上下文变量 4

2. 要将实体的值存储在上下文变量中,请使用以下语法:

图 22. 上下文变量 5

3.要在上下文变量中存储通过使用正则表达式从用户输入中提取的字符串的值,请使用以下语法:

图 23. 上下文变量 6

操作顺序

您定义上下文变量的顺序不会确定服务对其进行评估的顺序。 该服务以随机顺序评估被定义为 JSON 名称和值对的变量。 不要在第一个上下文变量中设置一个值,并希望能够在第二个上下文中使用该值,因为不能保证列表中的第一个上下文变量将在列表中的第二个上下文之前执行。 例如,不要使用两个上下文变量来实现逻辑,该逻辑返回零和传递给节点的较高值之间的随机数。

图 24. 例子

使用稍微更复杂的表达式,以避免在评估 $ answer 上下文变量之前,必须依赖于 $ upper 上下文变量的值。

图 25. 例子

更新上下文变量值

如果一个节点设置已经设置的上下文变量的值,那么先前的值将被覆盖。

  • 更新上下文 jason 对象

除了 JSON 对象之外,所有 JSON 类型的以前的值都将被覆盖。 如果上下文变量是复杂类型,例如 JSON 对象,则使用 JSON 合并过程来更新变量。 合并操作会添加任何新定义的属性,并覆盖对象的任何现有属性。

在此示例中,名称上下文变量定义为复杂对象。

图 26. 例子

对话框节点使用以下值更新上下文变量 JSON 对象:

图 27. 例子

结果是这个上下文:

图 28. 例子

  • 更新阵列

如果您的对话框上下文数据包含一组值,则可以通过附加值,删除值或替换所有值来更新数组。

选择其中一个操作来更新数组。 在每种情况下,在应用操作之后,我们会看到操作之前的数组,操作和数组。

  • Append : 要将值添加到数组的末尾,请使用 append 方法。

对于此对话框运行时上下文:

图 29. 例子

更新

图 30. 例子

结果

图 31. 例子

  • Remove

删除元素,使用 remove 方法并在数组中指定其值或位置。

Remove by value 从数组中删除一个元素的值。

对于此对话框运行时上下文:

图 32. 例子

更新

图 33. 例子

结果

图 34. 例子

Remove by position 通过索引位置从数组中删除元素:

对于此对话框运行时上下文:

图 35. 例子

更新

图 36. 例子

结果

图 37. 例子

Overwrite要覆盖数组中的值,只需将数组设置为新值即可:

对于此对话框运行时上下文:

图 38. 例子

更新

图 39. 例子

结果

图 40. 例子

Attention 如果将数组保存为字符串的一部分,则它将成为 String 对象而不是 Array。 例如,以下$ array 上下文变量是一个数组,但是 $ string_array 上下文变量是一个字符串。

图 41. 例子

如果您在"尝试出来"窗格中检查这些上下文变量的值,您将看到它们的值如下指定:

$array  :  ["one","two"]  
  $array_in_string  :  "this is my array:
                        [\"one\",\"two\"]"

您可以随后对 $数组变量执行数组方法,例如<? $ array.removeValue('two')?>而不是$ array_in_string 变量。

本文是 Watson Conversation 对话原理以及高级应用的第一部分,介绍了对话框、节点的使用条件和文本响应的内容。Watson Conversation 对话原理以及高级应用的第二部分将向您介绍如何创建一个复杂对话、用 slot 收集信息和创建一个 pizz 购买店的实战案例。

参考资源

阅读本文之前,需要建立对于 AI 的基础知识,并且对于 IBM Watson 的使用场景需要有一定掌握。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。