# 填槽对话指令

Dialoginterface提供管理你的技能和用户之间的多轮对话的指令。你可以使用这些指令来向用户询问完成你的技能所需要的信息。

# 使用要求

为了使用Dialog指令,你的技能需要在技能控制台创建一个交互模型。交互模型是意图的集合,意图中需要定义以下内容:

  • 必填槽:完成意图时必填的词槽。
  • 系统向用户询问必填槽时的话术。
  • 在技能继续操作之前是否需要向用户确认槽信息。
  • 在技能继续操作之前是否需要向用户确认整个意图信息。
  • 系统向用户确认槽和意图时的话术。
  • 验证用户提供的槽值是否有效的槽验证规则。这些规则既可以用于必填槽,也可以用于非必填槽。
  • 当用户输入的槽值有误时,系统向用户询问正确的槽值的提示和话术。

当用户与你的技能进行交互时,如何使用对话框模型取决于你如何管理对话

# 多轮对话的步骤

在技能中,与用户的对话是一个多轮对话,在这个对话中,系统提出问题,用户用答案进行回应。对话与表示用户总体请求的特定意图相关联。这些问题和答案用于收集、验证和确认槽值。直到根据交互模型中定义的规则填充并确认意图所需的所有词槽,对话才会继续。

系统在对话中的询问分为四类:

  • 填槽追问:向用户询问槽值。用户使用实体中的词条或包含词条的一整句话进行回答。举例:

    • 系统: 你从哪个城市出发?(追问fromCity槽的值)
    • 系统: 你要去哪个城市旅游?(追问toCity槽的值)
    • 系统: 你想什么时候去旅游?(追问tralvelDate槽的值)
  • 槽确认:请用户确认先前提供的(或程序自动设置的)单个槽值是否正确。用户回答“是”或“不是”。举例:

    • 系统: 你准备从合肥离开,是吗?(确认fromCity槽的值)
    • 系统: 你是准备去广州旅游吗?(确认toCity槽的值)
    • 系统: 你是想要4月21号出发是吗?(确认travelDate槽的值)
  • 意图确认:在实现意图之前,请用户验证为该意图收集的所有信息是否正确。与槽确认一样,用户回答“是”或“不是”。

    • 系统: 我将保存你在4月21号从合肥去广州的行程,请问确认吗?(PlanMyTrip意图确认)
  • 槽值验证:根据预先定义的规则检查槽值,并在槽值失败时提示用户。之后用户可以使用正确的值进行响应。

    • 系统: 我不能为你规划过去的日期的形成,请告诉我一个未来的旅游时间。(在用户提供了一个过去的时间时追问travelDate槽的值)

一个意图的对话可能包含所有这些步骤,或者只包含其中的一部分。例如,对话内容可以只使用槽追问,但没有使用槽或意图确认。

# 管理和用户之间的对话

在你的技能中,有三种主要的场景来处理与用户的多回合对话:

  1. 托管给iFLYOS:在这种情况下,iFLYOS会使用你在控制台中定义的交互模型进行提示。
  2. 使用Dialog.ElicitSlot,Dialog.ConfirmSlotDialog.ConfirmIntent指令来控制每一步对话。
  3. 综合使用两种。在这种情况下,你可以托管一部分的对话,在必要的时候自己操作另外一部分对话。

# 将对话托管给iFLYOS

这个选项允许你将大部分编码工作集中在满足用户请求的逻辑上,而不是自己编写所有代码来询问用户槽值。你可以委托对话,也可以使用DialogDelegate指令手动处理。

使用对话托管, iFLYOS基于交互模型的定义完成所有对话步骤,然后在完成时向你的技能发送一个IntentRequest。在这种情况下,你不需要使用Dialog指令。

使用手动处理,iFLYOS会在每次对话时向你的技能发送一个意图请求。请求包含一个dialogState属性,当该属性取值为STARTEDIN_PROGRESS时,标识对话尚未完成,你可以返回Dialog.Delegate指令。系统使用交互模型中定义的提示来进行下一步的槽追问,槽确认,槽验证或意图确认。

