rasa培训课程:Rasa微服务Action自定义及Slot Validation详解


第3课:Rasa微服务Action自定义及Slot Validation详解

 

做Rasa智能对话机器人,微服务Action自定义开发是绕不开的内容,只要做开发,一定会用到Actions、Tracker、Dispatcher、Events

 

Action类是任何自定义操作的基类。要定义自定义操作,请创建操作类的子类,并覆盖两个必需的方法:name和run。当收到运行操作的请求时,Action服务器将根据其name方法的返回值调用操作。

 

 

官网文档的一个示例:

 

class MyCustomAction(Action):

 

def name(self) -> Text:

 

return "action_name"

 

async def run(

self, dispatcher, tracker: Tracker, domain: Dict[Text, Any],

) -> List[Dict[Text, Any]]:

 

return []

rasa server的Action是一个普通的类

 

class Action:

"""Next action to be taken in response to a dialogue state."""

 

def name(self) -> Text:

"""Unique identifier of this simple action."""

 

raise NotImplementedError

 

async def run(

self,

output_channel: "OutputChannel",

nlg: "NaturalLanguageGenerator",

tracker: "DialogueStateTracker",

domain: "Domain",

) -> List[Event]:

"""Execute the side effects of this action.

 

Args:

nlg: which ``nlg`` to use for response generation

output_channel: ``output_channel`` to which to send the resulting message.

tracker (DialogueStateTracker): the state tracker for the current

user. You can access slot values using

``tracker.get_slot(slot_name)`` and the most recent user

message is ``tracker.latest_message.text``.

domain (Domain): the bot's domain

 

Returns:

A list of :class:`rasa.core.events.Event` instances

"""

raise NotImplementedError

 

def __str__(self) -> Text:

"""Returns text representation of form."""

return f"{self.__class__.__name__}('{self.name()}')"

 

def event_for_successful_execution(

self, prediction: PolicyPrediction

) -> ActionExecuted:

"""Event which should be logged for the successful execution of this action.

 

Args:

prediction: Prediction which led to the execution of this event.

 

Returns:

Event which should be logged onto the tracker.

"""

return ActionExecuted(

self.name(),

prediction.policy_name,

prediction.max_confidence,

hide_rule_turn=prediction.hide_rule_turn,

metadata=prediction.action_metadata,

)

 

rasa sdk server的action类:

 

class Action:

"""Next action to be taken in response to a dialogue state."""

 

def name(self) -> Text:

"""Unique identifier of this simple action."""

 

raise NotImplementedError("An action must implement a name")

 

async def run(

self,

dispatcher: "CollectingDispatcher",

tracker: Tracker,

domain: "DomainDict",

) -> List[Dict[Text, Any]]:

"""Execute the side effects of this action.

 

Args:

dispatcher: the dispatcher which is used to

send messages back to the user. Use

`dispatcher.utter_message()` for sending messages.

tracker: the state tracker for the current

user. You can access slot values using

`tracker.get_slot(slot_name)`, the most recent user message

is `tracker.latest_message.text` and any other

`rasa_sdk.Tracker` property.

domain: the bot's domain

Returns:

A dictionary of `rasa_sdk.events.Event` instances that is

returned through the endpoint

"""

 

raise NotImplementedError("An action must implement its run method")

 

def __str__(self) -> Text:

return f"Action('{self.name()}')"

 

 

reminder机器人 复写run方法,重点关注dispatcher: CollectingDispatcher, tracker: Tracker,

 

class ActionSetReminder(Action):

"""Schedules a reminder, supplied with the last message's entities."""

 

def name(self) -> Text:

return "action_set_reminder"

 

async def run(

self,

dispatcher: CollectingDispatcher,

tracker: Tracker,

domain: Dict[Text, Any],

) -> List[Dict[Text, Any]]:

 

dispatcher.utter_message("I will remind you in 5 seconds.")

 

date = datetime.datetime.now() + datetime.timedelta(seconds=5)

entities = tracker.latest_message.get("entities")

 

reminder = ReminderScheduled(

"EXTERNAL_reminder",

trigger_date_time=date,

entities=entities,

name="my_reminder",

kill_on_user_message=False,

)

 

return [reminder]

 

 

executor.py的CollectingDispatcher类

 

 

class CollectingDispatcher:

"""Send messages back to user"""

 

def __init__(self) -> None:

 

self.messages: List[Dict[Text, Any]] = []

 

def utter_message(

self,

text: Optional[Text] = None,

image: Optional[Text] = None,

json_message: Optional[Dict[Text, Any]] = None,

template: Optional[Text] = None,

response: Optional[Text] = None,

attachment: Optional[Text] = None,

buttons: Optional[List[Dict[Text, Any]]] = None,

elements: Optional[List[Dict[Text, Any]]] = None,

**kwargs: Any,

) -> None:

"""Send a text to the output channel."""

if template and not response:

response = template

warnings.warn(

"Please pass the parameter `response` instead of `template` "

"to `utter_message`. `template` will be deprecated in Rasa 3.0.0. ",

FutureWarning,

)

message = {

"text": text,

"buttons": buttons or [],

"elements": elements or [],

"custom": json_message or {},

"template": response,

"response": response,

"image": image,

"attachment": attachment,

}

message.update(kwargs)

 

self.messages.append(message)

 

# deprecated

def utter_custom_message(self, *elements: Dict[Text, Any], **kwargs: Any) -> None:

warnings.warn(

"Use of `utter_custom_message` is deprecated. "

"Use `utter_message(elements=)` instead.",

FutureWarning,

)

self.utter_message(elements=list(elements), **kwargs)

 

def utter_elements(self, *elements: Dict[Text, Any], **kwargs: Any) -> None:

"""Sends a message with custom elements to the output channel."""

warnings.warn(

"Use of `utter_elements` is deprecated. "

"Use `utter_message(elements=)` instead.",

FutureWarning,

)

self.utter_message(elements=list(elements), **kwargs)

 

def utter_button_message(

self, text: Text, buttons: List[Dict[Text, Any]], **kwargs: Any

) -> None:

"""Sends a message with buttons to the output channel."""

warnings.warn(

"Use of `utter_button_message` is deprecated. "

"Use `utter_message(text= , buttons=)` instead.",

FutureWarning,

)

 

self.utter_message(text=text, buttons=buttons, **kwargs)

 

def utter_attachment(self, attachment: Text, **kwargs: Any) -> None:

"""Send a message to the client with attachments."""

warnings.warn(

"Use of `utter_attachment` is deprecated. "

"Use `utter_message(attachment=)` instead.",

FutureWarning,

)

 

self.utter_message(attachment=attachment, **kwargs)

 

# noinspection PyUnusedLocal

def utter_button_template(

self,

template: Text,

buttons: List[Dict[Text, Any]],

tracker: Tracker,

silent_fail: bool = False,

**kwargs: Any,

) -> None:

"""Sends a message template with buttons to the output channel."""

warnings.warn(

"Use of `utter_button_template` is deprecated. "

"Use `utter_message(template=