🚀 原文地址:https://rasa.com/docs/action-server/actions

当 Rasa 机器人调用自定义操作时,它将向 Action Server 发送请求。Rasa 只知道请求中所返回的任何事件和响应,这取决于 Action Server 基于操作名称来调用正确的代码。

为了更好地理解 Rasa 调用自定义操作时会发生什么,我们考虑这样一个示例:我们已经将天气机器人部署到 Fackbook 和 Slack,用户可以使用意图ask_weather来询问天气。 如果用户指定了位置,则会有一个location插槽。action_tell_weather动作将使用 API 获取天气预报,如果用户未指定。则使用默认位置。该动作会将temperature设置为天气预报的最高温度,返回的消息将根据他们使用的通道而有所不同。

1. 自定义操作的输入

Action Server 从 Rasa 服务器接收以下负载:

  1. {
  2. "next_action": "action_tell_weather",
  3. "sender_id": "2687378567977106",
  4. "tracker": {
  5. "sender_id": "2687378567977106",
  6. "slots": {
  7. "location": null,
  8. "temperature": null
  9. },
  10. "latest_message": {
  11. "text": "/ask_weather",
  12. "intent": {
  13. "name": "ask_weather",
  14. "confidence": 1
  15. },
  16. "intent_ranking": [
  17. {
  18. "name": "ask_weather",
  19. "confidence": 1
  20. }
  21. ],
  22. "entities": []
  23. },
  24. "latest_event_time": 1599850576.655345,
  25. "followup_action": null,
  26. "paused": false,
  27. "events": [
  28. {
  29. "event": "action",
  30. "timestamp": 1599850576.654908,
  31. "name": "action_session_start",
  32. "policy": null,
  33. "confidence": null
  34. },
  35. {
  36. "event": "session_started",
  37. "timestamp": 1599850576.654916
  38. },
  39. {
  40. "event": "action",
  41. "timestamp": 1599850576.654928,
  42. "name": "action_listen",
  43. "policy": null,
  44. "confidence": null
  45. },
  46. {
  47. "event": "user",
  48. "timestamp": 1599850576.655345,
  49. "text": "/ask_weather",
  50. "parse_data": {
  51. "text": "/ask_weather",
  52. "intent": {
  53. "name": "ask_weather",
  54. "confidence": 1
  55. },
  56. "intent_ranking": [
  57. {
  58. "name": "ask_weather",
  59. "confidence": 1
  60. }
  61. ],
  62. "entities": []
  63. },
  64. "input_channel": "facebook",
  65. "message_id": "3f2f2317dada4908b7a841fd3eab6bf9",
  66. "metadata": {}
  67. }
  68. ],
  69. "latest_input_channel": "facebook",
  70. "active_form": {},
  71. "latest_action_name": "action_listen"
  72. },
  73. "domain": {
  74. "config": {
  75. "store_entities_as_slots": true
  76. },
  77. "session_config": {
  78. "session_expiration_time": 60,
  79. "carry_over_slots_to_new_session": true
  80. },
  81. "intents": [
  82. {
  83. "greet": {
  84. "use_entities": true
  85. }
  86. },
  87. {
  88. "ask_weather": {
  89. "use_entities": true
  90. }
  91. }
  92. ],
  93. "entities": [],
  94. "slots": {
  95. "location": {
  96. "type": "rasa.core.slots.UnfeaturizedSlot",
  97. "initial_value": null,
  98. "auto_fill": true
  99. },
  100. "temperature": {
  101. "type": "rasa.core.slots.UnfeaturizedSlot",
  102. "initial_value": null,
  103. "auto_fill": true
  104. }
  105. },
  106. "responses": {
  107. "utter_greet": [
  108. {
  109. "text": "Hey! How are you?"
  110. }
  111. ]
  112. },
  113. "actions": [
  114. "action_tell_weather",
  115. "utter_greet"
  116. ],
  117. "forms": []
  118. },
  119. "version": "2.0.0"
  120. }

1.1 next_action

next_action字段告诉 Action Server 要运行什么操作,我们的操作不必作为类实现,但它们必须可以按名称调用。在上述示例中,Action Server 应该运行action_tell_weather操作。

1.2 sender_id

