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

Rasa 2自定义动作返回SlotSet时规则后续动作未触发、槽值不更新问题

核心问题排查与修复方案

1. 规则执行中断、utter_ask_deal未触发原因

  • 自定义动作ActionGetOffer的run方法仅在user_asked_percentage > current_bargain分支内有返回语句,其余分支无显式返回,Rasa要求自定义动作的run方法必须返回事件列表(无事件需返回空列表[]),无返回会被判定为动作执行异常,直接中断后续规则步骤。
  • 当你返回SlotSet事件时,如果current_bargain槽配置了influence_conversation: true,Rasa会判定会话状态发生变更,需要重新预测后续动作,不会继续执行原规则中预设的utter_ask_deal步骤,这是返回SlotSet后后续动作不执行的核心原因。
  • 你提到的「不返回SlotSet后续动作可以正常执行」是正常现象:没有槽更新事件时会话状态未发生变更,Rasa会按规则定义的顺序继续执行后续步骤。

2. current_bargain槽值未更新原因

  • 单独调用SlotSet不会生效:SlotSet是Rasa的事件对象,必须放在run方法的返回列表中,Rasa才会处理该事件完成槽值更新,单独调用不会触发任何槽变更逻辑。
  • 槽配置错误:如果current_bargain槽未在domain中声明、类型不匹配(比如返回float但槽类型设为text)、未设置初始值导致tracker.get_slot('current_bargain')取到None,执行+2时报错动作执行失败,槽值自然不会更新。
  • 动作执行异常:代码未做非空判断,当current_bargain初始为None时,current_bargain = tracker.get_slot('current_bargain') + 2会抛出类型错误,导致动作执行失败,返回的SlotSet不会被处理。

3. 修复步骤

步骤1:调整domain中槽的配置

关闭current_bargain等业务槽的会话影响属性,保证槽更新不会打断规则执行,同时设置初始值避免空值报错:

slots:
  current_bargain:
    type: float
    initial_value: 0.0
    influence_conversation: false
  current_bargain_price:
    type: float
    initial_value: 0.0
    influence_conversation: false
  price:
    type: float
    influence_conversation: false

步骤2:补全自定义动作的逻辑

统一所有分支的返回逻辑,增加非空判断:

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

class ActionGetOffer(Action):
    def name(self) -> Text:
        return "action_get_offer"

    def run(self, dispatcher: CollectingDispatcher,
            tracker: Tracker,
            domain: DomainDict) -> List[Dict[Text, Any]]:
        dispatcher.utter_message(text = "Ok! Let me see what I can do!")

        product_price = 500
        platform_bargain_percentage = 5
        vendor_bargain_percentage = 5
        max_bargain = platform_bargain_percentage + vendor_bargain_percentage

        offer_price = int(tracker.get_slot("price") or 0)
        user_asked_percentage = (offer_price / product_price) * 100
        # 处理槽空值场景
        current_bargain = (tracker.get_slot('current_bargain') or 0) + 2
        events = []

        if user_asked_percentage > current_bargain:
            dispatcher.utter_message(text = "Okay so I just checked and sorry but we can't give away for that price!")
            current_bargain_price = tracker.get_slot('current_bargain_price') or 0
            if current_bargain_price == 0:
                current_bargain_price = (product_price - ((current_bargain/100) * product_price))
            if current_bargain <= max_bargain:
                dispatcher.utter_message(text = f"How about {product_price - ((current_bargain/100) * product_price)}?")
            else:
                dispatcher.utter_message(text = "Hmm...wanna make a fresh offer then?")
            # 把槽更新事件加入返回列表
            events.append(SlotSet("current_bargain", value = float(current_bargain)))
        
        # 所有场景统一返回事件列表
        return events

可选优化

如果调整槽配置后仍有规则执行中断问题,可以直接把utter_ask_deal的调用放到自定义动作中,无需依赖规则后续步骤:
在run方法末尾加一行dispatcher.utter_message(response="utter_ask_deal")即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 11:15:05