Building Chatbots – Introduction

This is really a hot topic these days: Chatbots . In this tutorial, we’re diving in the world of chatbots and how they are built.

What are chatbots?

Chatbots are systems that can have a fairly complex conversation with humans. They can go by different names: Conversational Agents or Dialog Systems . As you’ve probably guessed, chatbots use a lot of Natural Language Processing techniques in order to understand the human’s requests.

The Holy Grail of chatbot builders is to pass the Turing Test. This means that a human can’t figure out that he’s talking to an actual human. Although we are pretty far from that, (especially from a Natural Language Generation point of view) great progress has been made.

Most of the chatbots that are built these days are goal-oriented agents. This means that they will steer the conversation towards achieving a certain predefined goal. We can have customer support agents that figure out what the problem the user is facing and then solving it (or just opening a ticket).

Chatbots can use several types of engines for understanding conversation. Most of the modern chatbots use one or more of these architectures

  • Rule-based Systems: Handcrafted rules
  • Information Retrieval Systems: Search for the information in a collection of texts then present it to the user
  • Transduction models: Use deep learning models for understanding the input and generating the output.

Natural Language Understanding

Natural Language Understanding (NLU for short) is a term used to refer to the core of a chatbot, the part that deals with understanding what the human says. There is a very popular architecture type, that almost all NLU engines (both opensource and proprietary) use.

This architecture implies processing the user input in two steps:

  1. Determine the intent: schedule-meeting, buy-tickets, complaint, ask-question, ask-for-refund, get-account-information
  2. Extract entities (process also called slot filling ): Each intent can support arguments. For example, the schedule-meeting intent can support the when of type datetime and who of type Person

Let’s take a quick and simple example:

  1. Hello MeetingBot : [intent: "hello", slots: {}]
  2. Hi Andrew
  3. Can you schedule a meeting with John Smith for tomorrow morning? [intent: "schedule-meeting", slots: {when: "tomorrow morning", who: "John Smith"}]
  4. I’ve booked meeting room B for 9am February 12th for 1h. I’ll send a notification to John Smith.

This is how most of the chatbots out there understand conversations. There is another phase I didn’t capture in my example: slot resolution phase. We don’t have a way of using “tomorrow morning”. We need to transform it into an actual datetime. The same goes for John Smith, we need to assign that string to an actual contact from out phone.

NLU Frameworks

There are a lot of frameworks out there. Here are the most popular ones:

  1. DialogFlow – from Google
  2. – from Facebook
  3. – from Microsoft
  4. IBM Watson – from IBM
  5. Amazon Lex – from Amazon
  6. Rasa NLU – Open Source
  7. – Open Source

The proprietary ones have GUI you can use to train your engine. You can create intents and then give various examples for each intent. This way you train an engine to understand your specific needs. After that, you can highlight the entities and assign a type and the engine will also do the resolution automatically. After this, you can interact with your engine via a REST API.

The open source ones can be used programmatically. Both RasaNLU and Snips are python libraries that can be easily installed. This way you keep your models local. No need for Google/Amazon/Facebook/IBM/Microsoft to know what your chatbot is doing. There are obvious advantages of using proprietary engines as well:

  • No need to manage infrastructure
  • No need to handle scaling
  • Lower costs for infrastructure
  • Customer Support

Here is a comparative study between the most popular NLU engines: Evaluating NLU Engines. Note that the paper does not take into consideration. The main takeaway is that the performance of the systems is very similar, thus, choosing the opensource solution does not compromise accuracy.

Following this study, Snips did a side-by-side comparison of their own NLU engine and the commercial ones. You can read about the results here: Snips Benchmark. Main takeaway: Snips outperforms his proprietary competitors on various benchmarks.

Getting Started with RasaNLU

Let’s dive into Natural Language Understanding with Rasa. It’s a fairly simple process, that goes like this:

  1. Install RasaNLU: pip install rasa_nlu rasa_core
  2. Launch the NLU server: python -m rasa_nlu.server --path=~/Desktop
  3. Test that the server is working properly: curl 'http://localhost:5000/parse?q=hi'
  4. Create a config file, containing the training set
  5. Test how the trained model is performing

Here’s the file from step4:

This file tells the server we want to create a new model for the English language using the spacy_sklearn backend. RasaNLU also offers a TensorFlow backend, but that only makes sense when we have a lot of data. Let’s name the file rasa_nlu_model.yaml and save it somewhere handy. Here’s how to train a new model using that file:

Let’s now take our new model for a spin:

Let’s do another one:

Pretty simple, right? Notice how the results are not perfect. For example, the name “George” was not properly extracted. Probably providing more examples will make it more accurate.

Getting Started with Snips-NLU

Here’s how to install Snips: pip install snips-nlu. We will also need to download some English linguistic resources: python -m snips_nlu download en.

Working with Snips is pretty similar to working with Rasa. Let’s start by creating a dataset. In the case of Snips, we need different files for each intent and for each entity. It’s worth mentioning the subtle difference between entities and slots. Entities are real-world classes of objects. For example, city is an entity. departure_city is a slot, and it is of type city. Let’s write the equivalent intent files for the previous example:






Let’s now create the dataset in the Snips format. These files are just a convenient way for us to organize the intents and entities. Snips expects a single json file:

Take a few minutes to look at the json file.

Let’s now actually train a Snips model. Here’s the easy command for doing just that:

Querying the engine goes like this:

Notice how Snips was able to detect that Indonesian is a cuisine, even though it wasn’t in the training dataset.


  1. There are a plethora of alternative NLU engines for building chatbots
  2. The basis for building chatbots is having an NLU engine handy. We can then build answers, interact with API and maintain state around this NLU.
  3. There a both proprietary and open-source NLU engine alternatives. Both deserve attention.
  4. All of the engines provide a pretty similar functionality. The differences are in the details and formats used.