摘要
本文描述了一个基于计划的、独立于任务的对话管理框架RavenClaw。该框架的一个关键特点是,它将对话控制逻辑的特定领域方面与独立于领域的对话技巧隔离开来,并在这个过程中促进了在复杂的、面向任务的领域中运行的混合主动系统的快速发展。系统开发人员可以专注于描述对话框任务控制逻辑,而RavenClaw对话框引擎则透明地支持和执行大量与领域无关的会话技能,如错误处理、计时和轮流。
RavenClaw对话框管理框架
RavenClaw是一个两层对话管理框架,它在对话控制逻辑的领域相关和领域独立方面之间实现了清晰的分离-参见图2。特定于域的方面由dialog任务规范(dialog task specification)捕获,dialog任务规范本质上是系统作者提供的交互层次计划。可重用的、独立于域的对话引擎通过执行给定的对话任务规范来管理对话。在此过程中,对话引擎还提供了一组与域无关的基本会话策略,如错误处理、计时和轮流行为,以及各种其他通用对话机制,如帮助、重复、取消、暂停/恢复、退出、重新启动等。
The dialog task specification
dialog任务规范描述了交互的分层计划。更具体地说,对话任务规范由对话代理树组成,每个代理负责处理交互的一个子部分。例如,图3描绘了RoomLine的对话任务规范的顶部,RoomLine是一个语音对话系统,可以帮助用户预订会议室(关于该系统的更多细节将在后面的第5.2节中介绍)。根节点包含几个子节点:Login(标识用户到系统)、GetQuery(从用户获取时间和房间限制)、GetResults(对后端执行查询)和DiscussResults(显示获得的结果并处理即将进行的选择会议室的协商)最符合用户需求。在树的更深一层,登录代理分解为Welcome,它提供一个简短的欢迎提示AskRegistered和AskName,用于向系统标识用户,最后是GreetUser,用于向用户发送问候。
对话框任务规范中的对话框代理分为两类:基本对话框代理(如图3所示为灰色)和对话框代理(如图3所示为透明)。基本对话代理位于树中的终端位置(例如Welcome、AskRegistered)并实现原子对话操作或对话移动。有四种基本对话代理:通知-生成输出(例如,欢迎)、请求-请求用户信息(例如,AskRegistered)、期望-期望用户信息,但不显式请求(例如,Projector)和执行-执行特定于域的操作,例如数据库访问(例如。Projector)。对话框代理占据树中的非终端位置(如Login、GetQuery);它们的目的是控制其包含的代理的执行,并封装对话框任务的更高层次的时间和逻辑结构。
个对话代理实现一个执行单元,该例程在运行时由对话引擎调用。执行单元特定于代理类型。例如,通知代理在执行时生成输出,而请求代理在生成请求的同时还收集用户的响应。对于对话代理,执行单元负责规划其子代理的执行。除了执行单元之外,每个对话代理还可以定义前提条件、触发器以及成功和失败条件。在计划树中各种代理的执行时,对话引擎和父对话代理会考虑这些问题。
如果对话代理是RavenClaw对话管理框架中的基本执行单元,则系统在整个对话过程中处理的数据将封装在concepts中。concepts可以与对话框任务树中的各种代理相关联,例如图3中注册的和用户名,并且可以被树中的任何代理访问和操作。RavenClaw对话框管理框架中预定义了几个基本concepts类型:Boolean、string、integer和float。此外,该框架还支持开发人员定义的更复杂的concepts类型,如(嵌套)结构和数组。在内部,每个concepts的“值”由一组值/置信对表示,例如city_name={Boston/0.35;Austin/0.27}。因此,对话引擎可以跟踪每个concepts的多个替代假设,并可以捕获每个假设中的不确定性水平(Bohus and Rudnicky,2005a;Bohus and Rudnicky,2006)。此外,每个concepts还保留以前值的历史记录,以及有关接地状态、concepts上次更新时间等的信息。
The RavenClaw dialog engine
现在,我们将注意力转向RavenClaw对话框引擎用于执行给定对话框任务规范的算法。对话引擎算法集中在两个数据结构上:一个对话堆栈,它在运行时捕获话语结构;另一个期望议程,它捕获系统在任何给定回合中期望从用户那里听到的内容。该对话框由交错执行阶段和输入阶段控制——见图5。在执行阶段,任务树中的对话代理放置在对话堆栈上并从中执行,从而在进程中生成系统行为。在输入阶段,系统使用期望议程将当前用户输入的信息传输到对话框任务树。下面,我们将更详细地描述这两个阶段。
The execution phase
首先,对话框引擎调用对话框堆栈顶部代理的执行单元。执行单元的效果因代理类型而异。例如,通知代理输出一个系统提示;请求代理输出一个系统请求,然后请求一个输入阶段;对话框代理将其子代理推送到对话框堆栈上。执行单元完成后,控件将返回到对话框引擎。如果未请求输入阶段(某些代理可以在完成执行单元时发出此请求),则对话框引擎将测试对话框堆栈上所有代理的完成条件。所有已完成的代理都将从对话框堆栈中删除。接下来,对话框引擎调用错误处理决策过程。在这一步中,错误处理决策过程(我们将在第4.3节中更详细地描述)收集有关对话框进行得如何的证据,并决定是否触发错误处理操作。如果需要错误恢复操作,错误处理决策过程将动态创建错误处理代理并将其推送到对话框堆栈上(例如,显式确认等)。最后,在执行阶段的最后阶段,对话框引擎检查对话框任务树中所有代理的焦点声明(触发器)条件。如果任务树中的任何代理请求集中,它们将被推送到对话框堆栈的顶部。
为了清楚起见,我们将通过图6中的RoomLine对话框任务的执行呈现逐步跟踪。相应的对话框任务树也显示在同一图中。在启动时,对话框引擎将根代理RoomLine放在对话框堆栈上。接下来,对话框引擎进入执行阶段。首先,引擎调用堆栈顶部代理的Execute例程–RoomLine。这是一个对话代理,它基于其执行策略和子代理的先决条件,决定它需要首先使用登录代理。因此,它会将登录推送到对话框堆栈上—参见图6,步骤2,并将控件返回到对话框引擎。接下来,对话框引擎从对话框堆栈中弹出所有已完成的代理。由于RoomLine和登录都尚未完成,对话框引擎通过调用错误处理决策过程继续。在这种情况下不采取错误处理操作。2接下来,对话框引擎检查焦点声明,但此时不存在焦点声明。因此,对话引擎将进入一个新的执行阶段。这一次,Login位于堆栈的顶部,因此对话框引擎调用Login.Execute。Login将Welcome代理推送到对话框堆栈上,并将控件返回到对话框引擎-参见图6,步骤3。同样,没有完成任何代理,没有采取任何接地措施,也没有焦点声明。接下来,对话框引擎执行Welcome。这是一个通知代理,它将向用户发送欢迎消息。系统说:“欢迎使用RoomLine,会议室预订助理”。接下来,当对话框引擎检查完成条件时,它将发现Welcome已完成(在代理输出提示后立即通知complete),因此它将从执行堆栈中弹出Welcome–见图6,步骤4。在下一个执行阶段,再次调用Login.Execute。这一次,由于欢迎代理已经完成,登录代理将通过在对话框堆栈上推送AskRegistered代理来计划执行它-参见图6,步骤5。同样,堆栈上的代理都没有完成,没有采取任何接地操作,也没有提出焦点声明。当对话引擎下一步执行AskRegistered时,此代理将输出一个请求–“您是注册用户吗?”?,然后通过向对话框引擎传递特定的返回代码来调用输入阶段。下一小节将讨论输入阶段。
The input phase
在第一阶段,系统将期望议程(expectation agenda)组装起来,这是一个描述系统在当前回合中期望从用户那里听到什么的数据结构。议程分为多个层次。每个层次对应于对话堆栈上的一个代理,因此对应于特定的语篇段。对话框引擎从顶部元素到底部遍历堆栈,并在预期议程中构造相应的级别。在上面描述的示例中,在AskRegistered代理触发一个输入阶段之后,堆栈立即包含AskRegistered、Login和RoomLine代理–请参见图6,步骤5。因此,对话引擎通过收集AskRegistered代理的期望值来构建议程的第一级。AskRegistered代理希望听到已注册concepts的值,其形式为输入中的[是]或[否]语法槽。议程中的第二层是通过收集堆栈上下一个代理(即登录)的期望来构建的。当一个机构宣布其期望值时,默认情况下,它收集其子代理的所有期望值。在这种情况下,登录代理希望同时听到注册concepts(来自AskRegistered代理)和用户名concepts(来自AskUserName代理)。最后,期望议程的第三层(在本例中是最后一层)是通过收集RoomLine代理的所有期望来构建的。除了注册和用户名concepts外,最后一级还包含对话框任务树中所有其他代理的期望值。事实上,期望议程中的层次概括了系统期望听到的内容,从当前的焦点问题开始,并在越来越大的话语片段中移动。
组装好预期议程后,对话框引擎等待用户的输入;这是输入阶段的第二个阶段。
Expectation agenda and mixed-initiative interaction
我们用一个在航空旅行计划领域运行的语音对话系统的例子来说明焦点转移机制。示例如图7所示。在n号转弯处,系统问题是“你会从旧金山回来吗?”?“对应于对话框任务树中的/FlightLine/Leg1/AskReturn代理。此时,用户不再回答系统问题,而是决定询问有关在旧金山预订特定酒店的问题。解码后的输入与议程最后一级的[hotel name]期望值相匹配,酒店名称concepts也相应更新。一旦这个输入阶段完成,系统将继续执行一个阶段。在焦点索赔分析期间,/FlightLine/Hotels代理索赔焦点,因为此代理有一个触发条件,即更新酒店名称concepts。因此,对话框引擎将此代理放置在对话框堆栈的顶部-请参见图7中时间n 1处的堆栈。当对话引擎继续执行时,对话将从Hotels dialog agency继续。一旦hotels子对话框完成,hotels agency将从执行堆栈中弹出,我们将回到上一个上下文中的AskReturn问题。
系统作者可以控制对话框管理器允许用户在对话框中的每一点采取的主动性,方法是控制议程上的哪些期望是打开的,哪些期望是关闭的(关闭的期望不受约束)。默认情况下,由请求或预期代理定义的预期仅在会话焦点与定义预期的代理位于同一主主题下时打开。例如,如果我们的酒店代理被定义为一个主主题(使用IS-main-topic指令),那么在图7的步骤n中,[hotel name]期望将被关闭,并且酒店名称concepts将不会被更新。因此,系统作者可以通过定义树中的主要主题来控制哪些期望是开放的,哪些是关闭的。
可以通过一组期望范围操作符实现更细粒度的控制,这些操作符可用于更改期望的默认激活行为。
- !运算符;定义期望时使用此运算符时(例如![是]>是),只有当定义期望的代理实际上处于焦点时,期望才会打开。
- *运算符;当使用此运算符时,期望值始终是开放的。
- @(<agent_name>;<agent_name>。…)运算符;仅当对话的焦点位于指定列表中的某个代理下时,期望才打开。例如,如果我们希望仅当对话在旅行的第一段而不是第二段时才允许hotel-name concepts绑定,那么期望可以定义为@(/FlightInfo/Leg1;/FlightInfo/Hotels)[HotelName]
基于上下文的语义消歧
考虑图8中的示例,该示例同样来自在空中旅行域中操作的虚拟系统。对话的焦点是AskFrom请求代理,该代理负责获取行程第一段的出发城市。此代理声明了对from_cityconcepts的两个期望值:[FromCity],它捕获诸如“我想从旧金山离开”之类的结构,以及[city]捕获孤立地说出的城市名称,例如“San Francisco”。同时,到达子树中的AskTo请求代理还声明期望值[城市]和[城市],以便在to_cityconcepts中捕获到达城市。用户用一个简单的城市名称来回答系统问题,这个名称在语义上被解码为[城市]。由此产生了一种语义上的歧义:这座城市应该与“从城市”concepts相联系,还是与“到城市”concepts相联系?在concepts绑定阶段,通过自上而下遍历议程,可以自动解决歧义。在这种情况下,输入会更新from_city concepts,因为它出现在议程的更高级别(在本例中是第一级)。
因此,期望议程自动实现了一个歧义消解启发式:如果一个输入可用于更新多个concepts,则始终更新最接近当前上下文的concepts,即议程中较高的concepts,我们认为该concepts模仿了人类对话中使用的启发式。
动态特定语言建模
支持动态的、特定于上下文的语言建模。在对话框中的每个回合,期望议程都会在语义级别捕获系统期望从用户那里听到的内容。这些信息可以通过插入大量较小的、固定的语言模型来动态地构造特定于上下文的识别语言模型,从而提高识别精度(Xu和Rudnicky,2000)。例如,考虑到图8中的示例,系统可以通过插入[是]、[否]、[来自城市]、[城市]、[城市]等的模型来创建特定于状态的语言模型。
RavenClaw对话框管理框架中的错误处理
体系结构概述
RavenClaw对话框管理框架中的错误处理架构包含两个主要组件:(1)一组错误恢复策略,和(2)在适当时间触发这些策略的错误处理决策过程-见图9。
错误恢复策略分为两类:(1)从误解中恢复的策略(例如,显式和隐式确认)和(2)从不理解中恢复的策略(例如,要求用户重复、要求用户重新措辞、提供帮助等)。这些策略是使用前面描述的RavenClaw对话框任务规范形式主义编写的,它们可用作库对话框代理。系统作者只需指定对话管理器应该使用哪些策略,并相应地配置它们。
处理潜在错误的责任委托给错误处理决策过程(sequel中的EHDP),它是RavenClaw对话框引擎的子组件。在每个执行阶段,EHDP收集可用的证据,并决定应该采用哪种错误恢复策略(如果有的话)。如果认为有必要执行操作,EHDP将创建相应错误恢复策略的实例,相应地对其进行参数化,并将其推送到对话框堆栈上。实际上,EHDP更改了对话框任务,以确保相应地处理潜在的错误例如,在图9所示的示例中,基于置信度得分,对话框引擎决定触发对开始时间concepts的明确确认。因此,引擎实例化了一个ExplicitConfirm对话框代理(它实现了一个显式的确认策略),通过传递一个指向要确认的concepts的指针(在本例中为start_time)对其进行参数化,并将其放在对话框堆栈上。接下来,战略执行。完成后,它将从堆栈中移除,对话框将从它停止的位置继续。在显式确认的执行过程中,所有其他的对话框控制机制仍然存在;例如,用户可以请求更多的帮助,甚至改变当前的对话框主题。
错误恢复策略
根据所解决的问题类型,RavenClaw对话管理框架中的错误恢复策略可以分为两组:(1)处理潜在误解的策略和(2)处理不理解的策略。目前的一系列策略如表1所示。
参考文献
The RavenClaw dialog management framework: Architecture and systems