Core: 1. Basics#
This notebook shows basic tutorial of creating a simple dialog bot (agent).
Here, basic usege of Pipeline primitive is shown: its’ creation with from_script and execution.
Additionally, function check_happy_path that can be used for Pipeline testing is presented.
Let’s do all the necessary imports from DFF:
[1]:
# installing dependencies
%pip install -q dff
Note: you may need to restart the kernel to use updated packages.
[2]:
from dff.script import TRANSITIONS, RESPONSE, Message
from dff.pipeline import Pipeline
import dff.script.conditions as cnd
from dff.utils.testing.common import (
check_happy_path,
is_interactive_mode,
run_interactive_mode,
)
First of all, to create a dialog agent, we need to create a dialog script. Below script means a dialog script. A script is a dictionary, where the keys are the names of the flows. A script can contain multiple scripts, which is needed in order to divide a dialog into sub-dialogs and process them separately. For example, the separation can be tied to the topic of the dialog. In this tutorial there is one flow called greeting_flow
.
Flow describes a sub-dialog using linked nodes. Each node has the keywords RESPONSE
and TRANSITIONS
.
RESPONSE
contains the response that the agent will return from the current node.TRANSITIONS
describes transitions from the current node to another nodes. This is a dictionary, where keys are names of the nodes and values are conditions of transition to them.
[3]:
toy_script = {
"greeting_flow": {
"start_node": { # This is the initial node,
# it doesn't contain a `RESPONSE`.
RESPONSE: Message(),
TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))},
# If "Hi" == request of the user then we make the transition.
},
"node1": {
RESPONSE: Message(
text="Hi, how are you?"
), # When the agent enters node1,
# return "Hi, how are you?".
TRANSITIONS: {
"node2": cnd.exact_match(Message("I'm fine, how are you?"))
},
},
"node2": {
RESPONSE: Message("Good. What do you want to talk about?"),
TRANSITIONS: {
"node3": cnd.exact_match(Message("Let's talk about music."))
},
},
"node3": {
RESPONSE: Message("Sorry, I can not talk about music now."),
TRANSITIONS: {"node4": cnd.exact_match(Message("Ok, goodbye."))},
},
"node4": {
RESPONSE: Message("Bye"),
TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))},
},
"fallback_node": {
# We get to this node if the conditions
# for switching to other nodes are not performed.
RESPONSE: Message("Ooops"),
TRANSITIONS: {"node1": cnd.exact_match(Message("Hi"))},
},
}
}
happy_path = (
(
Message("Hi"),
Message("Hi, how are you?"),
), # start_node -> node1
(
Message("I'm fine, how are you?"),
Message("Good. What do you want to talk about?"),
), # node1 -> node2
(
Message("Let's talk about music."),
Message("Sorry, I can not talk about music now."),
), # node2 -> node3
(Message("Ok, goodbye."), Message("Bye")), # node3 -> node4
(Message("Hi"), Message("Hi, how are you?")), # node4 -> node1
(Message("stop"), Message("Ooops")), # node1 -> fallback_node
(
Message("stop"),
Message("Ooops"),
), # fallback_node -> fallback_node
(
Message("Hi"),
Message("Hi, how are you?"),
), # fallback_node -> node1
(
Message("I'm fine, how are you?"),
Message("Good. What do you want to talk about?"),
), # node1 -> node2
(
Message("Let's talk about music."),
Message("Sorry, I can not talk about music now."),
), # node2 -> node3
(Message("Ok, goodbye."), Message("Bye")), # node3 -> node4
)
A Pipeline
is an object that processes user inputs and returns responses. To create the pipeline you need to pass the script (toy_script
), initial node (start_label
) and the node to which the default transition will take place if none of the current conditions are met (fallback_label
). By default, if fallback_label
is not set, then its value becomes equal to start_label
.
[4]:
pipeline = Pipeline.from_script(
toy_script,
start_label=("greeting_flow", "start_node"),
fallback_label=("greeting_flow", "fallback_node"),
)
if __name__ == "__main__":
check_happy_path(
pipeline,
happy_path,
) # This is a function for automatic tutorial
# running (testing tutorial) with `happy_path`.
# Run tutorial in interactive mode if not in IPython env
# and if `DISABLE_INTERACTIVE_MODE` is not set.
if is_interactive_mode():
run_interactive_mode(pipeline)
# This runs tutorial in interactive mode.
(user) >>> text='Hi'
(bot) <<< text='Hi, how are you?'
(user) >>> text='I'm fine, how are you?'
(bot) <<< text='Good. What do you want to talk about?'
(user) >>> text='Let's talk about music.'
(bot) <<< text='Sorry, I can not talk about music now.'
(user) >>> text='Ok, goodbye.'
(bot) <<< text='Bye'
(user) >>> text='Hi'
(bot) <<< text='Hi, how are you?'
(user) >>> text='stop'
(bot) <<< text='Ooops'
(user) >>> text='stop'
(bot) <<< text='Ooops'
(user) >>> text='Hi'
(bot) <<< text='Hi, how are you?'
(user) >>> text='I'm fine, how are you?'
(bot) <<< text='Good. What do you want to talk about?'
(user) >>> text='Let's talk about music.'
(bot) <<< text='Sorry, I can not talk about music now.'
(user) >>> text='Ok, goodbye.'
(bot) <<< text='Bye'