提示

通过手动处理,你的技能可以在对话的每一轮中收到IntentRequest,你都可以随时选择接管对话还是继续委托给iFLYOS。如果你可以根据到目前为止的信息来设置默认槽值或计算槽值,我们建议你使用手动处理,这样系统将不会遍历询问整个对话。

对话完成后,传入IntentRequest的对话状态为COMPLETED。所有必需的信息都呈现在intentslot值中,此时,你的技能可以完成后续的处理。

# 用代码控制对话

用代码控制对话,也就是你通过自己的代码检查槽值和确认状态,决定对话的下一步,并返回合适的指令(Dialog.ElicitSlotDialog.ConfirmSlotDialog.ConfirmIntent)。

你需要在自己的代码里决定对话状态和下一步的操作。如果你的技能遇到需要使用Dialog指令的情况,你的技能收到的IntentRequest中会包含dialogState。当对话状态取值为STARTEDIN_PROGRESS时可以自己控制;当状态为COMPLETED时只能回复Dialog.Delegate指令。

注意,这些指令不使用控制台交互模型中定义的提示语。例如,当你返回Dialog.ElicitSlot时,你必须在回复中定义提示话术。Dialog.ElicitSlot会使用你在代码中提供的话术。我们建议这里提供的话术可以引导用户提供合适的回复。

另外注意,Dialog.ElicitSlot不包含槽验证。如果你想要定义槽验证规则,并希望在用户提供错误的槽值时提示追问用户,我们建议你托管对话。

# 两者混用

你可以结合使用两种方式。根据收到的IntentRequest,你的代码可以执行以下操作:

  • 回复Dialog.Delegate指令来让iFLYOS接管下一步。
  • 回复其他的Dialog指令来自己进行操作。

# 在对话中更新槽值和确认状态

每一个Dialog指令中均包含字段updatedIntent,该字段可以更改 Intent对象,用来:

  • 在继续对话框之前,使用代码设置或更改任何槽值。这可以减少系统实现意图时必须询问的问题数量,从而改善用户体验。当你可以基于用户默认值或其他你拥有的信息设置槽值时,我们建议你使用这个字段。
  • 设置或改变槽或意图的confirmationStatus

注意

在你返回Dialog指令时不能变更意图,返回的意图名称和槽组合必须和发送给你的完全一致。

# 对话指令

下列表格中是所有填槽指令,填槽对话指令是Response中的一部分。如果你的技能没有遇到需要使用Dialog指令的情况,返回以下任何一个指令都会造成错误。

指令 说明
Dialog.ElicitSlot 槽追问
Dialog.ConfirmSlot 槽确认
Dialog.ConfirmIntent 意图确认
Dialog.Delegate 填槽对话托管

# ElicitSlot 指令

{
  "type": "Dialog.ElicitSlot",
  "slotToElicit": "string",
  "updatedIntent": {
    "name": "string",
    "confirmationStatus": "NONE",
    "slots": {
      "SlotName": {
        "name": "SlotName",
        "value": "string",
        "resolutions": {},
        "confirmationStatus": "NONE"
      }
    }
  }
}

参数说明

参数名 说明 类型 必须出现
type 取值Dialog.ElicitSlot String
slotToElicit 需要追问的槽名 String
updatedIntent 云函数会发送意图给你的技能,当开发者认为当前语境下有更合理的意图理解时,你可以设置或修改槽值和确认状态。当你不需要修改意图中的槽值或者确认状态时,可以不出现该字段。 Object

# 代码示例

这个例子表示回复DialogElicitSlot指令来询问fromCity的槽值。注意OutputSpeech对象用来提示追问。

