Implementation

The Unified Bot Format

Idea

We wanted to define a stable file format for a chatbot which SMS systems can interface with. This format must only support chatbot capabilities which are relevant to the SMS interface. This gives us the possibility to create an ecosystem where chatbot designs can come from many different sources, not just Voiceflow.

The capabilities that we look for is multi-choice conversation branching. That is, every question has multiple choices, each of which may lead the conversation to a different question. This is a simple idea, but surprisingly, none of the current SMS systems support that in any kind of format, as our research here concluded.

Design

It’s best to explain this by example. Picture the following bot.

{
	"project": {
        "name": "A Fantastic Bot",
        "nodes": {
            "jkl": {
                "type": "start",
                "next": "tty"
            },
            "tty": {
                "type": "speak",
                "content": "What is the meaning of life",
                "next": "abc"
            },
            "kek": {
                "type": "speak",
                "content": "Please answer with yes :)",
                "next": "abc"
            },
            "abc": {
                "type": "choice",
                "options": [
                    {"type": "yes", "next": "aer"},
                    {"type": "no", "next": "kek"}
                ]
            },
            "aer": {
                "type": "speak",
                "content": "Correct answer. You are on your own now",
                "next": "hgf"
            }
        }
    }
}

Even intuitively, you might be able to understand how this chatbot functions. This chatbot asks the yes or no question, “What is the meaning of life?” and doesn’t stop asking until the user answers a yes, after which it exits.

In a way, this format is just a glorified Deterministic Finite Automaton (DFA). The nodes are questions, their state is which question you are currently on, and the input determines the next state.

In particular, we have different types of nodes. One type are speak nodes which send some response and continue to some specific next node. The only node which does conditional branching is the choice node which can branch to multiple nodes based on user input (or branch if the input matches none of the options). Special nodes are start and end with self-explanatory meaning.

Definition

The format is strictly defined in the form of a JSON Schema. In extension, any JSON that passes that schema should be considered an implementation of that format. We chose schema as it serves both definition and verification of the format with the same structure. The schema for a general UBF file is below:

{
        "$schema": "http://json-schema.org/draft-04/schema#",
        "type": "object",
        "properties": {
          "project": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "nodes": {
                "type": "object"
              }
            },
            "required": [
              "name",
              "nodes"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "project"
        ],
        "additionalProperties": false
      }

You can find schema definitions for every part of the UBF file here.