Skip to content

Writing dialogs

Matúš Žilinec edited this page May 3, 2018 · 12 revisions

Making sense of received messages

We need to understand what the user wants, or in other words, what is their intent. We also need to extract entities like names, dates and places.

To do this, we will use Wit.ai. Create a project there and copy your token to GOLEM_CONFIG.

You can train Wit.ai on examples - type a sentence like Hello world and set its intent to greeting. Now if someone types a similar sentence, Wit.ai should classify it as greeting. See Wit docs for details.

Creating dialog flows

Dialogue with the chatbot consists of so-called flows. Each flow is essentially a module that handles conversation about a particular topic. So for example you might have flows for greeting, telling a joke, ordering a pizza etc. Each flow has one or more states that represent specific points in the conversation.

Your dialog begins in a flow called default. Each flow starts in the root state. For example, if Wit.ai detects intent greeting, golem will move to state greeting.root if it exists.

Flows are defined in python like this:

{
    'default' : { # name of the flow, automatically accept intent of the same name
        'intent' : '(greeting|help)', # regex of additional intents to accept 
        'states' : { # states of the flow
            'root' : { # the root state, required. Will move here on intent 'greeting' or 'help'
                'accept' : { # action defined by a template
                    'template' : 'message',
                    'params' : {
                        'message' : 'Hi, welcome to IT support! :)',
                        'next' : 'question'
                    }
                }
            },
            'question' : { 
                'init' : my_custom_action, # action defined by a function
                'accept' : my_input_action
            },
            'like' : {
                'intent' : 'like', # move to this state if intent 'like' is accepted in the 'default' flow
                'accept' : my_like_action
            }
         ...
        }
    }

The bot moves between states when:

  • the extracted intent matches one of flows, this triggers its root state
  • you set the next parameter or you return a state name from an action

Each action can either be hardcoded in the dialog definition, or you can use your own function such as my_like_action. This function must take one parameter - state (more on that later) and returns a tuple of (response, next_state_name). For example:

def my_like_action(state: State) -> tuple:
    msg = # your logic here
    msg_1 = TextMessage("Hello World")
    msg_1.with_button(LinkButton("Our website", "http://example.com"))
    msg_2 = GenericTemplateMessage()
    msg_2.add_element(GenericTemplateElement(
        title="List item #1",
        image_url="http://placehold.it/300x300"
    ))
    return [msg, msg_1, "Another message"], "default.root"

The returned message can be:

  • a string,
  • an instance of golem.core.responses.MessageElement or
  • a list of responses.

The next state can be either a state name, like default.root:accept or None (if the bot should stay in the same state).

You also need to register the flow in the BOTSsection of GOLEM_CONFIG, as shown on the previous page. This way, you can easily enable and disable modules of your chatbot using the config file.

That's the basics. Now go and make a chatbot!