{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "你将从哪里出发?"
    },
    "shouldEndSession": false,
    "directives": [
      {
        "type": "Dialog.ElicitSlot",
        "slotToElicit": "fromCity",
        "updatedIntent": {
          "name": "PlanMyTrip",
          "confirmationStatus": "NONE",
          "slots": {
            "toCity": {
              "name": "toCity",
              "confirmationStatus": "NONE"
            },
            "travelDate": {
              "name": "travelDate",
              "confirmationStatus": "NONE",
              "value": "2017-04-21"
            },
            "fromCity": {
              "name": "fromCity",
              "confirmationStatus": "NONE"
            },
            "activity": {
              "name": "activity",
              "confirmationStatus": "NONE"
            },
            "travelMode": {
              "name": "travelMode",
              "confirmationStatus": "NONE"
            }
          }
        }
      }
    ]
  }
}

# 特别注意

OutputSpeech中你必须包含追问词槽的提示话术,这个指令不会使用交互模型中定义了的话术。Dialog.ElicitSlot会使用你在指令中提供的话术,我们建议这里提供的话术可以引导用户提供合适的回复。

如果你需要在继续执行前设置或更改槽值或确认状态,在updatedIntent属性中设置即可。

# 交互举例

一个规划行程的意图的交互流程如下:

用户:我要去旅游。

iFLYOS发送PlanMyTrip没有槽值的意图给技能

字段 取值
fromCity null
toCity null
travelDate null
travelMode null
activity null

技能回复Dialog.ElicitSlot 指令来追问fromCity的槽值。

技能:你将从哪里出发? (填槽追问话术来自回复中的outputSpeech)*

用户:合肥。

iFLYOS发送PlanMyTrip意图给技能,包含以下槽信息:

字段 取值
fromCity 合肥
toCity null
travelDate null
travelMode null
activity null

技能回复Dialog.ElicitSlot 指令来追问toCity的槽值。

技能:你要去哪里旅游?

用户:广州

iFLYOS发送PlanMyTrip意图给技能,包含以下槽信息:

字段 取值
fromCity 合肥
toCity 广州
travelDate null
travelMode null
activity null

对话还在继续

# ConfirmSlot 指令

{
  "type": "Dialog.ConfirmSlot",
  "slotToConfirm": "string",
  "updatedIntent": {
    "name": "string",
    "confirmationStatus": "NONE",
    "slots": {
      "string": {
        "name": "string",
        "value": "string",
        "resolutions": {},       
        "confirmationStatus": "NONE"
      }
    }
  }
}

参数说明

参数名 说明 类型 必须出现
type 取值Dialog.ConfirmSlot String
slotToConfirm 需要确认的槽名 String
updatedIntent 云函数会发送意图给你的技能,当开发者认为当前语境下有更合理的意图理解时,你可以设置或修改槽值和确认状态。当你不需要修改意图中的槽值或者确认状态时,可以不出现该字段。 Object

# 代码示例

这个例子表示回复DialogConfirmSlot指令来确认fromCity的槽值。注意OutputSpeech对象用来提示追问。

{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "你将从合肥出发,是吗?"
    },
    "shouldEndSession": false,
    "directives": [
      {
        "type": "Dialog.ConfirmSlot",
        "slotToConfirm": "fromCity",
        "updatedIntent": {
          "name": "PlanMyTrip",
          "confirmationStatus": "NONE",
          "slots": {
            "toCity": {
              "name": "toCity",
              "confirmationStatus": "NONE"
            },
            "travelDate": {
              "name": "travelDate",
              "confirmationStatus": "NONE",
              "value": "2017-04-21"
            },
            "fromCity": {
              "name": "fromCity",
              "value": "Seattle",
              "confirmationStatus": "NONE"
            },
            "activity": {
              "name": "activity",
              "confirmationStatus": "NONE"
            },
            "travelMode": {
              "name": "travelMode",
              "confirmationStatus": "NONE"
            }
          }
        }
      }
    ]
  }
}

# 特别注意

我们建议你少用词槽确认,避免交互中过多的“你确定吗”打扰用户

在返回Dialog.ConfirmSlot时,在OutputSpeech中你必须包含槽确认的提示话术,这个指令不会使用对话模型中定义了的话术。

