# 填槽对话指令
Dialog
interface提供管理你的技能和用户之间的多轮对话的指令。你可以使用这些指令来向用户询问完成你的技能所需要的信息。
# 使用要求
为了使用Dialog
指令,你的技能需要在技能控制台创建一个交互模型。交互模型是意图的集合,意图中需要定义以下内容:
- 必填槽:完成意图时必填的词槽。
- 系统向用户询问必填槽时的话术。
- 在技能继续操作之前是否需要向用户确认槽信息。
- 在技能继续操作之前是否需要向用户确认整个意图信息。
- 系统向用户确认槽和意图时的话术。
- 验证用户提供的槽值是否有效的槽验证规则。这些规则既可以用于必填槽,也可以用于非必填槽。
- 当用户输入的槽值有误时,系统向用户询问正确的槽值的提示和话术。
当用户与你的技能进行交互时,如何使用对话框模型取决于你如何管理对话。
# 多轮对话的步骤
在技能中,与用户的对话是一个多轮对话,在这个对话中,系统提出问题,用户用答案进行回应。对话与表示用户总体请求的特定意图相关联。这些问题和答案用于收集、验证和确认槽值。直到根据交互模型中定义的规则填充并确认意图所需的所有词槽,对话才会继续。
系统在对话中的询问分为四类:
填槽追问:向用户询问槽值。用户使用实体中的词条或包含词条的一整句话进行回答。举例:
- 系统: 你从哪个城市出发?(追问
fromCity
槽的值) - 系统: 你要去哪个城市旅游?(追问
toCity
槽的值) - 系统: 你想什么时候去旅游?(追问
tralvelDate
槽的值)
- 系统: 你从哪个城市出发?(追问
槽确认:请用户确认先前提供的(或程序自动设置的)单个槽值是否正确。用户回答“是”或“不是”。举例:
- 系统: 你准备从合肥离开,是吗?(确认
fromCity
槽的值) - 系统: 你是准备去广州旅游吗?(确认
toCity
槽的值) - 系统: 你是想要4月21号出发是吗?(确认
travelDate
槽的值)
- 系统: 你准备从合肥离开,是吗?(确认
意图确认:在实现意图之前,请用户验证为该意图收集的所有信息是否正确。与槽确认一样,用户回答“是”或“不是”。
- 系统: 我将保存你在4月21号从合肥去广州的行程,请问确认吗?(
PlanMyTrip
意图确认)
- 系统: 我将保存你在4月21号从合肥去广州的行程,请问确认吗?(
槽值验证:根据预先定义的规则检查槽值,并在槽值失败时提示用户。之后用户可以使用正确的值进行响应。
- 系统: 我不能为你规划过去的日期的形成,请告诉我一个未来的旅游时间。(在用户提供了一个过去的时间时追问
travelDate
槽的值)
- 系统: 我不能为你规划过去的日期的形成,请告诉我一个未来的旅游时间。(在用户提供了一个过去的时间时追问
一个意图的对话可能包含所有这些步骤,或者只包含其中的一部分。例如,对话内容可以只使用槽追问,但没有使用槽或意图确认。
# 管理和用户之间的对话
在你的技能中,有三种主要的场景来处理与用户的多回合对话:
- 托管给iFLYOS:在这种情况下,iFLYOS会使用你在控制台中定义的交互模型进行提示。
- 使用
Dialog.ElicitSlot
,Dialog.ConfirmSlot
和Dialog.ConfirmIntent
指令来控制每一步对话。 - 综合使用两种。在这种情况下,你可以托管一部分的对话,在必要的时候自己操作另外一部分对话。
# 将对话托管给iFLYOS
这个选项允许你将大部分编码工作集中在满足用户请求的逻辑上,而不是自己编写所有代码来询问用户槽值。你可以委托对话,也可以使用DialogDelegate
指令手动处理。
使用对话托管, iFLYOS基于交互模型的定义完成所有对话步骤,然后在完成时向你的技能发送一个IntentRequest
。在这种情况下,你不需要使用Dialog
指令。
使用手动处理,iFLYOS会在每次对话时向你的技能发送一个意图请求。请求包含一个dialogState
属性,当该属性取值为STARTED
或IN_PROGRESS
时,标识对话尚未完成,你可以返回Dialog.Delegate
指令。系统使用交互模型中定义的提示来进行下一步的槽追问,槽确认,槽验证或意图确认。
提示
通过手动处理,你的技能可以在对话的每一轮中收到IntentRequest
,你都可以随时选择接管对话还是继续委托给iFLYOS。如果你可以根据到目前为止的信息来设置默认槽值或计算槽值,我们建议你使用手动处理,这样系统将不会遍历询问整个对话。
对话完成后,传入IntentRequest
的对话状态为COMPLETED
。所有必需的信息都呈现在intent
的slot
值中,此时,你的技能可以完成后续的处理。
# 用代码控制对话
用代码控制对话,也就是你通过自己的代码检查槽值和确认状态,决定对话的下一步,并返回合适的指令(Dialog.ElicitSlot
,Dialog.ConfirmSlot
,Dialog.ConfirmIntent
)。
你需要在自己的代码里决定对话状态和下一步的操作。如果你的技能遇到需要使用Dialog
指令的情况,你的技能收到的IntentRequest
中会包含dialogState
。当对话状态取值为STARTED
或IN_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
属性的意图给你的技能,以表示用户的响应(CONFIRMED
或DENIED
)。
# 交互举例
一个规划行程的意图的交互流程如下:
用户:我要从合肥出发去旅游
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
)在之前的轮次中已经确认过了,另外两个槽(activity
和travelMode
)被填了,但是不需要确认。
{
"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
属性的意图给你的技能,以表示用户的响应(CONFIRMED
或DENIED
)。
# 交互举例
一个规划行程的意图的交互流程如下:
…在之前的交互中已经收集到了必填的fromCity
,toCity
, 和travelDate
槽值。iFLYOS把填了所有所需要的槽的意图PlanMyTrip
发送给技能,但是整个意图的confirmationStatus
设置为 NONE
.
技能回复了Dialog.ConfirmIntent
指令。
技能:你将在4月21日从合肥出发去广州,是吗?(意图确认话术来自发返回的outputSpeech
字段)
用户:是的 (iFLYOS会发送一个confirmationStatus
属性设置为CONFIRMED
的PlanMyTrip
)*
# Delegate 指令
json { "type": "Dialog.Delegate", "updatedIntent": { "name": "string", "confirmationStatus": "NONE", "slots": { "SlotName": { "name": "SlotName", "value": "string", "confirmationStatus": "NONE" } } } }
参数说明
参数名 | 说明 | 类型 | 必须出现 |
---|---|---|---|
type | 取值Dialog.Delegate | String | 是 |
updatedIntent | 云函数会发送意图给你的技能,当开发者认为当前语境下有更合理的意图理解时,你可以设置或修改槽值和确认状态。当你不需要修改意图中的槽值或者确认状态时,可以不出现该字段。 | Object | 否 |
# 特别注意
Dialog.Delegate
指令中不可包含outputSpeech
和reprompt
,iFLYOS会使用交互模型中定义的提示来询问用户槽值和确认。- 如果你的意图的交互模型中包含对意图确认的提示话术,你的代码需要在执行用户请求前确认
Intent.confirmationStatus
取值为COMFIRMED
。如果用户在确认时回复"no",dialogState
取值是COMPLETED
,confirmationStatus
取值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
指令。(travelMode
和activity
槽非必填,系统不会追问 )
系统:你确认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 | 是 |