Rasa Forms动态行为实现异常:howMedsStored无限重复询问求助
问题分析与解决方案
你的问题核心在于缺少槽位验证逻辑,并且extract方法的实现没有正确处理用户输入的提取流程,导致Rasa无法确认howMedsStored槽位的有效性,进而重复询问该槽位。
具体问题点
- 无验证方法:Rasa Form会要求每个必填槽位通过验证动作确认值的有效性,你只实现了
extract方法但没有对应的validate_howMedsStored方法,Rasa无法判断槽位值是否符合要求,因此会持续重复询问。 - extract方法逻辑冗余:你的
extract方法只是直接返回已有的槽位值,没有从用户最新输入中提取或处理数据,当Form尝试收集槽位时,无法正确获取用户输入并更新槽位。
修改后的代码示例
class ValidatehivNotPregForm(FormValidationAction): def name(self) -> Text: return "validate_NotPreg_form" async def required_slots( self, slots_mapped_in_domain: List[Text], dispatcher: "CollectingDispatcher", tracker: "Tracker", domain: "DomainDict", ) -> Optional[List[Text]]: additional_slots = [] if tracker.slots.get("Meds") is True: additional_slots.append("howMedsStored") additional_slots.append("MedsEnv") else: additional_slots.append("timeMedIntake") return slots_mapped_in_domain + additional_slots # 修正extract方法:从用户最新输入提取值 async def extract_howMedsStored( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: DomainDict ) -> Dict[Text, Any]: user_input = tracker.latest_message.get("text") return {"howMedsStored": user_input.strip() if user_input else None} async def extract_timeMedIntake( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: DomainDict ) -> Dict[Text, Any]: user_input = tracker.latest_message.get("text") return {"timeMedIntake": user_input.strip() if user_input else None} async def extract_MedsEnv( self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: DomainDict ) -> Dict[Text, Any]: user_input = tracker.latest_message.get("text") return {"MedsEnv": user_input.strip() if user_input else None} # 添加验证方法:确认howMedsStored的有效性 async def validate_howMedsStored( self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: DomainDict, ) -> Dict[Text, Any]: # 根据业务需求定义有效选项,示例为存储方式 valid_storage_options = ["阴凉干燥处", "冷藏", "常温"] if slot_value in valid_storage_options: return {"howMedsStored": slot_value} else: dispatcher.utter_message(text="请输入有效的药品存储方式,比如阴凉干燥处、冷藏或常温。") return {"howMedsStored": None} # 同理可添加MedsEnv和timeMedIntake的验证方法 async def validate_MedsEnv( self, slot_value: Any, dispatcher: CollectingDispatcher, tracker: Tracker, domain: DomainDict, ) -> Dict[Text, Any]: # 自定义验证逻辑 if slot_value: return {"MedsEnv": slot_value} else: dispatcher.utter_message(text="请描述药品所处的环境。") return {"MedsEnv": None}
额外配置检查
确保你的domain.yml中包含以下配置:
- 槽位定义:
slots: Meds: type: bool howMedsStored: type: text MedsEnv: type: text timeMedIntake: type: text - Form配置:
forms: NotPreg_form: ignored_intents: [] required_slots: # 这里可以留空,因为你通过代码动态添加 - Meds - 询问消息:
responses: utter_ask_howMedsStored: - text: "你的药品是如何存储的?" utter_ask_MedsEnv: - text: "药品所处的环境是什么样的?" utter_ask_timeMedIntake: - text: "你通常什么时候服药?"
内容的提问来源于stack exchange,提问作者emmasa
相关产品推荐
相关产品推荐