如果你需要在继续执行前设置或更改槽值或确认状态,在updatedIntent属性中设置即可。

在系统让用户确认槽值时,用户可以回复“是的”或“不是”,iFLYOS会发送包含更新过的slot.confirmationStatus属性的意图给你的技能,以表示用户的响应(CONFIRMEDDENIED)。

# 交互举例

一个规划行程的意图的交互流程如下:

用户:我要从合肥出发去旅游

iFLYOS发送PlanMyTrip意图给技能,包含以下信息:

字段 取值
fromCity 合肥
fromCity.confirmationStatus NONE
toCity null
travelDate null
travelMode null
activity null

技能回复Dialog.ConfirmSlot 指令来确认fromCity的槽值

技能:你将从合肥出发,是吗?

用户:是的 iFLYOS会发送一个意图,其中fromCity槽的确认状态fromCity.confirmationStatus设置为CONFIRMED

# ConfirmIntent 指令

在技能采取行动之前,发送这个指令让iFLYOS确认用户为意图提供的所有信息。你需要在OutputSpeech对象中提供一个用于意图确认的提示,我们建议你在提示话术中重复用户需要确认的值。

{
  "type": "Dialog.ConfirmIntent",
  "updatedIntent": {
    "name": "string",
    "confirmationStatus": "NONE",
    "slots": {
      "string": {
        "name": "string",
        "value": "string",
        "resolutions": {},               
        "confirmationStatus": "NONE"
      }
    }
  }
}

参数说明

参数名 说明 类型 必须出现
type 取值Dialog.ConfirmIntent String
updatedIntent 云函数会发送意图给你的技能,当开发者认为当前语境下有更合理的意图理解时,你可以设置或修改槽值和确认状态。当你不需要修改意图中的槽值或者确认状态时,可以不出现该字段。 Object

# 代码示例

这个例子表示回复DialogConfirmIntent指令来确认整个意图。注意OutputSpeech对象用来提示确认话术。

在这个例子中,3个必填槽(toCity,fromCity,travelDate)在之前的轮次中已经确认过了,另外两个槽(activitytravelMode)被填了,但是不需要确认。

{
  "version": "1.0",
  "sessionAttributes": {},
  "response": {
    "outputSpeech": {
      "type": "PlainText",
      "text": "你将在4月21日从合肥出发去广州,是吗?"
    },
    "shouldEndSession": false,
    "directives": [
      {
        "type": "Dialog.ConfirmIntent",
        "updatedIntent": {
          "name": "PlanMyTrip",
          "confirmationStatus": "NONE",
          "slots": {
            "toCity": {
              "name": "toCity",
              "value": "Portland",
              "confirmationStatus": "CONFIRMED"
            },
            "travelDate": {
              "name": "travelDate",
              "confirmationStatus": "CONFIRMED",
              "value": "2017-04-21"
            },
            "fromCity": {
              "name": "fromCity",
              "value": "Seattle",
              "confirmationStatus": "CONFIRMED"
            },
            "activity": {
              "name": "activity",
              "value": "hiking"
              "confirmationStatus": "NONE"
            },
            "travelMode": {
              "name": "travelMode",
              "value": "driving"
              "confirmationStatus": "NONE"
            }
          }
        }
      }
    ]
  }
}

# 特别注意

在你的技能收集了所有你实现意图需要的槽时,你可能想给用户再一次的机会来确认信息是否正确,然后再继续。这主要用于购买或预定的技能。

在返回Dialog.ConfirmIntent时,在OutputSpeech中你必须包含槽确认的提示话术,这个指令不会使用对话模型中定义了的话术。

如果你需要在继续执行前设置或更改槽值或确认状态,在updatedIntent属性中设置即可。

在系统让用户确认意图时,用户可以回复“是的”或“不是”,iFLYOS会发送包含更新过的intent.confirmationStatus属性的意图给你的技能,以表示用户的响应(CONFIRMEDDENIED)。

# 交互举例

一个规划行程的意图的交互流程如下:

