arrow-left

All pages
gitbookPowered by GitBook
1 of 6

Loading...

Loading...

Loading...

Loading...

Loading...

Loading...

2.5. Quiz

Quiz 2: Dialogue Graph

hashtag
Overview

You run a hair salon and recently adopted a dialogue system to take a call from a customer and book a service for the customer:

Your salon provides three services: haircut, hair coloring, and perms. Your system should reject any other service request from the customer:

Your system should understand the following dates: Monday ~ Saturday. The time is always followed by the date with the following format: <number><space><AM|PM>:

Only the following times and dates are available for the specific services:

  • Haircut:

    • Monday 10 AM, 1 PM, 2 PM

    • Tuesday: 2 PM

Thus, your system should not schedule an appointment for any other slots:

circle-check

Make sure your system does not throw an exception in any situation.

hashtag
Task 1

  1. Create a python file under the package and copy the code.

  2. Update the transitions to design a dialogue flow for the above dialogue system.

hashtag
Task 2

  • Create a PDF file quiz2.pdf that describes the limitations of your system.

hashtag
Submission

  1. Commit and push quiz2.py to your GitHub repository.

  2. Submit quiz2.pdf to Canvas.

S: Hello, how can I help you?
U: Hi, I'd like to book a haircut.
S: Sure. What date and time are you looking for?
U: Tuesday at 2 PM.
S: Your appointment is set. See you!
S: Hello, how can I help you?
U: Can I make an appointment for waxing?
S: Sorry, we do not provide that service.
U: OK then.
S: Goodbye.

