# 对话流

# 对话分支

一个对话结构一般都会设计成一个树状的流结构,这里的每个故事就是一个真正的对话示例,在每个故事的底部,点击 Branch Story 按钮试试看:

以下几个时间可以作为一个对话分支的开始:

  • 每个来自用户的会话(包含意图和实体)
  • slots (有上下文)

# 根据意图做对话流分支

会话分支最常见的情况是针对不同的意图做不同的分支处理,参考下面这个例子中关于 happysad 两个分支的实现:

# 根据实体做对话流的分支

另一种针对对话流分支的情况是针对不同的实体做分支,你可以先看下如何在对话中针对实体做标注.

试想这样一个例子:用户可以要求预定 eco 或者 business 类型,如果没有明确说明的意图由默认的逻辑处理,实现方式如下:

注意!不能这么做

按上面的操作步骤训练并测试一下,你会发现当你输入 /book 机器人会像预期一致的返回 utter_which_class,但当你输入 /book{"class":"eco"} 或者 /book{"class":"business"} 时,你会发现回复的内容是随机的!这是因为这个意图的值还没有被保存,Rasa 只针对这个意图的 class 是否在用户会话中出现来决定对话的分支。

要让上面的例子起作用,你需要 创建一个 slot,在本例中我们创建一个名为 categorical 的 slot,然后添加两个分类,分别叫 businesseco,重新训练,然后就一切正常了。

Categorical slot

# 根据槽做对话流的分支

一旦你定义了一个跟实体名字一样的槽,所有从用户会话中解析出来的这个实体值都会被填充到这个槽里面,而且这个槽的值在该会话周期中会一直存在,除非它被显式修改或者重置。比如上面的例子中,无论用户说的是 I want to book in economy book{"class":"eco"} 还是 I want to book in businessbook{"class":"business"}, 你都能根据槽信息进行对话流的分支处理。

用例: 用户想取消预订,但只取消 business 房间,你就可以想下面这样子实现对话流分支:

如你所见,- slot{"class":"..."} 槽决定了对话流的走向。

如果相关的 class 还没有赋值会怎样...

这种情况下你可以添加一个名为 not_set 的类别到 class 槽里,并把它的值初始化为 not_set ,这样,当出现没有设定的类别分支时流程就会走到这里,问题解决!

# 对话分支是如何处理的

底层实现上,Botfront 用的是 Rasa 的 checkpoints 机制,当你点击 branch story 的时候,父故事和子故事会被 checkpoints 无缝的连接起来,无需前台做处理。

# 根据其它特性做对话流分支

在每个故事底下的面包屑导航部分都明确的标明了你当前所在的分支。

Branching breadcrumbs

对分支的添加是没有上限的,你可以根据需要任意添加、重命名分支。

如果要删除一个分支,只需简单的点击后面的垃圾桶图标即可:

注意

删除最后两个分支中的一个同时也会自动删除另一个,另一个分支中的内容会自动添加到父故事中去。

# 关联故事

故事之间的连接是解决故事内容重复的一个非常有效的手段,而且为不同的故事创建连接也很简单,你只要简单的在故事栏右下角选一个故事作为目标故事就可以了,任何一个故事都可以被连接到另一个故事或者被其他故事连接,这个特性在一些需要经常重复的对话流中特别有用,比如在很多故事里面,最后都需要加一个 feedback 流。

当一个故事被别的故事连接,在这个故事的编辑框顶部会出现一个小黄条,用以提示连接关系。

点一下小黄条会列出所有已连接的故事。

目标故事在它所连接的故事删除之前不能被删除:

分支逻辑也会自动被连接到设定的目标故事。

提示

过多的使用连接会导致你的故事线变复杂,降低可阅读性。而且过多的使用连接故事还有可能导致训练时间变长。

# 关联一个故事到它本身

只有为一个故事创建了对话分支之后才可以把这个故事连接到它自身,比如说,你在某个场景里面创建了一个菜单对话,这个菜单的最后一个选项是 "go back" 到该故事逻辑的最开始处。 虽然这样,当我们想把一个故事连接到它自身的时候,这个故事还是需要首先被别的故事连接才行,比如被一个对话流的开场故事作为目标故事,如果不是这样,就无法使用这个特性。

下面是一个带开场故事的典型的示例(菜单逻辑):

Self linking schema

一个简单的自连接故事:

# 故事关联的工作原理

跟对话流分支的原理一样,Botfront 也是用 Rasa 的 checkpoints 机制 实现了故事之间的连接,当你点击 Link to 按钮的时候,源故事和目标故事通过 checkpoints 被无缝的连接在一起,有一点需要注意,故事里面不支持 > checkpoints 特性。