…在之前的交互中已经收集到了必填的fromCity,toCity, 和travelDate 槽值。iFLYOS把填了所有所需要的槽的意图PlanMyTrip发送给技能,但是整个意图的confirmationStatus 设置为 NONE.

技能回复了Dialog.ConfirmIntent指令。

技能:你将在4月21日从合肥出发去广州,是吗?(意图确认话术来自发返回的outputSpeech字段)

用户:是的 (iFLYOS会发送一个confirmationStatus属性设置为CONFIRMEDPlanMyTrip)*

# Delegate 指令

json { "type": "Dialog.Delegate", "updatedIntent": { "name": "string", "confirmationStatus": "NONE", "slots": { "SlotName": { "name": "SlotName", "value": "string", "confirmationStatus": "NONE" } } } }

参数说明

参数名 说明 类型 必须出现
type 取值Dialog.Delegate String
updatedIntent 云函数会发送意图给你的技能,当开发者认为当前语境下有更合理的意图理解时,你可以设置或修改槽值和确认状态。当你不需要修改意图中的槽值或者确认状态时,可以不出现该字段。 Object

# 特别注意

  1. Dialog.Delegate指令中不可包含outputSpeechreprompt,iFLYOS会使用交互模型中定义的提示来询问用户槽值和确认。
  2. 如果你的意图的交互模型中包含对意图确认的提示话术,你的代码需要在执行用户请求前确认Intent.confirmationStatus取值为COMFIRMED。如果用户在确认时回复"no",dialogState取值是COMPLETEDconfirmationStatus取值DENIED

# 交互举例

一个规划行程的意图的交互流程如下:

用户:我要去广州旅游。

iFLYOS发送PlanMyTrip意图给技能

字段 取值
dialogState STARTED
fromCity null
toCity Portland
travelDate null
travelMode null
activity null
confirmationStatus NONE

技能返回Dialog.Delegate 指令,其中updatedIntent.slots.fromCity设置为合肥(fromCity的有一个默认值),其他槽值没变。

技能:你要从合肥出发,是吗?(确认fromCity槽的话术来自交互模型)

用户:是的。

iFLYOS发送PlanMyTrip意图给技能

字段 取值
dialogState IN_PROGRESS
fromCity Seattle
fromCity.confirmationStatus CONFIRMED
toCity Portland
travelDate null
travelMode null
activity null
confirmationStatus NONE

技能返回Dialog.Delegate 指令。

技能:你想什么时候出发? (这个填槽追问话术来自交互模型)

用户:周五

iFLYOS发送PlanMyTrip意图给技能

字段 取值
dialogState IN_PROGRESS
fromCity Seattle
fromCity.confirmationStatus CONFIRMED
toCity Portland
travelDate 2017-04-21
travelMode null
activity null
confirmationStatus NONE

技能返回Dialog.Delegate 指令。(travelModeactivity槽非必填,系统不会追问 )

系统:你确认4月21日从合肥出发去广州,是吗? (意图确认话术来自交互模型)

用户:是的

iFLYOS发送PlanMyTrip意图给技能

字段 取值
dialogState IN_PROGRESS
fromCity Seattle
fromCity.confirmationStatus CONFIRMED
toCity Portland
travelDate 2017-04-21
travelMode null
activity null
confirmationStatus CONFIRMED

注意

如果用户在最后一轮确认时拒绝了,对话状态被认为是 COMPLETE, 但是 [intent.confirmationStatus]为 DENIED

现在PlanMyTrip意图拿到了所有需要的的信息。dialogState is COMPLETED,技能不能返回 Dialog.Delegate 指令。

# updateIntent 参数说明

参数名 说明 类型 必须出现
name 意图名称 String
confirmationStatus 意图确认状态,取值:NONE, CONFIRMED, DENIED String
slots 槽信息 Object
Slotname 槽名称 String
Slotname.name 槽名称,此处取值需与前面的Slotname一致 String
Slotname.value 槽值 String
Slotname.confirmationStatus 槽确认状态,取值:NONE, CONFIRMED, DENIED String