Custom Policy Issue

I am facing issue with my Custom Policy where it checks for any spelling errors and display the user with “Did you mean ”, to utter the message I have created a custom action and invoked it in the policy but action is being triggered continuously without break.

SpellCheckPolicy.py:

class SpellCheckPolicy(Policy):

""" This policy handles low NLU confidence in multiple stages."""

SPELL_CHECK_POLICY_PRIORITY = 6

def __init__(

    self,

    priority: int = SPELL_CHECK_POLICY_PRIORITY,

    spell_check_action_name: Text = "action_spell_check",

) -> None:

    super().__init__(

        priority=priority,

    )

    self.priority = priority

    self.spell_check_action_name = spell_check_action_name

def train(

    self,

    training_trackers: List[DialogueStateTracker],

    domain: Domain,

    **kwargs: Any,

) -> None:

    """Does nothing. This policy is deterministic."""

    pass

def persist(self, path: Text) -> None:

    """Persists the policy to storage."""

    config_file = os.path.join(path, "spellCheck_policy.json")

    meta = {

        "priority": self.priority,

        "spell_check_action_name": self.spell_check_action_name,    

    }

    rasa.utils.io.create_directory_for_file(config_file)

    rasa.utils.io.dump_obj_as_json_to_file(config_file, meta)

def predict_action_probabilities(

    self, tracker: DialogueStateTracker, domain: Domain

) -> List[float]:

    """Predicts the next action if NLU confidence is low.

    """

    print("Policyy--",tracker.latest_message.parse_data["text"])

    mt = tracker.latest_message.parse_data["text"]

    str = mt.translate(mt.maketrans('', '', '!\"#$%&\'()*+,.-:;<=>?@[\]^_`{|}~'))

    words = str.split(' ')

    beforeMessage = mt

    spell = SpellChecker(language='en')

    result = self._default_predictions(domain)

    print("Spelll Check Policy Hit!!!!")

    for word in words:

        if word not in spell and len(word)>1:

            mt = mt.replace(word, spell.correction(word))

            print("Word after spell check", mt)

    if beforeMessage is not mt:

        idx = domain.index_for_action(self.spell_check_action_name)

        result[idx] = 1.0

    return result

@classmethod

def load(cls, path: Text) -> "SpellCheckPolicy":

    meta = {}

    if os.path.exists(path):

        meta_path = os.path.join(path, "spellCheck_policy.json")

        if os.path.isfile(meta_path):

            meta = json.loads(rasa.utils.io.read_file(meta_path))

    return cls(**meta)



@staticmethod

def _standard_featurizer() -> None:

    return None

Config.yml image

Action:

class SpellCheckAction(Action):

    def name(self) -> Text:

        return "action_spell_check"

    async def run(self,

            dispatcher: CollectingDispatcher,

            tracker: Tracker,

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

            message = {

            "text": f"SpellCheck Action Hit"

            }
            return [create_bot_utterance(message)]

Hi @sahrutha!

I’m not sure, but I think this is happening because of SPELL_CHECK_POLICY_PRIORITY = 6.

You have set your policy to have the highest priority. In your config, you are using only those policies which can predict with either confidence 0 or 1. In such a case, if a tie happens then the priority of the policy is considered, which is highest for your own custom policy.

So, I guess, it is always your policy which is determining the next action, and since it can not determine any action other than action_spell_check, so it is predicting that action again and again.

Do you think this could be the case?

Hey @saurabh-m523, Thank you for the insights but when default priority 1 was set to my policy, I got a warning saying : Found policies [‘TEDPolicy’, ‘SpellCheckPolicy’] with same priority 1 in PolicyEnsemble. When personalizing priorities, be sure to give all policies different priorities. . Also, When I ignored the warning and continued, its the same action is called in loop

So, I had to keep the priority to 6

It worked, added a if condition in predict_action_probabilities, after this looping has stopped. Code:

if (tracker.latest_action_name == self.spell_check_action_name and tracker.latest_action_name != ACTION_LISTEN_NAME):

        idx = domain.index_for_action(ACTION_LISTEN_NAME)

        result[idx] = 1.0
1 Like

Hi @sahrutha!

I’m curious now, so this stopped looping, but are your stories being followed properly after this?

Yes @saurabh-m523

1 Like

Oh nice then. Actually I’m also working on customizing my own policy. I’ll keep that in mind when making my custom policy. Thanks!