热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

rasa算法_智能问答rasa框架02自定义action

问答机器人框架中非常重要的几个概念为意图识别、槽位填充通常使用机器学习算法进行意图的分类,但最终我们是让将用户的输入提取出我们想要的核心信息。--槽位提取因此slot

问答机器人框架中非常重要的几个概念为意图识别、槽位填充

通常使用机器学习算法进行意图的分类,但最终我们是让将用户的输入提取出我们想要的核心信息。--槽位提取

因此slot在rasa中极为重要, 如何我们想要深入自定义slot,以及solt前后逻辑,那么FormAction是必须要了解清楚的。

位于rasa_sdk/forms.py

class FormAction(Action):def name(self) -> Text:"""Unique identifier of the form"""raise NotImplementedError("A form must implement a name")@staticmethoddef required_slots(tracker: "Tracker") -> List[Text]:"""A list of required slots that the form has to fill.Use `tracker` to request different list of slotsdepending on the state of the dialogue"""raise NotImplementedError("A form must implement required slots that it has to fill")

源码中可以看到name,required_slots,是必须实现的函数,作用是告诉rasa 此action都有哪些slot,此aciton名为什么,rasa官方demo中也如此进行了简介

class SalesForm(FormAction):"""Collects sales information and adds it to the spreadsheet"""def name(self) -> Text:return "sales_form"@staticmethoddef required_slots(tracker) -> List[Text]:return ["job_function","use_case","budget","person_name","company","business_email",]

那么rasa将按照required_slots list顺序进行slot填充

流程是一致的,我们在story中定义意图以及匹配此意图是的机器人行为,

我们想要使用自定义的action,需要在 domain.yml 和stories.md中进行配置

## sales form
* contact_sales- sales_form - form{"name": "sales_form"} - form{"name": null}

domain中定义fromaction

forms:- sales_form

当我们运行 rasa run, 和 新开一个窗口 rasa run actions时,会进行sales_form注册到rasa中

python ../start.py run actions
2020-09-07 14:03:54 INFO rasa_sdk.endpoint - Starting action endpoint server...
2020-09-07 14:03:54 INFO rasa_sdk.executor - Registered function for 'sales_form'.
2020-09-07 14:03:54 INFO rasa_sdk.endpoint - Action endpoint is up and running on http://localhost:5055

重点知识-story中的定义的何时触发action, domain.yml 中定义。

运行之后,发现会自动识别每一个slot槽位的,向用户提问。这里是因为formaction会自动循环required_slots中的slot,同时自动匹配 domain.yml utter_ask_+ 意图。

源码中此处进行了定义

def request_next_slot(self,dispatcher: "CollectingDispatcher",tracker: "Tracker",domain: Dict[Text, Any],) -> Optional[List[EventType]]:"""Request the next slot and utter template if needed,else return None"""for slot in self.required_slots(tracker):if self._should_request_slot(tracker, slot):logger.debug(f"Request next slot '{slot}'")dispatcher.utter_message(template=f"utter_ask_{slot}", **tracker.slots)return [SlotSet(REQUESTED_SLOT, slot)]# no more required slots to fillreturn None

因此我们可以重写request_next_slot,做前后slot信息验证

def validate_business_email(self, value, dispatcher, tracker, domain) -> Dict[Text, Any]:"""Check to see if an email entity was actually picked up by duckling."""if any(tracker.get_latest_entity_values("email")):# entity was picked up, validate slotreturn {"business_email": value}else:# no entity was picked up, we want to ask againdispatcher.utter_message(template="utter_no_email")return {"business_email": None}

函数定义以 validate_ + slot rasa将自动进行输入校验

源码定义如下:

async def validate_slots(self,slot_dict: Dict[Text, Any],dispatcher: "CollectingDispatcher",tracker: "Tracker",domain: Dict[Text, Any],) -> List[EventType]:"""Validate slots using helper validation functions.Call validate_{slot} function for each slot, value pair to be validated.If this function is not implemented, set the slot to the value."""for slot, value in list(slot_dict.items()):validate_func = getattr(self, f"validate_{slot}", lambda *x: {slot: value})if utils.is_coroutine_action(validate_func):validation_output = await validate_func(value, dispatcher, tracker, domain)else:validation_output = validate_func(value, dispatcher, tracker, domain)if not isinstance(validation_output, dict):logger.warning("Returning values in helper validation methods is deprecated. "+ f"Your `validate_{slot}()` method should return "+ "a dict of {'slot_name': value} instead.")validation_output = {slot: validation_output}slot_dict.update(validation_output)# validation succeed, set slots to extracted valuesreturn [SlotSet(slot, value) for slot, value in slot_dict.items()]

定义特定槽位的用户输入验证,有时候还是无法满足我们需求,我们得自定义request_next_slot, 方法中放飞自我

def request_next_slot(self,dispatcher: "CollectingDispatcher",tracker: "Tracker",domain: Dict[Text, Any],) -> Optional[List[EventType]]:"""Request the next slot and utter template if needed,else return None"""for slot in self.required_slots(tracker):print(slot)if slot == "person_name" and tracker.get_slot("person_name") == "yxp":dispatcher.utter_message(text="对不起,不欢迎你,走开!!")return self.deactivate()if self._should_request_slot(tracker, slot):print("_should_request_slot")## Condition of validated slot that triggers deactivationif slot == "person_name" and tracker.get_slot("person_name") == "yxp":dispatcher.utter_message(text="对不起,不欢迎你,走开!!")return self.deactivate()## For all other slots, continue as usuallogger.debug(f"Request next slot '{slot}'")dispatcher.utter_message(template=f"utter_ask_{slot}", ** tracker.slots)REQUESTED_SLOT = "requested_slot"return [SlotSet(REQUESTED_SLOT, slot)]print("not _should_request_slot")return None

