-
Notifications
You must be signed in to change notification settings - Fork 18
User guides #177
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
User guides #177
Changes from 18 commits
Commits
Show all changes
20 commits
Select commit
Hold shift + click to select a range
265abb9
user guides
pseusys 4ab79c2
basic guide
pseusys d327b04
section changed
pseusys a0e7e47
prints removed
pseusys af3c8fd
minor text fixes
RLKRo a889f20
labels reverted
pseusys 17558fe
Merge branch 'dev' into feat/user_guides
pseusys ddd1cbe
Merge branch 'feat/user_guides' of https://github.com/deeppavlov/dial…
pseusys 3e02379
Merge branch 'dev' into feat/user_guides
pseusys 9b5bc90
review revised
pseusys a0f0de1
fixes reverted
pseusys 6b63499
minor text fixes
RLKRo 9f913b9
some review comments taken into account
pseusys 363f442
Merge branch 'feat/user_guides' of https://github.com/deeppavlov/dial…
pseusys a8527d8
replace note with a shield badge
RLKRo 297f640
get_previous_node_name doc changes
RLKRo 3849316
chat bot specification fixed further
pseusys b84aa3f
Merge branch 'feat/user_guides' of https://github.com/deeppavlov/dial…
pseusys a6c04b5
more review comments fixed
pseusys c05582b
chat bot description updated
pseusys File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| User guides | ||
| ----------- | ||
|
|
||
| :doc:`Basic conceptions <./user_guides/basic_conceptions>` | ||
| ~~~~~~~~~~~~~~~~~ | ||
|
|
||
| In the ``basic conceptions`` tutorial the basics of DFF are described, | ||
| those include but are not limited to: dialog graph creation, specifying start and fallback nodes, | ||
| setting transitions and conditions, using ``Context`` object in order to receive information | ||
| about current script execution. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,302 @@ | ||
| Basic Concepts | ||
| -------------- | ||
|
|
||
| Introduction | ||
| ~~~~~~~~~~~~ | ||
|
|
||
| Dialog Flow Framework helps its users create conversational services, which is done by | ||
| defining a specialized dialog graph that dictates the behaviour of the dialog service. | ||
| This dialog graph essentially represents the dialog script that guides the conversation | ||
| between the chat-bot and the user. | ||
|
|
||
| DFF leverages a specialized language known as a Domain-Specific Language (DSL) | ||
| to enable developers to quickly write and comprehend dialog graphs. | ||
| This DSL greatly simplifies the process of designing complex conversations and handling | ||
| various user inputs, making it easier to build sophisticated conversational systems. | ||
|
|
||
| DFF installation and requirements | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| For this very basic tutorial we will need only the core dependencies of DFF. | ||
| They can be installed via the following command: | ||
|
|
||
| .. code-block:: shell | ||
| pip3 install dff | ||
| Example conversational chat-bot | ||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Let us go through the creation of a simple bot that would play (virtual) ping-pong game with its users. | ||
pseusys marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| It would also greet them and handle exceptions. | ||
| First, we define the chat-bot in pseudo language: | ||
|
|
||
| .. code-block:: text | ||
| If user writes "Hello!": | ||
| Respond with "Hi! Let's play ping-pong!" | ||
| If user writes something else: | ||
| Respond with "You should've started the dialog with 'Hello!'" | ||
| Repeat from responding with "Hi! Let's play ping-pong!" if user writes anything | ||
| If user afterwards writes "Ping" or "ping" or "Ping!" or "ping!": | ||
| Respond with "Pong!" | ||
| Repeat this behaviour | ||
pseusys marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| If user writes something else: | ||
| Respond with "You should've written 'Ping', not '[USER MESSAGE]'!" | ||
| Repeat from responding with "Hi! Let's play ping-pong!" if user writes anything | ||
| Later in this tutorial we will create this chat-bot using DFF, starting from the very basics | ||
| and then elaborating on more complicated topics. | ||
|
|
||
| Example chat-bot graph | ||
| ~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Let's start from creating the very simple dialog agent: | ||
|
|
||
| .. code-block:: python | ||
| from dff.pipeline import Pipeline | ||
| from dff.script import TRANSITIONS, RESPONSE, Message | ||
| import dff.script.conditions as cnd | ||
| ping_pong_script = { | ||
| "ping_pong_flow": { | ||
| "start_node": { | ||
| RESPONSE: Message(), | ||
| TRANSITIONS: { | ||
| "greeting_node": cnd.exact_match(Message(text="Hello!")), | ||
| }, | ||
| }, | ||
| "greeting_node": { | ||
| RESPONSE: Message(text="Hi! Let's play ping-pong!"), | ||
| TRANSITIONS: { | ||
| "response_node": cnd.exact_match(Message(text="Ping!")), | ||
| }, | ||
| }, | ||
| "response_node": { | ||
| RESPONSE: Message(text="Pong!"), | ||
| TRANSITIONS: { | ||
| "response_node": cnd.exact_match(Message(text="Ping!")), | ||
| }, | ||
| }, | ||
| "fallback_node": { | ||
| RESPONSE: Message(text="That was against the rules!"), | ||
| TRANSITIONS: { | ||
| "greeting_node": cnd.true(), | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
| pipeline = Pipeline.from_script( | ||
| ping_pong_script, | ||
| start_label=("ping_pong_flow", "start_node"), | ||
| fallback_label=("ping_pong_flow", "fallback_node"), | ||
| ) | ||
| if __name__ == "__main__": | ||
| pipeline.run() | ||
| .. warning:: | ||
|
|
||
| Current dialog agent doesn't support different cases and/or marks in "Ping" | ||
| messages, it only supports exact "Ping!" message from user. | ||
| It also supports only one standard error message for any error. | ||
|
|
||
| That's what the agent consists of: | ||
|
|
||
| * ``ping_pong_script``: in order to create a dialog agent, a dialog **script** is needed; | ||
| a script is a dictionary, where the keys are the names of the flows (that are "sub-dialogs", | ||
| used to separate the whole dialog into multiple sub-dialogs). | ||
|
|
||
| * ``ping_pong_flow`` is our behaviour flow; flow is a separated dialog, containing linked | ||
pseusys marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| conversation nodes and possibly some extra data, transitions, etc. | ||
|
|
||
| * ``start_node`` is the initial node, contains no response, only transfers user to an other node | ||
| according to the first message user sends. | ||
| It transfers user to ``greeting_node`` if user writes text message exactly equal to "Hello!". | ||
|
|
||
| * Each node contains "RESPONSE" and "TRANSITIONS" elements. | ||
|
|
||
| * ``RESPONSE`` value should be a ``Message`` object, that can contain text, images, | ||
| audios, attachments, etc. | ||
|
|
||
| * ``TRANSITIONS`` value should be a dict, containing node names and conditions, | ||
| that should be met in order to go to the node specified. | ||
| Here, we can see two different types of transitions: ``exact_match`` requires user message text to | ||
| match the provided text exactly, while ``true`` allowes unconditional transition. | ||
|
|
||
| * ``greeting_node`` is the node that will greet user and propose him a ping-pong game. | ||
| It transfers user to ``response_node`` if user writes text message exactly equal to "Ping!". | ||
|
|
||
| * ``response_node`` is the node that will play ping-pong game with the user. | ||
| It transfers user to ``response_node`` if user writes text message exactly equal to "Ping!". | ||
|
|
||
| * ``fallback_node`` is an "exception handling node"; user will be transferred here if in any node | ||
| no transition for the message given by user is found. | ||
| It transfers user to ``greeting_node`` no matter what user writes. | ||
|
|
||
| * ``pipeline`` is a special object that processes user requests according to provided script. | ||
| In order to create pipeline, the script should be provided and two two-string tuples: | ||
pseusys marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| the first specifies initial node flow and name and the second (optional) specifies fallback | ||
| node flow and name (if not provided it equals to the first one by default). | ||
|
|
||
| .. note:: | ||
|
|
||
| See `tutorial on basic dialog structure`_. | ||
|
|
||
| Advanced graph features | ||
| ~~~~~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| Right now the agent we have created is a very simple one and does not behave **exactly** as we wanted | ||
| our bot to behave. Let's see how we can improve our script: | ||
|
|
||
| .. code-block:: python | ||
| from dff.pipeline import Pipeline | ||
| from dff.script import TRANSITIONS, RESPONSE, Context, Message | ||
| import dff.script.conditions as cnd | ||
| import dff.script.labels as lbl | ||
| def get_previous_node_name(ctx: Context) -> str: | ||
| """ | ||
| Get name of the previous visited script node. | ||
pseusys marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| """ | ||
| last_label = sorted(list(ctx.labels))[-2] if len(ctx.labels) >= 2 else None | ||
| # labels store the list of nodes the bot transitioned to, | ||
| # so the second to last label would be the label of a previous node | ||
| return ctx.labels[last_label][1] if last_label is not None else "start_node" | ||
pseusys marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| # label is a two-item tuple used to identify a node, | ||
| # the first element is flow name and the second is node name | ||
| def fallback_response(ctx: Context, _: Pipeline, *args, **kwargs) -> Message: | ||
| """ | ||
| Generate response for fallback node, according to the previous node | ||
| we have been to. | ||
| If the previous node was `start_node`, a sample message will be returned, | ||
| otherwise the message will include user input. | ||
| """ | ||
| if get_previous_node_name(ctx) == "start_node": | ||
| return Message(text="You should've started the dialog with 'Hello!'") | ||
| elif ctx.last_request is not None: | ||
| last_request = ctx.last_request.text | ||
| note = f"You should've written 'Ping', not '{last_request}'!" | ||
| return Message(text=f"That was against the rules! {note}") | ||
| else: | ||
| raise RuntimeError("Error occurred: last request is None!") | ||
| ping_pong_script = { | ||
| "ping_pong_flow": { | ||
| "start_node": { | ||
| RESPONSE: Message(), | ||
| TRANSITIONS: { | ||
| lbl.forward(): cnd.exact_match(Message(text="Hello!")), | ||
| }, | ||
| }, | ||
| "greeting_node": { | ||
| RESPONSE: Message(text="Hi! Let's play ping-pong!"), | ||
| TRANSITIONS: { | ||
| lbl.forward(): cnd.regexp(r"^[P|p]ing!?$"), | ||
| }, | ||
| }, | ||
| "ping_pong_node": { | ||
| RESPONSE: Message(text="Pong!"), | ||
| TRANSITIONS: { | ||
| lbl.repeat(): cnd.regexp(r"^[P|p]ing!?$"), | ||
| }, | ||
| }, | ||
| "fallback_node": { | ||
| RESPONSE: fallback_response, | ||
| TRANSITIONS: { | ||
| "greeting_node": cnd.true(), | ||
| }, | ||
| }, | ||
| }, | ||
| } | ||
| pipeline = Pipeline.from_script( | ||
| ping_pong_script, | ||
| start_label=("ping_pong_flow", "start_node"), | ||
| fallback_label=("ping_pong_flow", "fallback_node"), | ||
| ) | ||
| if __name__ == "__main__": | ||
| pipeline.run() | ||
| That's what we've changed: | ||
|
|
||
| * ``fallback_node`` has a callback response, it prints different messages depending on the | ||
| previous node. | ||
|
|
||
| .. note:: | ||
|
|
||
| See `tutorial on response functions`_. | ||
|
|
||
| * A special function ``get_previous_node_name`` was written to determine the name of the previous | ||
| visited node. It utilizes ``labels`` attribute of the ``Context`` object. | ||
|
|
||
| .. note:: | ||
|
|
||
| See `documentation of Context object`_. | ||
|
|
||
| * Transitions were changed: transitions to next, previous and current node were replaced with special | ||
| standard transitions. | ||
|
|
||
| .. note:: | ||
|
|
||
| See `tutorial on transitions`_. | ||
|
|
||
| * Conditions were changed: now regular expressions are used to check user text input value. | ||
|
|
||
| .. note:: | ||
|
|
||
| See `tutorial on conditions`_. | ||
|
|
||
| Further exploration | ||
| ~~~~~~~~~~~~~~~~~~~ | ||
|
|
||
| There are still a lot of capabilities of Dialog Flow Framework that remain uncovered by this tutorial. | ||
|
|
||
| For example: | ||
|
|
||
| * You can use ``GLOBAL`` transitions that will be available from every node in your script. | ||
| See `tutorial on global transitions`_. | ||
RLKRo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| * You can serialize context (available on every transition and response) | ||
RLKRo marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| to json or dictionary in order to debug it or extract some values. | ||
| See `tutorial on context serialization`_. | ||
|
|
||
| * You can alter user input and modify generated responses. | ||
| User input can be altered with ``PRE_RESPONSE_PROCESSING`` and will happen **before** response generation. | ||
| See `tutorial on pre-response processing`_. | ||
| Node response can be modified with ``PRE_TRANSITION_PROCESSING`` and will happen **after** response generation. | ||
| See `tutorial on pre-transition processing`_. | ||
|
|
||
| * Additional data ``MISC`` can be added to every node, flow and script itself. | ||
| Warning! Unlike the other Context fields, the MISC values are not shared across script executions. | ||
pseusys marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| See `tutorial on script MISC`_. | ||
|
|
||
| Conclusion | ||
| ~~~~~~~~~~ | ||
|
|
||
| In this tutorial, we explored the basics of Dialog Flow Framework (DFF) to build dynamic conversational services. | ||
| By using DFF's intuitive Domain-Specific Language (DSL) and well-structured dialog graphs, we created a simple interaction between user and chat-bot. | ||
| We covered installation, understanding the DSL and building dialog graph. | ||
| However, this is just the beginning. DFF offers a world of possibilities in conversational chat-bot. | ||
| With practice and exploration of advanced features, you can create human-like conversations and reach a wider audience by integrating with various platforms. | ||
| Now, go forth, unleash your creativity, and create captivating conversational services with DFF. | ||
| Happy building! | ||
|
|
||
|
|
||
| .. _tutorial on basic dialog structure: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.1_basics.html | ||
| .. _tutorial on response functions: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.3_responses.html | ||
| .. _documentation of Context object: https://deeppavlov.github.io/dialog_flow_framework/apiref/dff.script.core.context.html | ||
| .. _tutorial on transitions: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.4_transitions.html | ||
| .. _tutorial on conditions: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.2_conditions.html | ||
| .. _tutorial on global transitions: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.5_global_transitions.html | ||
| .. _tutorial on context serialization: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.6_context_serialization.html | ||
| .. _tutorial on pre-response processing: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.7_pre_response_processing.html | ||
| .. _tutorial on pre-transition processing: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.9_pre_transitions_processing.html | ||
| .. _tutorial on script MISC: https://deeppavlov.github.io/dialog_flow_framework/tutorials/tutorials.script.core.8_misc.html | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.