Hair coloring:

  • Wednesday: 10 AM, 11 AM, 1 PM

  • Thursday: 10 AM, 11 AM

  • Perms

    • Friday: 10 AM, 11 AM, 1 PM, 2 PM

    • Saturday: 10 AM, 2 PM

  • quiz2.pyarrow-up-right
    quizarrow-up-right
    S: Hello, how can I help you?
    U: Can I make an appointment for a perm?
    S: Sure. What date and time are you looking for?
    U: Saturday 10 AM.
    S: Your appointment is set. See you!
    S: Hello, how can I help you?
    U: Hi, I'd like to book a haircut.
    S: Sure. What date and time are you looking for?
    U: Saturday 10 AM.
    S: Sorry, that slot is not available for a haircut.
    U: OK.
    S: Goodbye.

    2.2. State Transition

    Create a dialogue flow using state transitions.

    hashtag
    Dialogue Flow

    Let us create a dictionary called transitions and name its initial state as start:

    • #1: transitions is a .

    Add transitions to conduct a single-turn dialogue:

    • #3: the system begins the dialogue by saying, "Hello. How are you?".

    • #4: the system matches the user input with 'good'.

    circle-info

    All keys and values must be in the type, where literals need to be surrounded by reversed primes (e.g., '`Hello. How are you?`').

    There are two ways to create a string in Python, using single quotes (e.g., 'Hello') and double quotes (e.g., "Hello"). When you use single quotes, any single quote inside the string needs to be escaped by a backslash (e.g., 'I\'m "good"!'). Similarly, when you use double quotes, any double quote needs to be escaped (e.g., "I'm \"good\"!").

    Create the dialogue flow df that expects the initial state start and the final state end, which must match the names of the initial and final states in transitions:

    • #1: the import statement should be on top of the source code (see ).

    • #2:

    Load the transitions to the dialogue flow df:

    Finally, run the dialogue flow:

    • #1:

    1. Enter inputs such as "good", "Good", or "Good!" (separately) and see how the system responds. Does the system respond differently?

    2. How does the system respond to inputs like "fantastic" or "bad"?

    hashtag
    Branching

    Let us add a transition such that it can also handle the input 'bad':

    • #7-9: a new transition for the 'bad' condition.

    When you load the new transitions and run the dialogue flow, it now gives proper responses to both 'good' and 'bad':

    hashtag
    Error Handling

    Even with branching, it still throws errors for other inputs. Let us add an error transition to set the default statement for all the other inputs:

    • #10-12: an error transition to generate the default response.

    circle-check

    Make sure to put a default error statement for every branching; otherwise, it will throw an exception during runtime, which can be detrimental.

    hashtag
    Code Snippet

    • #3: although Python is a dynamically-typed language, it allows you to indicate the type of a variable or a function using (since Python 3.5).

    transitions = {'state': 'start'}
    #5: the system responds to the user with "Glad to hear that ..." and recognizes that it is the final state end.

    User inputs get automatically lowercased and tokenizedarrow-up-right before matching. Thus, the system gives the same response to those inputs.

  • If the input does not match 'good' exactly, the system throws an error because no exception is currently handled in our code.

  • S: Hello. How are you?
    U: Good!
    S: Glad to hear that you are doing well :)
    dictionaryarrow-up-right
    stringarrow-up-right
    dialogue_graph.pyarrow-up-right
    keyword vs. positional argumentsarrow-up-right
    top-level code environmentarrow-up-right
    typingarrow-up-right
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            'good': {
                '`Glad to hear that you are doing well :)`': 'end'
            }
        }
    }
    from emora_stdm import DialogueFlow
    df = DialogueFlow('start', end_state='end')
    df.load_transitions(transitions)
    if __name__ == '__main__':
        df.run()
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            'good': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            'bad': {
                '`I hope your day gets better soon :(`': 'end'
            }
        }
    }
    S: Hello. How are you?
    U: Good
    S: Glad to hear that you are doing well :)
    S: Hello. How are you?
    U: Bad
    S: I hope your day gets better soon :(
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            'good': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            'bad': {
                '`I hope your day gets better soon :(`': 'end'
            },
            'error': {
                '`Sorry, I didn\'t understand you.`': 'end'
            }
        }
    }
    S: Hello. How are you?
    U: It could be better.
    S: Sorry, I didn't understand you.
    from emora_stdm import DialogueFlow
    
    def state_transition() -> DialogueFlow:
        transitions = {
            'state': 'start',
            '`Hello. How are you?`': {
                'good': {
                    '`Glad to hear that you are doing well :)`': 'end'
                },
                'bad': {
                    '`I hope your day gets better soon :(`': 'end'
                },
                'error': {
                    '`Sorry, I didn\'t understand you.`': 'end'
                }
            }
        }
    
        df = DialogueFlow('start', end_state='end')
        df.load_transitions(transitions)
        return df
    
    if __name__ == '__main__':
        state_transition().run()

    2. Dialogue Graph

    This chapter provides how to build a simple dialogue graph using Emora STDM.

    hashtag
    Content

    1. Emora STDM

    hashtag
    Resource

    • Source code:

    2.1. Emora STDM

    Introduce Emora State Transition Dialogue Manager.

    Emora State Transition Dialogue Manager (STDM) is a dialogue system development framework that seamlessly integrates intent classification, pattern recognition, state machine, and information state approaches to dialogue management and natural language understanding. It supports rapid prototyping and long-term team-based development workflows, catering to a wide range of developer expertise.

    circle-check

    Make sure you have the emora_stdm package installed from the .

    State Transition
    Matching Strategy
    Multi-turn Dialogue
    Quiz
    dialogue_graph.pyarrow-up-right
    hashtag
    References
    • , James D. Finch and Jinho D. Choi, Proceedings of the Annual Meeting of the Special Interest Group on Discourse and Dialogue: System Demonstrations (SIGDIAL:DEMO), 2020.

    Environment Setup
    Figure 1 from .
    Emora STDM: A Versatile Framework for Innovative Dialogue System Developmentarrow-up-right
    Emora STDM GitHub Repositoryarrow-up-right
    Finch and Choi, SIGDIAL 2020arrow-up-right

    2.3. Matching Strategy

    A taste of matching strategies provided in Emora STDM.

    hashtag
    Multiple Matching

    There is more than one way of expressing "good" or "bad". Let us use a setarrow-up-right to match multiple expressions per condition by surrounding them with curly brackets:

    • #4: matches the input with either 'good' or 'fantastic'.

    • #7: matches the input with either 'bad' or 'could be better'.

    The above transitions can handle the following inputs (on top of the cases of good and bad):

    circle-info

    A phrase can be used for matching, although it needs to match the entire input such that 'could be better' in #7 does not match an input like "It could be better".

    Enter inputs such as "I'm good" or "Pretty bad" and see how the system responds.

    It responds with the error statement because the string key (e.g., 'good', 'bad') does not match the entire input (e.g., "I'm good", "Pretty bad").

    If you replace 'bad' in #7 with 'pretty bad', it matches the input "Pretty bad". However, it no longer matches the input "bad".

    triangle-exclamation

    Currently, STDM does not allow you to insert a single quote (') in any condition such that if you replace 'good' in #4 with 'I\'m good', it will throw a runtime error. This bug will be fixed in the next version.

    hashtag
    Partial Matching

    Matching the entire input is often too restrictive. Let us use a to allow partial matching:

    • #4: the keyword 'good' is surrounded by the square brackets (good -> [good]), and matched to any word in the input.

    • #7: the keyphrase 'could be better' is surrounded by the square brackets, and matched to any phrase in the input.

    circle-exclamation

    What are the differences between a set and a list in general data structures?

    The above transitions yield the following dialogues:

    Replace the condition in #4 with '[good, fantastic]'. Does it respond as expected?

    All terms in a list must match some terms in the input sequentially. Thus, by replacing '[good]' with '[good, fantastic]', it no longer understands the inputs "good" or "fantastic":

    Instead, it understands the input "good and fantastic" by matching "good" first, then "fantastic" later:

    See

    hashtag
    Nesting

    To allow partial matching of multiple expressions, a set can be put in a list:

    • #4: the keywords 'good' and 'fantastic' are first put in a set for multiple matching and then in a list for partial matching.

    • #7: the keyword 'bad' and the keyphrase 'could be better' are first put in a set for multiple matching, then in a list for partial matching.

    circle-exclamation

    What are the meanings of nesting a set inside a list vs. a list inside a set?

    What happens if '[{good, fantastic}]' in #4 is replaced with '{[good, fantastic]}'; in other words, put the keywords in a list first, then in a set?

    It behaves the same way as the one in Exercise 2.

    hashtag
    Sequential Matching

    Keywords or keyphrases delimited by commas in a list are matched sequentially:

    • #10: first matches 'how', then matches 'you' sequentially so that "how" must be followed by "you" in the input for this condition to be true.

    All terms in the list must be matched sequentially such that the conditions are false for the following cases:

    Let us replace 'how' with '{how, and}' and 'you' with '{you, going}' in #10:

    • #10: first matches ('how' or 'and'), then matches ('you' or 'going') sequentially.

    circle-exclamation

    What other inputs does the condition in #10 match? Is there any consequence of matching that many expressions?

    How does the system respond when the input is "Good, how are you"?

    Since both the conditions in #5 and #11 match the input, it randomly chooses one of the responses such that it can nondeterministically generate either of the followings:

    hashtag
    Code Snippet

    2.4. Multi-turn Dialogue

    Create a multi-turn dialogue flow.

    All examples in the previous session are single-turn dialogues, where users get to interact with the system only once. Let us design a multi-turn dialogue:

    • #5: after the system says "Glad to ...", it matches the input with those conditions.

    • #6: if the condition in #5 is true, the system responds with "I feel superb ...".

    The condition in #6 does not come with the default action indicated by an error transition. Let us create an error transition for it:

    • #10: prompts the error statement for any other inputs.

    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            '{good, fantastic}': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            '{bad, could be better}': {
                '`I hope your day gets better soon :(`': 'end'
            },
            'error': {
                '`Sorry, I didn\'t understand you.`': 'end'
            }
        }
    }
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            '[{good, fantastic}]': {
                '`Glad to hear that you are doing well :)`': {
                    '[{how, and}, {you, going}]': {
                        '`I feel superb. Thank you!`': 'end'
                    }
                }
            },
            'error': {
                '`Got it; thanks for sharing.`': 'end'
            },
        }
    }
    for more details.
    listarrow-up-right
    Sequential Matching
    S: Hello. How are you?
    U: Good!
    S: Glad to hear that you are doing well :)
    U: How are you doing?
    S: I feel superb. Thank you!
    S: Hello. How are you?
    U: Fantastic
    S: Glad to hear that you are doing well :)
    U: Thank you!
    Traceback (most recent call last):
    ...
    S: Hello. How are you?
    U: Fantastic!!
    S: Glad to hear that you are doing well :)
    S: Hello. How are you?
    U: Could be better..
    S: I hope your day gets better soon :(
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            '[good]': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            '[could be better]': {
                '`I hope your day gets better soon :(`': 'end'
            },
            'error': {
                '`Sorry, I didn\'t understand you.`': 'end'
            },
        }
    }
    S: Hello. How are you?
    U: I'm good!!
    S: Glad to hear that you are doing well :)
    S: Hello. How are you?
    U: It could be better..
    S: I hope your day gets better soon :(
    S: Hello. How are you?
    U: good
    S: Sorry, I didn't understand you.
    S: Hello. How are you?
    U: fantastic
    S: Sorry, I didn't understand you.
    S: Hello. How are you?
    U: good and fantastic!
    S: Glad to hear that you are doing well :)
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            '[{good, fantastic}]': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            '[{bad, could be better}]': {
                '`I hope your day gets better soon :(`': 'end'
            },
            'error': {
                '`Sorry, I didn\'t understand you.`': 'end'
            },
        }
    }
    S: Hello. How are you?
    U: I'm so good!
    S: Glad to hear that you are doing well :)
    S: Hello. How are you?
    U: It's fantastic!!
    S: Glad to hear that you are doing well :)
    S: Hello. How are you?
    U: Pretty bad..
    S: I hope your day gets better soon :(
    S: Hello. How are you?
    U: It could be better.
    S: I hope your day gets better soon :(
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            '[{good, fantastic}]': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            '[{bad, could be better}]': {
                '`I hope your day gets better soon :(`': 'end'
            },
            '[how, you]': {
                '`I feel superb. Thank you!`': 'end'
            },
            'error': {
                '`Sorry, I didn\'t understand you.`': 'end'
            },
        }
    }
    S: Hello. How are you?
    U: Fine. How are you doing?
    S: I feel superb. Thank you!
    S: Hello. How are you?
    U: Fine. How is it going?
    S: Sorry, I didn't understand you.
    S: Hello. How are you?
    U: Fine, and you?
    S: Sorry, I didn't understand you.
    transitions = {
        'state': 'start',
        '`Hello. How are you?`': {
            '[{good, fantastic}]': {
                '`Glad to hear that you are doing well :)`': 'end'
            },
            '[{bad, could be better}]': {
                '`I hope your day gets better soon :(`': 'end'
            },
            '[{how, and}, {you, going}]': {
                '`I feel superb. Thank you!`': 'end'
            },
            'error': {
                '`Sorry, I didn\'t understand you.`': 'end'
            },
        }
    }
    S: Hello. How are you?
    U: Fine. How is it going?
    S: I feel superb. Thank you!
    S: Hello. How are you?
    U: Fine, and you?
    S: I feel superb. Thank you!
    S: Hello. How are you?
    U: Good, how are you?
    S: Glad to hear that you are doing well :)
    S: Hello. How are you?
    U: Good, how are you?
    S: I feel superb. Thank you!
    def matching_strategy() -> DialogueFlow:
        transitions = {
            'state': 'start',
            '`Hello. How are you?`': {
                '[{good, fantastic}]': {
                    '`Glad to hear that you are doing well :)`': 'end'
                },
                '[{bad, could be better}]': {
                    '`I hope your day gets better soon :(`': 'end'
                },
                '[{how, and}, {you, going}]': {
                    '`I feel superb. Thank you!`': 'end'
                },
                'error': {
                    '`Sorry, I didn\'t understand you.`': 'end'
                },
            }
        }
    
        df = DialogueFlow('start', end_state='end')
        df.load_transitions(transitions)
        return df
    
    if __name__ == '__main__':
        matching_strategy().run()
    def multiturn_dialogue() -> DialogueFlow:
        transitions = {
            'state': 'start',
            '`Hello. How are you?`': {
                '[{good, fantastic}]': {
                    '`Glad to hear that you are doing well :)`': {
                        '[{how, and}, {you, going}]': {
                            '`I feel superb. Thank you!`': 'end'
                        },
                        'error': {
                            '`You are the best!`': 'end'
                        }
                    }
                },
                'error': {
                    '`Got it; thanks for sharing.`': 'end'
                },
            }
        }
    
        df = DialogueFlow('start', end_state='end')
        df.load_transitions(transitions)
        return df
    
    
    if __name__ == '__main__':
        multiturn_dialogue().run()
    S: Hello. How are you?
    U: Fantastic!
    S: Glad to hear that you are doing well :)
    U: Thank you!
    S: You are the best!