How to Develop an EndtoEnd Chatbot using RASA Framework
作者:禅与计算机程序设计艺术
1.简介
Chatbot作为一个新兴的研究领域,正在逐步发展并渗透到人们的生活方方面面。它能够协助用户从简单的查询逐渐发展到处理复杂的任务,在即时通讯、社交媒体以及电子邮件等多种渠道中,提供高效且精确的信息服务。在开发过程中,基于知识图谱的NLU引擎被视为不可或缺的关键组件。
作为一款开源平台上的核心组件,RASA框架为自然语言理解提供了强大的支持。它命名灵感来自于其开发者设计的智能服务机器人——Rasa,而Rasa则是一款专业的智能对话辅助工具。基于Python语言开发的RASA框架,不仅提升了代码的可维护性,还显著简化了部署和运行流程。目前,RASA已经被广泛认可为事实上的NLU引擎标准,广泛应用于医疗保健、金融、旅游、音乐、娱乐等多个行业领域。
本文将通过实例展示如何构建一个基于RASA框架的简单问答机器人系统。完成阅读后,读者将熟悉RASA框架的工作流程,并主动掌握如何基于该框架构建更复杂的业务需求。
2.基本概念及术语介绍
2.1 概念
2.1.1 什么是Chatbot?
Chatbot被设计为一种基于对话交互机制与用户进行交流,实现信息交流、提供服务支持或处理用户需求的客服机器人。
典型的Chatbot场景如下:
个人助理:如通过自动电话和短信系统向用户发送信息;
在线服务:提供咨询、事务处理、售后服务等多种在线服务;
会议助手:支持会议预约、点单等功能的辅助工具;
聊天群组:让群内所有成员能够便捷地与他人互动的聊天机器人;
广告推送:推送品牌信息、促销活动及最新资讯;
游戏辅助:帮助玩家模拟游戏角色、解答经典问题等;
支付系统:为用户提供即时、安全的在线付款服务。
其中,利用NLP技术开发的Chatbot具有以下特点:
自然语言理解:通过自然语言生成对话,并对语句进行分类处理和关键信息提取,从而实现自然流畅、连贯的对话交流;
对话管理:支持多轮对话,通过反馈机制判断用户是否真正需要服务,增强人机对话的自适应能力;
持续学习:基于用户的反馈信息持续优化对话策略,提升服务质量。
2.1.2 为什么要使用RASA?
RASA是一个开源的NLU引擎框架,以Python为开发语言。如今,RASA已成为多个行业采用的标杆NLU引擎,涵盖医疗保健、金融、旅游、音乐和娱乐等多个领域。
RASA框架包括四个主要模块:
- NLU模型:主要负责实体识别、意图识别以及槽值填充等功能模块;
- Core算法:主要基于检索式对话管理,能够处理多轮对话并跟踪系统状态;
- Action插件:提供自定义动作,负责对话逻辑的实现;
- 训练组件:整合了数据标注、训练、评估、微调等功能模块。
2.2 RASA相关术语介绍
2.2.1 Domain文件
Domain文件涵盖了系统涉及的领域和实体。它定义了对话中的用户、组、领域词汇、动作、意图以及相关的训练数据等其他相关信息。
2.2.2 Training Data
Training Data由机器学习系统所需的数据构成,由许多对话样例组成。系统经过对这些样例的训练,以改善对话系统的性能。
2.2.3 Intent与Entity
Intent指的是用户希望实现的目标,如咨询、预订机票或购物等。实体则用于描述实现这些目标所需的必要参数,如出发地、目的地和日期等。
2.2.4 Slots
Slots代表用户提供的简短信息,如时间、金额等。在对话过程中,这些信息被存储在临时的内存空间中。
2.2.5 Actions
Actions是对话系统中响应用户请求的指令。Action插件可以用来定义对话的业务逻辑。例如,在购物车页面,用户点击结算按钮后,系统调用结算Action插件进行订单结算。
2.2.6 Tracker与Story
Tracker主要负责对话状态的记录,能够追踪用户的输入、回答和对话历史记录。Story是由一系列对话按照顺序组成的集合。Story可以由多个故事片段组成,每个片段包含用户输入、系统响应以及槽位更新等信息。
2.2.7 Policy与Rules
Policy是一种机器学习算法,用于指导系统执行特定行为。规则能够使系统根据特定条件执行特定行为。例如,当用户指示“帮我查一下明天的天气”时,规则系统将从本地数据库中检索明天的天气信息,并将结果返回给用户。
2.2.8 Server与Client
在机器学习系统中,Server扮演着主节点的角色。它处理外部命令、数据和请求,并与系统中的其他模块进行数据交互。在对话系统中,Client充当用户接口,负责将用户的输入和系统输出的消息展示给用户。
3.核心算法原理与操作步骤
3.1 NLU模型
RASA的NLU模型基于通用领域实体标签识别机制。通过该方法,RASA能够识别不同领域中的实体,并将其与相关数据进行关联。
实体识别策略主要分为基于规则的策略和基于统计的学习策略两类。基于规则的策略通过预先定义明确的规则,能够有效地识别出实体信息。基于统计的学习策略利用自然语言处理技术,通过对对话文本进行分析,识别出最可能属于特定类别的词汇。
3.1.1 实体识别
实体识别作为NLU的初始阶段。在这一阶段,RASA将输入的文本划分为连续的单词序列。随后,系统将每个单词与预先训练的词汇表进行匹配。对于无法归类为已知实体或未知实体的单词,系统将不会进行标记。
当已知实体存在时,RASA系统会将该实体的类型和值赋值到对应的槽位中。若无已知实体,则RASA将未知实体存储于unseen\_entities列表中。
3.1.2 意图识别
在NLU流程中,意图识别被视为第二步。在这一阶段,RASA通过将用户输入的文本与预先定义的意图集合进行匹配来执行意图识别。当某个意图与输入文本的相似度超过预设阈值时,系统将识别该输入文本的意图为此意图。否则,RASA将该输入文本归类为无意图状态。
RASA使用了几个不同的技术来进行意图识别:
Memoization Technique
Memoization是一种基于动态规划的算法。该算法通过递归来构建转移矩阵,这个转移矩阵记录了不同意图之间的转移概率。通过Memoization,RASA能够在O(n)的时间复杂度内计算出输入句子的最大概率意图。
CRF Technique
CRF(Conditional Random Fields)被定义为条件概率模型。该模型特别适用于序列标注问题的求解。RASA系统通过CRF模型推导出每个单词在不同语境下的条件概率。CRF模型通过估计每个非标注位置的标签,从而使得学习过程更加精细化。
Embeddings Technique
Embedding方法通过将单词转换为定长向量来实现信息的量化。通过Embedding技术,NLU模型能够提取单词间的联系和相似性。RASA采用了基于BERT的word embeddings作为预训练模型,该技术通过大规模语料的训练提取语义信息。通过该预训练模型,RASA能够在训练过程中显著提升其性能水平。
3.1.3 Slot Filling
在NLU流程中,Slot filling被定位为第三步。在这一阶段,RASA系统致力于填充用户所提出的槽位信息。槽位被视为一个临时存储单元,用于暂存所需的信息。槽位填充过程通常需要结合实体识别和意图识别来实现。
系统RASA会为每个槽位字段确定一个具体值。候选值列表基于训练数据中的潜在候选值构建。每个槽位的候选值项可以由用户在对话中呈现给系统。
槽位填充策略遵循规则进行。RASA将首先评估当前槽位值的完整性。当槽位值不足时,RASA将相应地将槽位字段留为空。
3.2 Core算法
Core算法负责管理对话。Core算法的核心功能包含负责处理多轮对话、负责跟踪系统状态以及负责抽取式对话管理。
3.2.1 多轮对话管理
多轮对话处理功能是Core算法体系中的一个核心功能。RASA系统采用记忆回环机制来处理多轮对话。记忆回环机制是一种递归算法,能够有效记录对话状态并整理对话历史。
RASA依靠记忆重用技术来避免内存占用。该技术会将之前遇到的相同对话进行存储,从而避免重复出现。
3.2.2 系统状态跟踪
系统状态跟踪是Core算法的一个重要功能。RASA通过利用Tracker来跟踪对话的状态。Tracker是一个对象,它包含了对话的状态,包括当前的槽位值、对话轮次、对话历史以及用户输入等信息。
RASA通过规则来管理对话状态。这些规则体系可以用来指定系统应该采取哪些动作,以便响应用户的输入。
3.2.3 抽取式对话管理
作为Core算法的重要组成部分,抽取式对话管理承担着关键角色。RASA依赖实体抽取器,从用户输入中提取相关信息。实体抽取器能够识别用户输入中的实体(如日期、地址、数字等),并将其存储到tracker的对应槽位中。
RASA的训练数据集被大量涵盖了许多例子,这些对话示例可以丰富地呈现给模型。当对话示例数量增加时,RASA的抽取模型的精确度会显著提升。
3.3 Action插件
在RASA系统中,Action插件被设计用于定义对话逻辑的组件。该插件可指导系统执行特定任务,如搜索信息、执行查询、交换意图或确认用户需求。
RASA提供了几种类型的Action插件:
Simple Actions
Simple Action属于基础类的Action插件。它包含一些基础操作,例如,可以发送一条消息给用户,或者推荐一些电影给他们。
Form Actions
Form Action用于收集用户的输入信息。在电商平台中,Form Action可以引导用户填写必要的个人信息,从而完成订单的支付流程。
Custom Actions
Custom Action则可赋予系统完全定制化的业务逻辑支持。基于关键字的Action则可通过用户输入的文本实现语音交互。
3.4 训练组件
该训练组件通过在RASA系统中整合多种功能模块,实现了数据标注、训练、评估和微调等功能。
RASA的训练组件涵盖多个关键环节,包括训练对话模型的过程、数据标注任务、模型微调阶段、模型评估环节以及模型发布阶段。这些功能模块共同构成了完整的训练体系。
训练组件还有一个另一个主要功能,即模型压缩技术。RASA利用模型压缩技术来降低模型体积,并通过模型量化方法减少计算负担。
4.具体代码实例及解释说明
为了深入掌握RASA框架的工作流程,我们可以以问答机器人为例,展示其具体代码实现。
4.1 安装配置RASA
为了安装和配置RASA,请参考官方文档。
4.2 创建项目文件夹结构
建立一个名为chatbot的文件夹,并在其内部分别创建三个子文件夹,命名为data、domain和models。
├── chatbot
├── data
│ └── nlu.md # 对话训练数据集
├── domain # 项目领域定义文件
│ ├── domain.yml # 领域配置文件
│ ├── entities # 实体定义文件目录
│ │ ├── entity.md # 实体模板
│ ├── intents # 意图定义文件目录
│ │ ├── intent.md # 意图模板
│ ├── slots # 槽位定义文件目录
│ │ ├── slot.md # 槽位模板
├── models # 模型存放目录
└── default # 默认模型
├── core # 核心算法模型
│ ├── processor.pkl # 处理器
│ ├── featurizer.pkl # 特征提取器
│ ├── classifier.pkl # 分类器
│ ├── entities_model.pkl # 实体抽取器
│ ├── policy_network.pkl # 策略网络
│ └── vocab.pkl # 词典
├── policies # 策略目录
├── stories # 对话示例目录
├── config.yml # 配置文件
├── metadata.json # 模型元数据
└── training_data.json # 训练数据
代码解读
4.3 数据准备
在训练RASA的自然语言理解模型时,我们需准备一份对话训练数据集。目前,我们采用的对话训练数据集是RASA官方提供的Demo数据集。但由于命名不规范,导致直接使用该数据集存在困难。因此,我们对数据集进行了改名,命名为nlu.md,并将其放置于chatbot/data文件夹中。
├── data
└── nlu.md # 对话训练数据集
代码解读
4.4 Domain文件的编写
定义RASA项目的领域需要编写domain.yml文件。domain.yml文件明确了我们的对话系统领域。
我们在domain.yml文件中写入以下内容:
version: "2.0"
session_config:
session_expiration_time: 60 # session过期时间,单位秒
carry_over_slots_to_new_session: true # 是否跨会话传递槽位
intents:
- greet # 问候
- goodbye # 撤回
- search_restaurant # 查询餐厅
- request_restaurant_info # 请求餐厅详情
- offer_book_table # 提供预约服务
responses:
utter_greet: # 问候语模版
- text: "你好!"
utter_goodbye: # 撤回语模版
- text: "再见,欢迎下次光临!"
utter_default: # 默认回复模版
- text: "抱歉,我没有理解您的意思。"
utter_search_restaurant: # 查询餐厅语料库
- text: "您可以问我关于{}的任何问题。"
utter_request_restaurant_info: # 请求餐厅详情语料库
- text: "抱歉,我无法满足您的要求。"
utter_offer_book_table: # 提供预约服务语料库
- text: "好的,{name},您的预约已提交,请稍后等待。"
actions: # action定义
- utter_default
slots:
name:
type: text
influence_conversation: false
forms: {}
代码解读
其中,version参数设置为'2.0',表示采用了RASA的2.x版本。session_config用于配置对话会话的相关参数,session_expiration_time表示会话的有效时长,而carry_over_slots_to_new_session指示是否将槽位传递到新会话中。
|intents是项目的意图清单,其中包含问候、撤回、查询餐厅、请求餐厅详情、提供预约服务五种。responses是模板消息,用于输出用户信息。actions定义系统的动作,其中默认回复是utter_default。
槽位名称是项目的槽位清单,其中包含name字段,name字段是文本类型的槽位,influence_conversation属性被设置为false,表示该槽位不会影响对话的关键路径。
forms是项目的表单清单,这里为空,因为我们不需要收集用户输入。
4.5 Training Data的编写
为了构建RASA的自然语言理解(NLU)模型,我们首要任务是准备一份高质量的对话训练数据集。我们采用的对话训练数据集是RASA官方提供的Demo数据集,但因其中文命名不规范,导致无法直接使用。因此,我们对原始数据集进行了重命名为nlu.md,并将其放置于chatbot/data文件夹中。
训练数据集支持包含Markdown和JSON格式两种数据形式。具体来说,我们采用的是Markdown格式,建议将nlu.md文件复制粘贴到chatbot/data/nlu.md的指定路径中。
nlu.md文件内容示例:
## intent:greet
- 你好
- 您好
- 早上好
- 上午好
## intent:goodbye
- 再见
- 走吧
- 拜拜
## intent:search_restaurant
- 找个[北京](location)的[德国](cuisine)餐厅看看
- 查找[纽约市](location)有没有[巴黎](cuisine)的店
- 找一家[日本料理](cuisine)的餐厅吃饭
- [东京](location)有没有便宜点的[火锅](dish)
- 去哪里吃[泰国](location)[烧腊味蕾](dish)
## intent:request_restaurant_info
- 麻烦您详细介绍一下这家餐厅吧
- 请问这家店的营业时间是多少
- 可以告诉我这家餐厅的地址吗
- 请问这家店的电话号码是多少
## intent:offer_book_table
- 可以预约一下[10月20日](date)的[8:00](time)的[北京菜馆](place)的[空闲](people)桌位
- [2019年3月25日](date)的[星期三](dayofweek)有空余的[西湖边餐厅](place)
- 能否安排[六点半](time)的[莫斯科](place)附近的[五人餐厅](people)
- 有空的话[周五晚上九点](date)[南山派拉蒙酒店](place)的[15号楼1005](room)还有没有位置
- 请问[{name}](name),您的预约是什么时候呢?
## synonym:北京 city
- beijing
- bj
- 北京
## synonym:纽约 location
- new york
- nyc
- nyc
- ny
- 纽约
## synonym:巴黎 cuisine
- tapas
- pitti
- pita
- pizza
- panino
- broodjes
- francesinha
- 巴黎
## synonym:日本 cuisine
- sushi
- japanese
- sakura
- ramen
- 和風ジャーマン
- 和田玉子
- 日本料理
## synonym:东京 location
- tokyo
- 东京
## synonym:泰国 location
- yangon
- thailand
- taipei
- 泰国
## synonym:烧腊味蕾 dish
- pahu hua lew
- pha lan viet nam
- littl eboockh laotian
## regex:^[0-9]+$ time
- [0-9]+:[0-9]+
## lookup:dates date
- today
- tomorrow
- monday
- tuesday
- wednesday
- thursday
- friday
- saturday
- sunday
- {date}
## lookup:locations place
- 北京菜馆
- 大胡同西口
- 友爱道
- 美食街
- 西湖边餐厅
## lookup:days dayofweek
- 星期一
- 星期二
- 星期三
- 星期四
- 星期五
- 星期六
- 星期日
## lookup:people people
- 一人
- 两人
- 三人
- 四人
- 五人
## lookup:rooms room
- 15号楼1005
- A座301
- B座203
## lookup:names name
- 小罗
- 小李
- 小米
- 小刘
- 小杨
代码解读
4.6 使用RASA训练模型
通过运行rasa train命令可以实现模型的训练。在chatbot文件夹中,执行以下命令:
cd models
rasa train
代码解读
该命令将引发训练流程的启动,基于指定的训练数据,该系统将生成一个新的模型。经过训练后,生成的模型将被存储在预设的models/default文件夹中。
4.7 测试模型
使用RASA的模型测试仅需运行rasa shell命令。在chatbot文件夹下,建议进入models文件夹并执行以下命令:
cd models
rasa shell
代码解读
通过这个命令,RASA将启动命令行界面。你可以输入对话示例指令,RASA将返回相应的回应。
我们输入以下对话示例:
>> hello
>>> 你好,我可以帮您做些什么呢?
>> what can you do?
>>> 我可以查询餐厅、预约餐厅、提供咨询服务。
>> find a restaurant in [nyc](location), with [chinese food](cuisine)
>>> 恭喜你,正在为您查找餐厅...
---
loc: nyc, cuisine: chinese food, restaurants: 恭喜你,查找到了这家餐厅。名称为XX餐厅,地址为XX路XX号,营业时间为XX:XX~XX:XX,菜系为XX。电话号码为XX-XXX-XXXX。在此期间,你可以预约,也可以咨询。谢谢您的使用。
>> I want to book a table at the Chinese restaurant for next Monday, between 1pm and 3pm
>>> 好的,小米,您的预约已提交,请稍后等待。
代码解读
