基于LLM的任务型对话系统:论文《Task-Oriented Dialogue with In-Context Learning》思路

Task-Oriented Dialogue with In-Context Learning

Task-Oriented Dialogue with In-Context Learning》(论文实验github)是Rasa团队在2024年2月发布的论文,是其Rasa pro功能CALM(Conversational AI with Language Models)对应的论文,它描述了用LLM的in-context learning能力与确定的业务逻辑一起来实现一个任务型对话系统(LLM会将对话翻译成推进业务逻辑的领域语言(domain-specific language, DSL)。

基于意图的NLU方法的局限性

一个典型的对话型系统或助手是一个模块化架构,由三部分组成:自然语言理解(natural language understanding, NLU),对话管理(dialogue management, DM),自然语言生成(natural language generation, NLG)。

用户与对话型系统交互时的话语被NLU翻译成对话行为(dialogue atcs),一个对话行为包括一个意图(intent)和一系列实体(entities),比如"I need a taxi to the station" 可能会被分类为意图“book_taxi"和取值为“station"的实体”destination"。这个对话行为作为NLU和DM之间的接口。DM包含将”book_taxi“意图初始化为一个出租车预订任务的逻辑,并让用户输入时间、接人地点等,这些字段通常被称为槽位(slots)。随着对话的进行,用户接下来的信息也被表示成对话行为比如”inform(time=3pm)“;而DM根据基于规则或基于模型的对话策略(dialogue policy)来对这些输入序列做出响应,执行动作并回复用户。

论文将前述流程称为基于意图的NLU方法(intent-based NLU approach),它的主要特点是将自然语言理解作为一个分类任务,用户消息通过分配一个预定义的意图来被”理解“。但是论文作者认为用一些固定的意图来理解自然语言有如下限制:

  • 当意图的个数达到几百个,意图的分类法很难被记住和推理,使得标注和反馈、debug都变得很复杂。
  • 因为DM被编码成期望对特定的意图序列作出回应,对意图定义进行改变或者引入新的意图就很容易使得对话系统出错。
  • 意图通常被定义为助手能够完成的任务的映射,但是用户输入通常不直接与某一个任务对应。比如开发者可能创建了”replace_card“和”block_card“,但是用户会用自己的语言去描述情景(比如”I lost my wallet“),它们可被映射到多个不同的任务。
  • 消息没有考虑上下文,总会被分配给同一个意图。(论文注:这一点或许可通过在NLU模块添加一些假设或者训练包含对话历史的监督型模型来克服,但是实际上这些方法很少被广泛应用)
  • 一般DM只考虑NLU模块的输出作为上下文,比如DM会问用户一个yes/no问题来填充一个boolean槽位(如“Would you like to proceed?”),当用户的回复被映射到affirm或deny意图,DM重新解释这些输出并相应地将boolean槽位设置成true或false。 类似地,NLU模块可能识别一个通用实体如person或location,需要再将它们映射到任务相关的槽位如“transfer recipient” 或 “taxi destination”。

框架思路

RASA基于LLM的任务型对话系统的包括三个主要组件:对话理解(Dialogue Understanding)、业务逻辑(Business Logic)、对话修复(Conversation Repair)。当一个用户给对话系统发消息时,会有如下过程:

  1. 对话理解模块结合到目前为止的对话记录将用户最新消息翻译成一系列的命令。
  2. 这些命令经过DM的校验和处理后用来更新对话状态。
  3. 如果用户消息需要进行对话修复,对应的修复模式也被添加到对话状态。
  4. DM确定性地执行相关业务逻辑,包括修复模式等,并继续执行操作,直到需要额外的用户输入。
对话理解

对话理解模块作为传统的NLU模块的替代,利用了LLM的in-context learning能力,它将对话理解作为一个命令生成问题。

对话理解模块的输出是一个命令(command)序列,这个序列用来描述用户想如何与助手推进当前对话。允许的命令如论文表1所示。

在这里插入图片描述

下面是两个对话理解的输入输出例子:

#### 例子1 ####
## 输入
"I want to transfer money"
## 输出
StartFlow(transfer money)

#### 例子2 ####
## 输入
"I want to transfer $55 to John"
## 输出, 可以直接进行槽位映射
StartFlow(transfer money), 
SetSlot(recipient, John), 
SetSlot(amount, 55)

对话的上下文会被考虑,所以如下示例的槽位也能被正常处理。

在这里插入图片描述

用户纠正输入,开始另一个任务的例子

在这里插入图片描述

业务逻辑

业务逻辑描述了如何完成一个具体任务需要进行的步骤,比如转账(transfering money)。任务被定义成声明式形式的flows。一个最小形式的flow包括一个描述和一系列的步骤,这些步骤描述了:1. 需要从用户那里获取什么信息(如转账金额和收款人),2. APIs需要什么样的信息(如用户账户是否收支平衡),3. 其他基于所收集信息的分支逻辑。

下面是一个最小化形式的transfer_money flow的例子,定义了基本逻辑

transfer_money: 
	description: send money to another account
	steps: 
		- collect: recipient
		- collect: amount
		- action: initiate_transfer

flow是开发者定义的,除了上述flow定义外,完成任务还需要定义槽位的类型,但这两部分就是实现一个任务的全部代码了,不需要额外的训练语言理解的训练数据。

slots: 
	recipient:
  	type: text 
  amount: 
  	type: float 
responses: 
	utter_ask_recipient: 
		- text: Who are you sending money to? 
	utter_ask_amount: 
		- text: How much do you want to send?

下图是一个更复杂的flow定义

在这里插入图片描述

所以业务逻辑只是描述了完成一个任务所需要的步骤,不需要指出用户是如何提供这些信息的。flow只定义了"happy path"。

对话修复

对话修复定义了模式(patterns)集合,模式是描述当对话偏离flow定义的”happy path"时助手如何行动的meta flows。而”happy path“是指在collect步骤时用户成功提供了所需信息,使业务逻辑走到下一步的对话。

而实际上用户经常会偏离happy path,比如:

  • 取消了当前交互流程
  • 在继续当前流程之前,打断当前流程先完成其他的事情
  • 要求额外的信息
  • 插入题外话,比如"just one moment"
  • 纠正之前说过的话
  • 说了需要进一步澄清的话

对这些常见场景,对话修复提供了模式,这些模式通过特殊命令如CancelFlow或指定对话状态已经达到来触发。 比如插入的flow完成或取消时,之前被中断的flow被重启时一个特定的模式会被触发。

比如下面的例子开发者定义了多个card相关任务的流,澄清会被触发。(作者认为”card“或者”cancel“ 很难用来指代特定意图。并且用户发了非常长的消息时通常也要求澄清,基于意图的NLU很难处理这些场景)

在这里插入图片描述

Dialogue Stack

系统用一个对话栈来处理命令和执行业务逻辑。对话栈维护一个存储了active flows以及其状态的后进先出的栈(Last-in-first-out(LIFO))。

对话栈可以提供额外的上下文信息给对话理解模块,比如active flow有哪些槽位要填充,槽位类型以及允许的值是什么,这可以帮助LLM生成正确的命令。 而LLM生成的命令可以设置对话栈里的槽位,开启新的flow,但不会直接去操作对话栈。

当所有的命令都处理过了,DM接管对话栈并确定性地执行最上面的flow,当它到达listen步骤时执行停止。

其他组件
  • Contextual Response Rephraser: 用LLM改写模板,改写会考虑对话上下文以提高流畅度。比如下面的例子,但是这个改写不一定总能保持与模板一样的含义,取决于LLM、prompt、采样率参数,需要开发者进行权衡。
    在这里插入图片描述

  • Flow Pre-Selection: 当助手要处理的任务个数不断增加,输入给LLM的信息可能会超过LLM的上下文窗口。所以对话理解组件可以预先选择一些候选flow作为LLM的上下文。通过比较最新用户消息与flow的描述信息的向量相似度,取top k个最相似的流。作者的试验是k=20时遗漏正确flow的可能性就非常小了。

  • Information Retrieval: 处理用户问题里可通过静态数据来回答的问题,对应到的命令是KnowledgeAnswer,以对话修复里的模式来处理。(这就是基于知识库的问答或RAG的流程 )

总结

RASA提出的这个基于LLM的任务型对话系统用LLM来实现对话理解,去掉了基于意图分类的NLU模块。按照论文的实验结论,相比原来的RASA效果好很多。

在这里插入图片描述

参考资料

  1. Task-Oriented Dialogue with In-Context Learning

  2. 两篇关于去掉intent的rasa博客: 12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值