NAV Navbar
  • 多轮对话设计器
  • 多轮对话设计器

    概述

    多轮对话设计器 (Conversation Designer)是以自然语言为输入,定义聊天机器人逻辑思维的工具。它可以很方便的通过Chatopera支持的脚本语法描述复杂的对话逻辑,并且通过函数的形式集成企业的其它服务。企业的业务人员可以很容易的学习脚本语法,制作满足企业业务需求的聊天机器人。

    多轮对话设计器是设计满足业务需求的对话机器人的PC端应用程序,现已支持Windows和Mac OSX平台。多轮对话能力是聊天机器人模仿人的对话能里的一大挑战,在复杂的上下文和需要很多背景知识的前提下,现有的人工智能技术是无能为力的,在Chatopera,我们相信在企业服务中,当话术或流程固定的情况下,依赖Chatopera的产品可以输出用对话完成任务的服务,比如用对话完成点餐、报销、请假。这些对话可以在企业的聊天工具中,也可以通过智能音箱的等其他客户端。

    安装

    仅支持Mac OSX和Windows操作系统。

    下载地址

    下载地址:

    版本 操作系统 下载
    v1.0.0 Mac OSX 链接
    v1.0.0 Windows 链接

    启动应用

    多轮对话设计器打开后页面
    多轮对话设计器打开后页面

    可能遇到的问题

    1. Macos上首次启动警告

    MacOS权限问题
    macos权限问题

    解决方案

    在应用中心,找到“多轮对话设计器”:

    应用中心
    应用中心

    选择“多轮对话设计器”并且右键:

    右键打开
    右键打开

    点击“打开”(“Open”)。

    快速开始

    下载安装包后,双击打开,进入安装向导。

    安装完打开应用图标后进入主面板,如下图:

    应用主面板
    应用主面板

    导入示例程序

    下载示例程序包文件:小叮当-1.0.0-conversations.c66

    https://github.com/chatopera/conversation-sampleapp

    示例程序下载地址
    示例程序下载地址

    在主面板点击界面的右上方的“导入”按钮,选择刚才下载的示例程序小叮当-1.0.0-conversations.c66如图:

    导入对话框
    导入对话框

    导入成功,可以看到在聊天机器人界面有一条数据显示,“名字 小叮当”等;点击小叮当的“管理”按钮,可以看到它的多轮对话列表,包括:chatopera,profile,weather。如下图:

    多轮对话列表
    多轮对话列表
    对话 功能
    chatopera 关于Chatopera的公司信息
    profile 机器人的画像
    weather 提供天气查询功能的对话

    测试示例程序

    可以针对上面的三个多轮对话,进行一番聊天测试,下面测试主要以“问天气”为例子。

    选择 “weather” 对话的编辑按钮,进入weather对话的编辑窗口,包括:

    概念 描述
    脚本 按照多轮对话语法规则来描述机器人对话逻辑
    函数 执行JavaScript代码的环境,声明的接口可以直接从脚本中调用
    日志 函数中debug方法的输出
    逻辑 聊天机器人的思维逻辑导图,保存脚本后自动生成
    对话 实时测试聊天机器人的窗口

    在“对话”区域的下方输入框输入:你知道哪些天气信息

    多轮对话编辑窗口
    多轮对话编辑窗口

    点击“发送”按钮,可以看到对话区域有了问答的信息流,并且“逻辑”区域也有了对话状态,对话路径显示“绿色”高亮。

    测试对话
    测试对话

    在此界面可以进行多轮对话测试,如下截图:

    多轮对话
    多轮对话

    增加新的对话

    测试新对话

    我:今天北京适合游玩么?
    机器人:风清气爽,当然可以啊~
    

    在脚本区域可以自行设计脚本,非常简单,例如增加:

    + 今天 (*) 适合游玩么?
    - 风清气爽,当然可以啊~
    

    点击界面上方“保存”按钮,会使得刚才定义的对话生效,并且可以在聊天区域直接测试。

    保存新版本

    刚才点击“保存”按钮时,同时将weather的对话生成一个快照,我们随时可以回退到某个快照。

    查看快照
    查看快照

    回到聊天机器人列表页面,可以点击“发布”按钮,可以将当前聊天机器人生成新版本,相关的信息如图:

    发布新版本
    发布新版本

    点击上图的“确认”按钮,发布新版本成功,点击“版本管理”,看到刚才发布的1.0.1版本的信息。

    各个版本之间比较

    对于聊天机器人的发布的各个版本差异,可以使用版本比较工具,比较具体的差异,包括:脚本比较和函数比较。 点击上图1.0.1对应的“对比差异”,可以“对比变化”界面,其中分为三个部分,

        - “左上”为被对比的参考版本;本例子为:1.0.0
    
        - “右上”为要对比的目标版本,本例子为:1.0.1
    
        - “下方”为两版本数据的差异,具体:
    
            * 绿色:新增的内容;
    
            * 红色:删除的内容;
    
            * 灰色:没有变化的内容;
    

    刚进入“对比变化”界面,默认对比的是:函数,本例子请在选择“版本号”的右边切换“脚本”为“对话”,如图:

    版本之间比较差异
    版本之间比较差异

    对比的差异部分为绿色,表示新增。

    导出特定版本

    多轮对话设计器属于设计阶段,在机器人满足需求后,可以导出为对话应用.c66文件,方便分发和部署。在生产环境,导入到智能问答引擎中,作为多轮对话应用的运行时。

    在“版本管理”界面,选择刚才发布的“1.0.1”的“导出”,可以选择一个路径存储该导出的文件,如图:

    导出文件
    导出文件

    脚本语法

    术语

    在正式介绍脚本语法前,我们先来认识下面的术语:

    概念 描述
    对话 满足设定需求的多轮对话
    输入 用户向聊天机器人发送的消息的文字形式
    触发器 匹配用户输入文字的字符串,可以声明槽位,当用户的输入发生时,会按照算法顺序匹配触发器
    回复 机器人回复用户输入的文字
    多轮对话 根据上一次回复的状态,声明下轮对话的优先匹配规则
    函数 可以从脚本中接受输入,并通过JavaScript执行任务返回结果的代码
    对话
    对话
        
    
    

    触发器

    触发器是对话的基础,当用户向聊天机器人发送一条消息时,机器人引擎会从所有定义的触发器中找到匹配的一个。在机器人引擎中,触发器用半角字符加号( + )表示。机器人的回答用半角字符减号( - )表示。

    例如,我们可以这样定义一个对话:

    + 晚饭吃什么
    - 北京烤鸭    
    

    注意:这里( + )和( - )和文字之间需要隔一个空格。

    槽位

    为了让触发器能适应复杂的需求,机器人引擎使用槽位规则,槽位既能让规则具有更好的匹配能力,也能让回复和函数中使用不同槽位的值。

    注意:下面的某些槽位左右带有空格,这些空格是必须的。

    通用槽位

    解释示例:通用槽位

    匹配:客服你好
    匹配:你好
    匹配:你好吗
    

    通用槽位会匹配零到无穷个字符、单词。此处的输入也会被系统捕获或者存储。

    + (*) 你好 (*)
    - 欢迎光临
    

    确定长度槽位

    解释示例:确定长度槽位

    匹配:早安北京
    不匹配:早安乌鲁木齐
    

    如果你知道你想要的字符长度,可以试试确定长度槽位。此处的槽位可以被系统捕获,而且可以在回答中使用

    语法为:*n, 其中n代表长度。

    + 早安 *2
    - 早安
    

    可控长度槽位

    解释示例:可控长度槽位

    匹配:早安
    匹配:早安北京
    匹配:早安哈尔滨
    匹配:早安乌鲁木齐
    不匹配:早安君士坦丁堡
    

    如果只想匹配一些字符,可控长度的槽位是个不错的选择。语法为:*~n, n代表你想匹配的最大长度

    + 早安 *~4
    - 早安
    

    区间槽位

    解释示例:区间槽位

    匹配:早安北京
    匹配:早安乌鲁木齐
    不匹配:早安
    

    如果想匹配一个确定的区间,比如2到4个字符之间,区间槽位绝对可以满足需要。语法为:*(最短-最长),此槽位可以被系统捕获和用在回复中。

    + 早安 *(2-4)
    - 早安
    

    必选项

    解释示例:必选项

    匹配:早安北京
    不匹配:早安西安
    不匹配:早安
    

    必选项用在你有一系列可选项,但是必须有一个被匹配。输入中的可选项会被系统捕获和用在回复中

    + 早安(北京|上海|天津)
    - 早安
    

    可选项

    解释示例:可选项

    匹配:早安北京
    匹配:早安美丽的北京
    不匹配:早安热闹的北京
    

    可选项用来确定一些额外的内容

    + 早安 [美丽的] 北京
    - 早安
    

    回复

    在触发器中,我们已经学到了怎么添加一个回答。事实上你可以添加任意数量的回答。这里还有一些高级功能可以帮助你完成更多的任务。

    简单形式

    + 在吗
    - 你好,在的
    

    如果添加了多个回答,系统会从中随机挑选一个作为回复, 然后丢掉这个回答。

    + 在吗
    - 亲,在的
    - 亲,有什么需要帮助
    - 你好,请问遇到什么问题了吗?
    

    所谓丢掉这个答案,是指机器人针对同一个用户,在半个小时内再次匹配上该触发器时,选择回复时,不考虑使用过的回复。 在一个触发器中声明多个回复后,保存,逻辑中将出现分支。

    机器人对话逻辑
    机器人对话逻辑

    如果不想让系统丢掉使用过的回复,可以在回复前添加{keep}。

    + 在吗
    - {keep} 亲,在的
    - 亲,有什么需要帮助
    - 你好,请问遇到什么问题了吗?
    

    也可以在触发器前添加{keep},就不用在每个回答中都添加了

    + {keep} 在吗
    - 亲,在的
    - 亲,有什么需要帮助
    - 你好,请问遇到什么问题了吗?
    

    如果回答很长,可以通过“^”分割以方便可读性。可以通过“\n”实现换行

    + 在吗
    - 你好,这里是客服中心,\n
    ^ 请问遇到什么问题了吗?    
    

    它等价于

    + 在吗
    - 你好,这里是客服中心,请问遇到什么问题了吗?
    

    槽位取值

    解释示例:槽位取值

    匹配:小明比小红高
    回答:你确定小明比小红高吗?
    

    有些时候,在回答中需要使用输入中的槽位值,这时可以使用达到目的。

    + 我是 *~3
    - 你好,
    

    如果用户输入,“我是张三”,那么系统将回复“你好,张三”,当有多个槽时,可以使用多个

    + *2 比 *2 高
    - 你确定高吗?
    

    在对话中,我们有时候会需要以前的槽位值,看一下下面这个例子:

    + 我叫 *~3
    - 你好,
    
        + 你猜我叫什么?
        % 你好,
        - 你刚说了,你叫
    

    代表了以前的槽位。其中N代表在在对话中之前的问答,M代表捕获的位移。

    槽位取值
    槽位取值

    此处,还有一个重要语法:%。(%) 开头的句子代表触发器“你猜我叫什么?”只服务于“你好,”作为回复时,它会被优先匹配。上一轮对话的回复通过(%)的方式指定了接下来的逻辑,形成多轮对话。 关于(%)的用法,后文还会进行详细介绍,此处,读者只需要掌握从上下文的槽位取值便可。

    另外,(+, %, -) 前的空格不是必须的,在多轮对话中,空格可以增强脚本的可读性,但是系统是忽略的。

    重定向 {@__reply__}

    有些时候,在问答对中重用一些回复能使编写脚本效率更高,这时可以定义一个问答对,并在脚本其它位置引用它。

    + 在吗
    - {@__greeting__} 请问有什么能帮助您?
    
    + __greeting__
    - 亲,在的。
    - 你好,客服小美为您服务
    - 亲亲,稍等,客服马上就到
    

    引用的方式就是 “{@触发器}”,触发器中的下划线不是必须的,但是它能增强脚本的可读性。

    多轮对话

    在实际应用中,和机器人聊天时,很可能要通过多轮对话完成一个任务。我们用(%)来定位之前回复,声明新的触发器,(%)后的内容是和某个回复内容一样的字符串。

    + *
    - 您身高多少
    
      + *(3-5)
      % 您身高多少
      - 我的身高也是
    

    让我们一起看看这个例子:

    1. 当用户输入任何文字,我们用通用槽位触发回答,然后系统回复“您身高多少”。

    2. 当用户继续输入时,系统会先从历史中查看之前的回复中是否有对应的上下文,在这里指的是“% 您身高多少”

    3. 最后,如果用户输入3到5个字符,系统匹配触发器“+ *(3-5)”, 并且回复“我也是”。“”代表的就是用户输入的内容。

    函数

    函数是一个强大而有趣的设计。在回复中,可以使用函数来获取整条消息对象,用户对象或者其它资源,比如数据库。把槽位值当做变量传给函数,例如下面这个例子:

    + 我的用户名是 *(2-10)
    - ^getUserAccount()
    

    所以,调用函数的方式就是使用“^”。在函数的编辑窗口中,可以这样定义:

    exports.getUserAccount(account, cb) {
      cb(null, "对不起,系统没有找到" + account);
    }
    

    函数的声明中,参数列表首先是槽位的值,可以传多个,然后最后一个参数始终是回调函数(cb),cb的参数列表为(error, text)。text作为文本添加到回复中。

    复合函数

    在回复中,可以添加任意多的函数,比如

    + ...
    - 联合 ^callFunction1() 和 ^callFunction2()
    

    嵌套函数

    在函数的回调函数中,函数名会被解析成对应的函数,所以放心的在回复中添加任意合法的函数,比如在脚本中这样写:

    + ...
    - ^nestedAFunction()
    

    然后,在函数中,定义如下:

    exports.nestedAFunction = function(cb) {
      cb(null, "张三 ^nestedBFunction()");
    }
    exports.nestedBFunction = function(cb) {
      cb(null, "和李四");
    }
    

    总结

    以上是多轮对话设计器 v1.x 版本中支持的脚本语法,这些语法能够保证业务人员实现满足需求的聊天机器人,除了函数部分的有一点门槛外,其它内容是非常容易掌握的。对于函数,只需要一点JavaScript基础知识,就可以掌握。

    示例应用

    本节介绍使用多轮对话设计器实现一个“聊天机器人”的具体过程。我们以实现天气问答机器人为例,我们选择这个场景并不是因为它简单,而是因为它容易理解,使用多轮对话设计器可以实现更复杂,更有价值的应用。我们先一睹为快,这个机器人是什么样子的。

    视频:天气查询机器人Demo

    是不是很实用?如果你掌握了多轮对话设计器,就可以实现聊天机器人。

    需求分析

    首先,我们需要梳理一下需求:

    1) 我想知道任意城市的天气信息,比如“今天上海天气怎么样”;

    2) 我还比较关心空气,我可以通过“今天上海空气怎么样”获得空气质量信息;

    3) 我想知道今天适不适合户外运动,就问“今天上海适合运动么”;

    4) 如果我问了一个城市的天气状况,我还想继续询问这个城市更多信息,这样我不用每次都告诉机器人城市名称。

    当然,我的每个意图都有多种表述方式,机器人能支持一些变化的问法。如果我的问题不够严谨,机器人还应该提醒我合理的表达。

    调研提供天气信息查询的API

    现在很多服务以API的形式提供,从搜索引擎中查找“天气查询服务 API”,我们就能得到一些供应商,经过一些比较,我选择了和风天气,它数据丰富,免费额度大方。

    和风天气
    和风天气

    AI音箱

    Chatopera与杭州任你说科技达成战略合作伙伴关系,所以,我们的对话系统产品与任你说音箱可以直接集成。

    任你说官网
    任你说官网

    第一条规则

    第一次打开多轮对话设计器后,我们看到如下的面板,我们称之为主面板。

    和风天气
    和风天气

    点击新建按钮,弹出创建机器人的表单:

    创建聊天机器人
    创建聊天机器人

    填入“小叮当”,当前多轮对话设计器支持中文(zh_CN)和英文(en_US),我们选择“zh_CN”,点击“确认”。然后我们就得到了一个聊天机器人。

    聊天机器人
    聊天机器人

    在操作中,有几个按钮:

    点击“管理”,进入多轮对话管理页面,点击“新建对话”,在弹出的窗口中,填写“对话名称”为“weather”,点击“确认”。这时,我们看到了新建的对话,我们将修改它的内容完成天气对话服务。

    创建对话
    创建对话

    点击“编辑”,进入对话编辑窗口。在左侧的“脚本区域”,写下第一条规则。

    + 今天 (*) 天气 [怎么样]
    - {keep} 天气挺好的
    

    点击“保存”,这时右侧的“逻辑区域”有了变化,出现了一个线条,在线条左右两端分别是问题和答案。在“对话区域”,我们输入“今天北京天气怎么样”,点击发送,这时机器人回复了。

    对话编辑窗口
    对话编辑窗口

    从我们需求上看,这没什么用,但是它工作了,我们就一点点优化它。对于在这条规则中,我们使用的语法,(*)代表一个槽位,代表在回复中取槽位的值,[怎么样]是可有的字符串,{keep}代表这条规则始终生效,keep涉及到对话的状态管理,我们将在文档中提供更多规则的描述,现在,读者看懂本示例就可以了。

    添加函数

    在多轮对话设计器中,怎么请求和风天气的数据呢?使用函数。函数是多轮对话支持的使用JavaScript实现的程序。

    我们在“对话编辑窗口”点击函数,粘贴如下代码:

    var WForewast = function (apiKey) {
    
        if (!apiKey) throw new Error('Invalid token, get it from http://www.heweather.com/my/service');
        this.key = apiKey;
    }
    
    
    WForewast.prototype.getWeatherByCity = function (city) {
        return new Promise((resolve, reject)=>{
            let url =  "https://free-api.heweather.com/v5/weather?city=" + encodeURIComponent(city) + "&key=" + this.key
            http
                .get(url)
                .then((res)=>{
                    resolve(res.data.HeWeather5[0].suggestion);
                })
                .catch(function (err) {
                    if (err) return reject(err);
                });
        })
    }
    
    const wf = new WForewast('182f1b6826d94c6285a489d2414f3ad0');
    
    
    exports.getWeatherByCity = function(city, cb){
        debug("getWeatherByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["comf"]["txt"]
                })
            }, (err)=>{
                debug("error:%j", err)
                cb(null, {
                    text: `很抱歉,没有获得${city}的天气信息。`
                })
            })
    }
    
    exports.getAirByCity = function(city, cb){
        debug("getAirByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["air"]["txt"]
                })
            }, (err)=>{
                cb(null, {
                    text: `很抱歉,没有获得${city}的空气信息。`
                })
            })
    }
    
    
    exports.getSportByCity = function(city, cb){
        debug("getSportByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["sport"]["txt"]
                })
            }, (err)=>{
                cb(null, {
                    text: `很抱歉,没有获得${city}的信息。`
                })
            })
    }
    
    exports.getDresscodeByCity = function(city, cb){
        debug("getDresscodeByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["drsg"]["txt"]
                })
            }, (err)=>{
                cb(null, {
                    text: `很抱歉,没有获得${city}的信息。`
                })
            })
    }
    

    在函数中,我们实现了根据城市请求天气、空气质量、着装建议和运动建议的接口,分别是getWeatherByCitygetAirByCitygetDresscodeByCitygetSportByCity

    细心的读者会发现,在函数中,多轮对话设计器直接支持了http,debug作为工具类,发起网络请求和输出日志信息。这两个接口极大的扩展了函数的能力,我们也会在函数中详细描述它们的使用。

    然后,回到“脚本区域”,修改一下规则,更新如下:

    + 今天 (*) 天气 [怎么样]
    - {keep} ^getWeatherByCity()
    

    在回复中,我们调用了getWeatherByCity,并且传入了城市名称。 接着,在“对话区域”,输入“今天北京天气怎么样”,回复与上次不一样了。

    测试对话
    测试对话

    这次,我们看到了期望的回复,正是从和风天气返回的北京今天的天气状况。

    使用环境变量

    在上面的函数中,我们有一个敏感的信息:和风天气的API密钥。在实际应用中,我们希望设计阶段部署阶段,它的值是不同的。这时,就需要使用环境变量,环境变量正是为解决这个问题而设计的。

    回到主面板,在“小叮当”操作中,点击环境变量,创建如下键值对:

    设置环境变量
    设置环境变量

    读者可以从和风天气获得该密钥,为验证用途,可以粘贴下面的值:

    "HEWEATHER_URL": "https://free-api.heweather.com/v5",
    "HEWEATHER_KEY": "182f1b6826d94c6285a489d2414f3ad0"
    

    保存后,回到天气对话脚本的“对话编辑窗口”,在函数中,使用下面的脚本:

    var WForewast = function (apiKey) {
        if (!apiKey) throw new Error('Invalid token, get it from http://www.heweather.com/my/service');
        this.key = apiKey;
    }
    
    
    WForewast.prototype.getWeatherByCity = function (city) {
        return new Promise((resolve, reject)=>{
            let url = config["HEWEATHER_URL"] + "/weather?city=" + encodeURIComponent(city) + "&key=" + this.key
            http
                .get(url)
                .then((res)=>{
                    resolve(res.data.HeWeather5[0].suggestion);
                })
                .catch(function (err) {
                    if (err) return reject(err);
                });
        })
    }
    
    const wf = new WForewast(config["HEWEATHER_KEY"]);
    
    
    exports.getWeatherByCity = function(city, cb){
        debug("getWeatherByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["comf"]["txt"]
                })
            }, (err)=>{
                debug("error:%j", err)
                cb(null, {
                    text: `很抱歉,没有获得${city}的天气信息。`
                })
            })
    }
    
    
    
    exports.getAirByCity = function(city, cb){
        debug("getAirByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["air"]["txt"]
                })
            }, (err)=>{
                cb(null, {
                    text: `很抱歉,没有获得${city}的空气信息。`
                })
            })
    }
    
    
    exports.getSportByCity = function(city, cb){
        debug("getSportByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["sport"]["txt"]
                })
            }, (err)=>{
                cb(null, {
                    text: `很抱歉,没有获得${city}的信息。`
                })
            })
    }
    
    exports.getDresscodeByCity = function(city, cb){
        debug("getDresscodeByCity: %s", city);
        wf.getWeatherByCity(city)
            .then((suggestions)=>{
                cb(null, {
                    text: suggestions["drsg"]["txt"]
                })
            }, (err)=>{
                cb(null, {
                    text: `很抱歉,没有获得${city}的信息。`
                })
            })
    }
    

    这次,代码内容和前一版本相比,使用了config对象,config是一个包含环境变量的JSON数据。所以,我们更加利于将来部署对话应用了。

    支持更多对话

    回想我们需要的几种天气信息,我们根据需求变更脚本,一个满足需求的脚本呈现如下:

    // 技能介绍
    
    + 你知道哪些天气信息
    - 我知道今天的空气,着装建议和适不适合运动
    
    // 天气
    
    + 今天 (*) 天气 [怎么样]
    - {keep} ^getWeatherByCity()
    
    + [今天] (天气|气候) [怎么样]
    - {@__wf_guide_}
    
    + (*) 今天天气 [怎么样]
    - {keep} ^getWeatherByCity()
    
        + (*) 空气 (*)
        % ^getWeatherByCity()
        - {keep} ^getAirByCity()
    
    
    + __wf_guide_
    - {keep} 添加城市名哦,比如“今天北京天气怎么样”或者“北京天气怎么样”
    - 我需要知道城市名称,比如“今天北京天气怎么样”或者“北京天气怎么样”
    - 要告诉我城市名,比如“今天北京天气怎么样”或者“北京天气怎么样”
    
    
    // 空气
    
    + [今天] 空气 [怎么样]
    - {@__wf_guide_air}
    
    + (*) 今天空气 [怎么样]
    - {keep} ^getAirByCity()
    
    + 今天 (*) 空气 [怎么样]
    - {keep} ^getAirByCity()
    
    + __wf_guide_air
    - {keep} 添加城市名哦,比如“今天北京空气怎么样”或者“北京空气怎么样”
    - 我需要知道城市名称,比如“今天北京空气怎么样”或者“北京空气怎么样”
    - 要告诉我城市名,比如“今天北京空气怎么样”或者“北京空气怎么样”
    
    
    // 运动
    
    + [今天] 适(合|宜)运动(么|吗)
    - {@__wf_guide_sport}
    
    + (*) 今天适(合|宜)运动(么|吗)
    - {keep} ^getSportByCity()
    
    + 今天 (*) 适(合|宜)运动(么|吗)
    - {keep} ^getSportByCity()
    
    + __wf_guide_sport
    - {keep} 添加城市名哦,比如“今天北京适合运动么”或者“北京今天适合运动么”
    - 我需要知道城市名称,比如“今天北京适合运动么”或者“北京今天适合运动么”
    - 要告诉我城市名,比如“今天北京适合运动么”或者“北京今天适合运动么”
    
    
    // 衣着
    
    + [今天] 适(合|宜)穿什么
    - {@__wf_guide_dresscode}
    
    + (*) 今天适(合|宜)穿什么
    - {keep} ^getDresscodeByCity()
    
    + [今天] (*) 适(合|宜)穿什么
    - {keep} ^getDresscodeByCity()
    
    
    + __wf_guide_dresscode
    - {keep} 添加城市名哦,比如“今天北京适合穿什么”或者“北京今天适合穿什么”
    - 我需要知道城市名称,比如“今天北京适合穿什么”或者“北京今天适合穿什么”
    - 要告诉我城市名,比如“今天北京适合穿什么”或者“北京今天适合穿什么”
    

    这也就是我们在天气查询机器人Demo中看到的机器人的脚本,在设计过程中,我们通过对话区域来测试机器人的回复是否符合预期,我们通过逻辑窗口来查看当前机器人的思维逻辑导图,当前机器人对话的状态会被高量,被命中的规则呈现为路径。

    机器人思维逻辑
    机器人思维逻辑

    另外,在设计过程中,每次保存自动为脚本和函数生成快照,使用快照下拉列表,我们能方便的回退。

    快照管理
    快照管理

    多轮对话设计器中,业务人员可以更专注于对话机器人的对话逻辑满足需求。

    发布机器人

    现在,有了可以工作的脚本,我们想发布一个版本,这时回到主面板,点击“发布”,填入如下信息,点击“确认”。

    发布机器人
    发布机器人

    导出机器人

    最终,我们需要得到一个“服务”,它能时刻被访问,以及和AI音箱集成。我们需要将天气机器人导出为对话应用,然后部署到智能问答引擎。在主面板,点击版本管理,我们看到操作中有三项。

    多轮对话设计器支持导出机器人后,极大的方便了分发和部署。