最后两个重要方法为 slot_mappings, 和 submit

slot_mappings 正如函数名称定义的那样,允许用户进行slot槽位提取时的复杂方式。

比如用户输入 确认意图,填充true,输入否定意图,填充false等

def slot_mappings(self) -> Dict[Text, Union[Dict, List[Dict]]]:"""A dictionary to map required slots to- an extracted entity- intent: value pairs- a whole messageor a list of them, where a first match will be picked"""return {"job_function": [self.from_entity(entity="job_function"),self.from_text(intent="enter_data"),],"use_case": [self.from_text(intent="enter_data")],"budget": [self.from_entity(entity="amount-of-money"),self.from_entity(entity="number"),self.from_text(intent="enter_data"),],"person_name": [self.from_entity(entity="name"),self.from_text(intent="enter_data"),],"company": [self.from_entity(entity="company"),self.from_text(intent="enter_data"),],"business_email": [self.from_entity(entity="email"),self.from_text(intent="enter_data"),],}

最后一个action结束时候,进行最后处理 submit函数为,当收集到所有的意图slot,最终处理方法。

def submit(self,dispatcher: CollectingDispatcher,tracker: Tracker,domain: Dict[Text, Any],) -> List[Dict]:person_name = tracker.get_slot("person_name")import datetimebudget = tracker.get_slot("budget")company = tracker.get_slot("company")email = tracker.get_slot("business_email")job_function = tracker.get_slot("job_function")person_name = tracker.get_slot("person_name")use_case = tracker.get_slot("use_case")date = datetime.datetime.now().strftime("%d/%m/%Y")sales_info = [company, use_case, budget, date, person_name, job_function, email]print(sales_info)dispatcher.utter_message(template="utter_confirm_salesrequest", user_name=person_name)return []

以上,我们完成了FormAction 自定义处理, 可以帮助我们实现复杂的多轮次对话。



推荐阅读
  • 尽管在WPF中工作了一段时间,但在菜单控件的样式设置上遇到了一些基础问题,特别是关于如何正确配置前景色和背景色。 ... [详细]
  • 本文详细介绍了如何使用C#实现不同类型的系统服务账户(如Windows服务、计划任务和IIS应用池)的密码重置方法。 ... [详细]
  • 本文详细介绍如何在SSM(Spring + Spring MVC + MyBatis)框架中实现分页功能。包括分页的基本概念、数据准备、前端分页栏的设计与实现、后端分页逻辑的编写以及最终的测试步骤。 ... [详细]
  • 本文基于Java官方文档进行了适当修改,旨在介绍如何实现一个能够同时处理多个客户端请求的服务端程序。在前文中,我们探讨了单客户端访问的服务端实现,而本篇将深入讲解多客户端环境下的服务端设计与实现。 ... [详细]
  • Spring Security基础配置详解
    本文详细介绍了Spring Security的基础配置方法,包括如何搭建Maven多模块工程以及具体的安全配置步骤,帮助开发者更好地理解和应用这一强大的安全框架。 ... [详细]
  • D17:C#设计模式之十六观察者模式(Observer Pattern)【行为型】
    一、引言今天是2017年11月份的最后一天,也就是2017年11月30日,利用今天再写一个模式,争取下个月(也就是12月份& ... [详细]
  • 本文深入探讨了WPF框架下的数据验证机制,包括内置验证规则的使用、自定义验证规则的实现方法、错误信息的有效展示策略以及验证时机的选择,旨在帮助开发者构建更加健壮和用户友好的应用程序。 ... [详细]
  • 本文详细介绍了如何在Spring框架中设置事件发布器、定义事件监听器及响应事件的具体步骤。通过实现ApplicationEventPublisherAware接口来创建事件发布器,利用ApplicationEvent类定义自定义事件,并通过ApplicationListener接口来处理这些事件。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 深入理解线程池及其基本实现
    本文探讨了线程池的概念、优势及其在Java中的应用。通过实例分析不同类型的线程池,并指导如何构建一个简易的线程池。 ... [详细]
  • Python3爬虫入门:pyspider的基本使用[python爬虫入门]
    Python学习网有大量免费的Python入门教程,欢迎大家来学习。本文主要通过爬取去哪儿网的旅游攻略来给大家介绍pyspid ... [详细]
  • Hibernate全自动全映射ORM框架,旨在消除sql,是一个持久层的ORM框架1)、基础概念DAO(DataAccessorOb ... [详细]
  • 本文详细介绍如何在 Apache 中设置虚拟主机,包括基本配置和高级设置,帮助用户更好地理解和使用虚拟主机功能。 ... [详细]
  • 本文详细介绍了如何在最新版本的Xcode中重命名iOS项目,包括项目名称、应用名称及相关的文件夹和配置文件。通过本文,开发者可以轻松完成项目的重命名工作。 ... [详细]
  • 本文探讨了如何利用RxJS库在AngularJS应用中实现对用户单击和拖动操作的精确区分,特别是在调整区域大小的场景下。 ... [详细]
author-avatar
专业破解王_920
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有