<commit_before>.. _policies:

Policies
========


The ``Policy`` is the core of your bot, with its most important method:

.. doctest::

    def predict_action_probabilities(self, tracker, domain):
        # type: (DialogueStateTracker, Domain) -> List[float]
        """Predicts the next action the bot should take
        after seeing the tracker.

        Returns the list of probabilities for the next actions"""

        return []


This uses the current state of the conversation (provided by the tracker) to choose the next action to take.
The domain is there if you need it, but only some policy types make use of it. The returned array contains
the probabilities for each action to be executed next. The action that is most likely will be executed.


Let's look at a simple example for a custom policy:

.. doctest::

  from rasa_core.policies import Policy
  from rasa_core.actions.action import ACTION_LISTEN_NAME
  from rasa_core import utils
  import numpy as np

  class SimplePolicy(Policy):
      def predict_action_probabilities(self, tracker, domain):
          responses = {"greet": 3}

          if tracker.latest_action_name == ACTION_LISTEN_NAME:
              key = tracker.latest_message.intent["name"]
              action = responses[key] if key in responses else 2
              return utils.one_hot(action, domain.num_actions)
          else:
              return np.zeros(domain.num_actions)


**How does this work?**
When the controller processes a message from a user, it will keep asking for the next most likely action using
``predict_action_probabilities``. The bot then executes that action, then call ``predict_action_probabilities`` again
with a new ``tracker``, until it receives an ``ActionListen`` instruction.
This breaks the loop and makes the bot await further instructions. 

In pseudocode, what the ``SimplePolicy`` above does is:

.. code-block:: md

    -> a new message has come in

    if we were previously listening:
        return a canned response
    else:
        we must have just said something, so let's listen again


Note that the policy itself is stateless, and all the state is carried by the ``tracker`` object.


Creating Policies from Stories
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Writing rules like in the SimplePolicy above is not a great way to build a bot, it gets messy fast & is hard to debug.
If you've found Rasa Core, it's likely you've already tried this approach and were looking for something better.

The second important method of any policy is ``train(...)``:

.. doctest::

    def train(self,
          training_trackers,  # type: List[DialogueStateTracker]
          domain,  # type: Domain
          **kwargs  # type: **Any
          ):
    # type: (...) -> None
    """Trains the policy on given training trackers."""

This method creates "some rules" for prediction depending on the training data.


Memorising the training data
----------------------------

A good next step is to use our story framework to build a policy by giving it some example conversations.<commit_msg>take code snippets for methods from policy.py<commit_after>.. _policies:

Policies
========


The ``Policy`` is the core of your bot, with its most important method:

.. literalinclude:: ../rasa_core/policies/policy.py
   :pyobject: Policy.predict_action_probabilities

This uses the current state of the conversation (provided by the tracker) to choose the next action to take.
The domain is there if you need it, but only some policy types make use of it. The returned array contains
the probabilities for each action to be executed next. The action that is most likely will be executed.


Let's look at a simple example for a custom policy:

.. doctest::

  from rasa_core.policies import Policy
  from rasa_core.actions.action import ACTION_LISTEN_NAME
  from rasa_core import utils
  import numpy as np

  class SimplePolicy(Policy):
      def predict_action_probabilities(self, tracker, domain):
          responses = {"greet": 3}

          if tracker.latest_action_name == ACTION_LISTEN_NAME:
              key = tracker.latest_message.intent["name"]
              action = responses[key] if key in responses else 2
              return utils.one_hot(action, domain.num_actions)
          else:
              return np.zeros(domain.num_actions)


**How does this work?**
When the controller processes a message from a user, it will keep asking for the next most likely action using
``predict_action_probabilities``. The bot then executes that action, then call ``predict_action_probabilities`` again
with a new ``tracker``, until it receives an ``ActionListen`` instruction.
This breaks the loop and makes the bot await further instructions. 

In pseudocode, what the ``SimplePolicy`` above does is:

.. code-block:: md

    -> a new message has come in

    if we were previously listening:
        return a canned response
    else:
        we must have just said something, so let's listen again


Note that the policy itself is stateless, and all the state is carried by the ``tracker`` object.


Creating Policies from Stories
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Writing rules like in the SimplePolicy above is not a great way to build a bot, it gets messy fast & is hard to debug.
If you've found Rasa Core, it's likely you've already tried this approach and were looking for something better.

The second important method of any policy is ``train(...)``:

.. literalinclude:: ../rasa_core/policies/policy.py
   :pyobject: Policy.train

This method creates "some rules" for prediction depending on the training data.


Memorising the training data
----------------------------

A good next step is to use our story framework to build a policy by giving it some example conversations.
{'fraction_non_alphanumeric': 0.08697164724299879, 'fraction_numerical': 0.0006957731779439903, 'mean_word_length': 3.294249439880508, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 7, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4465724', 'n_tokens_mistral': 1507, 'n_tokens_neox': 1442, 'n_words': 723}