sender_id告诉我们进行对话的用户唯一ID,其格式因输入通道而已,机器人告诉我们有关用户的内容还取决于输入通道以及通道如何识别用户。在上述示例中,sender_id不用于任何事情。

1.3 tracker

跟踪器包含对话的信息,包括事件的历史记录和所有插槽的记录:

  • sender_id
  • slots:机器人域中的每个插槽及其当前时间下的值
  • latest_message:最新一条消息的属性
  • latest_event_time:最后一个事件添加到跟踪器的时间戳
  • followup_action:调用的动作是强制的后续动作
  • paused:对话当前是否暂停
  • events:之前所有事件的列表
  • latest_input_channel:收到最后一条用户消息的输入通道
  • active_form:当前活动表单的名称,如果有的话
  • lastest_action_name:机器人执行的最后一个动作名称

在示例案例中,自定义操作使用location插槽(如果已经设置了)来获取天气预报。它还会检查latest_input_channel属性,并格式化消息负载,以便它在 Facebook Messager 中正确显示。

1.4 domain

域是 domian.yml 文件的 JSON 表示形式,自定义操作不太可能引用其内容,因为它们是静态的,因为它们是静态的,并且不表明对话的状态。

1.5 version

这是 Rasa 版本,自定义操作也不太可能引用此内容,但如果 Action Server 仅与某些 Rasa 版本兼容,我们可能在验证步骤中使用到它。

2. 自定义操作的输出

Rasa 服务器需要一个事件和响应字典作为对自定义操作调用的响应。

2.1 事件

事件描述的是 Action Server 如何影响对话,在示例情况下,自定义操作应将最高温度存储在temperature插槽中,因此它需要返回一个slot事件。要设置插槽并且不执行任何其他操作,我们的响应负载将如下所示:

  1. {
  2. "events": [
  3. {
  4. "event": "slot",
  5. "timestamp": null,
  6. "name": "temperature",
  7. "value": "30"
  8. }
  9. ],
  10. "responses": []
  11. }

请注意,事件将按照所列出的顺序应用于跟踪器;对于插槽事件,顺序无关紧要,但对于其他事件类型,是适用的。

2.2 响应

响应可以是 Rasa 富响应的任何类型,在示例案例中,我们希望向用户发送包含天气预报的消息。要发送常规的文本消息,响应负载将如下所示:

  1. {
  2. "events": [
  3. {
  4. "event": "slot",
  5. "timestamp": null,
  6. "name": "temperature",
  7. "value": "30"
  8. }
  9. ],
  10. "responses": [
  11. {
  12. "text": "This is your weather forecast!"
  13. }
  14. ]
  15. }

但是,如果我们想利用通道的特定功能,由于latest_input_channel是 Facebook,因此我们添加了一个带有自定义负载的响应,该负载将根据 Facebook 的 API 规范呈现为媒体消息。我们的响应负载如下所示:

  1. {
  2. "events": [
  3. {
  4. "event": "slot",
  5. "timestamp": null,
  6. "name": "temperature",
  7. "value": "30"
  8. }
  9. ],
  10. "responses": [
  11. {
  12. "text": "This is your weather forecast!"
  13. },
  14. {
  15. "attachment": {
  16. "type": "template",
  17. "payload": {
  18. "template_type": "media",
  19. "elements": [
  20. {
  21. "media_type": "weather_forcast.gif",
  22. "attachment_id": "<id from facebook upload endpoint>"
  23. }
  24. ]
  25. }
  26. }
  27. }
  28. ]
  29. }

当这个响应被发送回 Rasa 服务器时,Rasa 会将slot事件和两个响应应用到跟踪器,并将两个消息都返回给用户。

3. 特定操作类型

在某些情况下会地总触发一些特殊的动作类型,即默认动作和插槽验证动作。这些特殊操作类型具有预定义的命名约定,必须遵循这些约定以保持自动触发行为。我们可以通过实现具有完全相同名称的自定义操作来自定义默认操作。

插槽验证操作在每个用户轮次运行,具体取决于表单是否处于活跃状态。当表单不活动时,应该运行的插槽验证操作必须称为action_validate_slot_mappings。当表单处于活跃状态时,应该运行的插槽验证操作必须称为valiate_<form_name>。这些动作应该只返回SlotSet事件,并且分别表现得像 Rasa SDK ValidationAction 类和 FormValidationAction类。