You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rasa表单验证中途触发意图时如何停用表单?

RASA表单中途退出功能实现解决方案

问题背景

使用RASA框架开发registration_form表单收集用户注册信息,槽位均为text类型,映射条件为active_loop: registration_form。需求是用户输入/exit触发deactivate意图时,中途停用表单,返回初始状态并发送问候消息。

当前配置

domain.yml

slots:
  email:
    type: text
    influence_conversation: false
    mappings:
      - type: from_text
        conditions:
          - active_loop: registration_form
            requested_slot: email
  username:
    type: text
    influence_conversation: false
    mappings:
      - type: from_text
        conditions:
          - active_loop: registration_form
            requested_slot: username
  quit_form:
    type: bool
    influence_conversation: true
    mappings:
      - type: from_text

尝试方案及问题

  1. 验证方法中直接停用表单:在validate_email中检测退出意图后返回事件列表,触发UserWarning: Cannot validate email: make sure the validation method returns the correct output.警告,表单仍继续询问后续槽位。
  2. 添加故事处理退出:编写故事指定触发deactivate意图时调用action_deactivate_loop,训练时提示规则/故事冲突,预测应为action_listen却指定了action_deactivate_loop。

解决步骤

1. 修正表单验证类的逻辑

FormValidationAction的validate_*方法仅允许返回槽位键值对字典,不能直接返回事件。需重写run方法提前拦截退出意图:

from typing import Text, Dict, Any, List
from rasa_sdk import FormValidationAction, Tracker
from rasa_sdk.executor import CollectingDispatcher
from rasa_sdk.types import DomainDict
from rasa_sdk.events import SlotSet, ActiveLoop

class ValidateForm(FormValidationAction):
    data = {}
    signup_response = {}

    def name(self) -> Text:
        return "validate_registration_form" 

    def run(
        self,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> List[Dict[Text, Any]]:
        # 优先检测退出意图
        latest_text = tracker.latest_message.get("text", "").lower()
        if tracker.get_intent_of_latest_message() == "deactivate" or "/quit" in latest_text:
            dispatcher.utter_message(text="已退出注册流程,欢迎随时再来!")
            # 清空已收集槽位并停用表单
            return [
                ActiveLoop(None),
                SlotSet("email", None),
                SlotSet("username", None)
            ]
        
        # 正常执行验证逻辑
        return super().run(dispatcher, tracker, domain)

    # 保留原有验证逻辑,移除退出检测代码
    def validate_email(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        slot_value = slot_value.lower()
        if email_validation(slot_value):  
            if user_validation_from_local_db("email", slot_value) or user_validation(value=slot_value):
                dispatcher.utter_message(text="Email exists, try entering another email")
                return {"email": None}
            
            self.data['email'] = slot_value
            return {"email": slot_value}
        else: 
            dispatcher.utter_message(text="Email is not valid, please enter a valid email.")
            return {"email": None}
    
    def validate_username(
        self,
        slot_value: Any,
        dispatcher: CollectingDispatcher,
        tracker: Tracker,
        domain: DomainDict,
    ) -> Dict[Text, Any]:
        if username_validation(slot_value):
            if user_validation_from_local_db('username', slot_value) or user_validation(value=slot_value): 
                dispatcher.utter_message(text="Username exists, try entering another username")
                return {"username":None}
            self.data['username'] = slot_value
            return {"username": slot_value}
        else:
            dispatcher.utter_message("Please enter a valid Username.\nMake sure username only consists lower-case characters, numbers, underscore(_) and no spaces.")
            return {'username':None}

2. 使用规则替代故事处理退出

表单退出属于明确的触发-响应流程,用规则替代故事可避免训练冲突,在rules.yml中添加:

- rule: Exit registration form
  steps:
    - active_loop: registration_form
    - intent: deactivate
    - action: action_deactivate_loop
    - active_loop: null
    - action: utter_greet  # 替换为你的问候动作

3. 简化domain.yml配置(可选)

若无需通过槽位控制退出,可移除quit_form槽:

slots:
  email:
    type: text
    influence_conversation: false
    mappings:
      - type: from_text
        conditions:
          - active_loop: registration_form
            requested_slot: email
  username:
    type: text
    influence_conversation: false
    mappings:
      - type: from_text
        conditions:
          - active_loop: registration_form
            requested_slot: username

4. 完善deactivate意图训练数据

在nlu.yml中补充意图示例:

- intent: deactivate
  examples: |
    - /exit
    - quit
    - exit
    - stop
    - cancel
    - 退出
    - 取消

关键说明

  • validate_*方法仅支持返回槽位字典,事件需在run方法中返回,否则会触发验证警告。
  • 规则比故事更适合处理表单这类结构化流程,可避免训练时的冲突问题。

内容的提问来源于stack exchange,提问作者sarveshsta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:04:58