Core: 1. Basics#
This notebook shows a basic example of creating a simple dialog bot (agent).
Here, basic usage of Pipeline is shown.
Additionally, function check_happy_path that can be used for Pipeline testing is presented.
Let’s do all the necessary imports from Chatsky:
[1]:
# installing dependencies
%pip install -q chatsky
Note: you may need to restart the kernel to use updated packages.
[2]:
from chatsky import (
TRANSITIONS,
RESPONSE,
Pipeline,
Transition as Tr,
conditions as cnd,
# all the aliases used in tutorials are available for direct import
# e.g. you can do `from chatsky import Tr` instead
)
from chatsky.utils.testing.common import (
check_happy_path,
is_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
is a list of Transitions that describes possible transitions from the current node as well as their conditions and priorities.
[3]:
toy_script = {
"greeting_flow": {
"start_node": { # This is the initial node,
# it doesn't contain a `RESPONSE`.
TRANSITIONS: [Tr(dst="node1", cnd=cnd.ExactMatch("Hi"))],
# This transition means that the next node would be "node1"
# if user's message is "Hi"
},
"node1": {
RESPONSE: "Hi, how are you?",
# When the bot enters node1,
# return "Hi, how are you?".
TRANSITIONS: [
Tr(dst="node2", cnd=cnd.ExactMatch("I'm fine, how are you?"))
],
},
"node2": {
RESPONSE: "Good. What do you want to talk about?",
TRANSITIONS: [
Tr(dst="node3", cnd=cnd.ExactMatch("Let's talk about music."))
],
},
"node3": {
RESPONSE: "Sorry, I can not talk about music now.",
TRANSITIONS: [Tr(dst="node4", cnd=cnd.ExactMatch("Ok, goodbye."))],
},
"node4": {
RESPONSE: "Bye",
TRANSITIONS: [Tr(dst="node1", cnd=cnd.ExactMatch("Hi"))],
},
"fallback_node": {
# We get to this node if the conditions
# for switching to other nodes are not performed.
RESPONSE: "Ooops",
TRANSITIONS: [Tr(dst="node1", cnd=cnd.ExactMatch("Hi"))],
},
}
}
happy_path = (
(
"Hi",
"Hi, how are you?",
), # start_node -> node1
(
"I'm fine, how are you?",
"Good. What do you want to talk about?",
), # node1 -> node2
(
"Let's talk about music.",
"Sorry, I can not talk about music now.",
), # node2 -> node3
("Ok, goodbye.", "Bye"), # node3 -> node4
("Hi", "Hi, how are you?"), # node4 -> node1
("stop", "Ooops"), # node1 -> fallback_node
(
"stop",
"Ooops",
), # fallback_node -> fallback_node
(
"Hi",
"Hi, how are you?",
), # fallback_node -> node1
(
"I'm fine, how are you?",
"Good. What do you want to talk about?",
), # node1 -> node2
(
"Let's talk about music.",
"Sorry, I can not talk about music now.",
), # node2 -> node3
("Ok, goodbye.", "Bye"), # node3 -> node4
)
Pipeline
is an object that processes user inputs and produces responses.
To create the pipeline you need to pass the script (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
).
If fallback_label
is not set, it defaults to start_label
.
Roughly, the process is as follows:
Pipeline receives a user request.
The next node is determined with the help of
TRANSITIONS
.Response of the chosen node is sent to the user.
For a more detailed description, see here.
[4]:
pipeline = Pipeline(
script=toy_script,
start_label=("greeting_flow", "start_node"),
fallback_label=("greeting_flow", "fallback_node"),
)
if __name__ == "__main__":
check_happy_path(
pipeline,
happy_path,
printout=True,
) # This is a function for automatic tutorial
# running (testing tutorial) with `happy_path`.
if is_interactive_mode():
pipeline.run()
# this method runs the pipeline with the preconfigured interface
# which is CLI by default: it allows chatting with the bot
# via command line
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'