A simple syntax for defining the NLU model for a conversational interface.
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Type Name Latest commit message Commit time
Failed to load latest commit information.


Expando is a translation language for easily defining user utterance examples when building conversational interfaces for Natural Language Understanding services like Dialogflow, LUIS, or the Alexa Skills Kit. This is roughly analagous to the concept of building grammars for speech recognition systems.

Table of Contents

What's all this, then?

The following line of Expando:

(is it possible to|can I|how do I) return (something|an item)

...would be expanded by producing the Cartesian product of the phrases in parentheses that are separated by pipes:

is it possible to return something
is it possible to return an item
can I return something
can I return an item
how do I return something
how do I return an item

This encoding makes it much easier to manage multiple user utterance examples when building conversational interfaces.

Using Expando, you can:

  • House your intents and entities in version control, simplifying collaboration.
  • Use the CLI to automatically update your intents and entities (only supports Dialogflow, at the moment).
  • Make use of the expansion syntax to dramatically simplify the encoding of utterance examples.


This reference implementation of the Expando language is built with Ruby, and packaged as a gem. You can install it with:

$ gem install expando

Getting started

The Expando CLI features an init command for initializing new Expando projects:

$ mkdir support-bot
$ cd support-bot
$ expando init
✓ intents directory created
✓ entities directory created
✓ .expando.rc.yaml file created
✓ circle.yaml file created

This will create intents and entities directories, for housing the utterance examples themselves, as well as some configuration files.

Configure Dialogflow integration

If you'll be using Expando to update the intents and entities of an existing Dialogflow agent, you'll need to copy the client access token and developer access token for the agent to .expando.rc.yaml:

# Dialogflow credentials - add the credentials for your agent below
:client_access_token: REPLACE_WITH_TOKEN
:developer_access_token: REPLACE_WITH_TOKEN

Set up continuous integration

The circle.yaml file can be used to configure CircleCI to enable automatically updating an Dialogflow agent when commits are pushed to your Expando project's repo.

Create intent and entity files

Let's assume we have an agent on Dialogflow named support-bot. If we want to use the Expando syntax for one of this agent's intents named openHours, we'd create a file in the intents directory named openHours.txt.

It's also possible to create expandable entity examples in the same manner. A file named entities/products.txt would match to a products entity on Dialogflow.


Phrase combination

Using the above example, we could include the following line of Expando in the file intents/openHours.txt:

(when|what times) are you open

This would be expanded by creating a version of this utterance with each of the phrases enclosed by paretheses and separated by pipes:

when are you open
what times are you open

If multiple sets of phrases are included on the same line, a Cartesian product of each of the phrases will be created. The following line of Expando:

(when|what times) are (you|y'all|you guys) open

...would result in this full list of utterances:

when are you open
when are y'all open
when are you guys open
what times are you open
what times are y'all open
what times are you guys open

Optional phrases

By making the final phrase in a set blank, you can make it optional. The following Expando:

what are your (open| ) hours

...would result in:

what are your open hours
what are your hours

It's also possible to make an entire set of phrases optional:

what are your (open|business| ) hours

...results in:

what are your open hours
what are your business hours
what are your hours

Essentially, you're making the last phrase in the set an empty string.

Referencing Dialogflow developer entities

If you had the following Dialogflow developer entity location in a file location.txt:

home, house
office, business, work

...you could reference that entity using the Dialogflow template mode syntax in an intent getTemp.txt:

(what is|tell me) the temperature at @location:locationName

Expando will mimic Dialogflow's automatic annotation when you run expando update intents and automatically convert the utterances to template mode syntax by inserting randomly selected canonical entity values for each referenced entity:

what is the temperature at home
tell me the temperature at work

Expando will also automatically annotate the above utterances:

what is the temperature at home
                           @location:locationName => entity:    location
                                                     parameter: locationName

If the message "what is the temperature at home" was received by the Dialogflow agent, it would recognize the following:

  • intentName: getTemp
  • locationName: home

Referencing Dialogflow system entities

You can reference Dialogflow system entities within Expando just as you would any other entity:

I need a ride at @sys.time:pickupTime

Expando will perform the same type of automated expansion that it does for developer entities, automatically inserting example values for the entity:

I need a ride at 2pm
                 @sys.time:pickupTime => entity:    @sys.time
                                         parameter: pickupTime

Adding Dialogflow text responses

Expando supports adding Dialogflow text responses to your intents. In the responses directory of your project, create a file with the same name as an existing intent, with one response per line (up to a maximum of 10):


Definitely! We'll gladly help with your return.
Sure thing! I can help you with that.

Upon running expando update intent canIReturn to update the intent, these text responses will be added to the Dialogflow agent for the intent.

All relevant Expando syntax is supported in these files (i.e. everything except entity referencing.


Starting a line with a # indicates that it is a comment, and should be ignored. The following Expando:

# TODO: need to add more synonyms for good
I'm feeling (good|great|grand)

...results in:

I'm feeling good
I'm feeling great
I'm feeling grand


You can store arbitrary metadata on your intents and entities in the form of YAML front-matter:

# ---
# description: Asking about open hours.
# link: http://realtimeboard/app/board/...
# ---

what are your (open|business| ) hours

You can then list this metadata with the command expando list intents:

metadata example

Updating Dialogflow

In order to update intents or entities on Dialogflow, use the following commands:

$ expando update intents
$ expando update entities

It's also possible to target specific entities or intents for updating:

$ expando update intents openHours

You can also access full help for the Expando CLI:

$ expando --help

..and also help for specific Expando CLI commands:

$ expando update --help


Documentation for the source code of the expando gem itself can be viewed here.


Initial work on Expando was graciously funded by the good folks at vThreat. Expando is brought to you by Voxable, a conversational interface agency in Austin, Texas.