# Tutorial: Building Assistants

After following the basics of setting up an assistant in the [Rasa Tutorial](/content/docs/rasa/user-guide/rasa-tutorial/index.html), we’ll now walk through building a basic FAQ chatbot and then build a bot that can handle contextual conversations.

## Building a simple FAQ assistant

FAQ assistants are the simplest assistants to build and a good place to get started. These assistants allow the user to ask a simple question and get a response. We’re going to build a basic FAQ assistant using features of Rasa designed specifically for this type of assistant.

In this section we’re going to cover the following topics:

- Responding to simple intents with the MemoizationPolicy  
- Handling FAQs using the ResponseSelector

To prepare for this tutorial, we’re going to create a new directory and start a new Rasa project.

```
mkdir rasa-assistant
rasa init
```

Let’s remove the default content from this bot, so that the `nlu.md`, `stories.md` and `domain.yml` files are empty.

### Memoization Policy

The MemoizationPolicy remembers examples from training stories for up to a `max_history` of turns. For the purpose of a simple, context-less FAQ bot, we only need to pay attention to the last message the user sent, and therefore we’ll set that to `1`.

You can do this by editing your `config.yml` file as follows:

```
policies:
- name: MemoizationPolicy
  max_history: 1
- name: MappingPolicy
```

### Adding Intents and Responses to the Domain

Now that we’ve defined our policies, we can add some stories for the `goodbye`, `thank`, and `greet` intents to the `stories.md` file:

```
## greet
* greet
  - utter_greet

## thank
* thank
  - utter_noworries

## goodbye
* bye
  - utter_bye
```

We’ll also need to add the intents, actions, and responses to our `domain.yml` file in the following sections:

```
intents:
  - greet
  - bye
  - thank

responses:
  utter_noworries:
    - text: No worries!
  utter_greet:
    - text: Hi
  utter_bye:
    - text: Bye!
```

### Training the Model

You can now train a first model and test the bot, by running the following commands:

```
rasa train
rasa shell
```

This bot should now be able to reply to the intents we defined consistently, and in any order.

For example:

### Creating a New Assistant Project

To use content from [Sara](https://github.com/RasaHQ/rasa-demo), the Rasa assistant that, amongst other things, helps the user get started with the Rasa products, we can create a new project.

### Sample Intents

To prepare for testing, we can add some sample intents to our `nlu.md` file:

```
## intent:greet
- Hi
- Hey
- Hi bot
- Hey bot
- Hello
- Good morning

## intent:bye
- goodbye
- goodnight
- see ya
- farewell

## intent:thank
- Thanks
- Thank you
```

### Testing the Bot

Once you’ve added the intents and trained your model, test it by running:

```
rasa shell
```

### Handling Contextual Conversations

For the next step, we will expand our bot to handle contextual conversations. In this section we’re going to cover a variety of topics:

- Handling business logic  
- Handling unexpected user input  
- Failing gracefully  
- More complex contextual conversations

Since the user goals can involve collecting information, it is important to define the `SalesForm` as a new class in the `actions.py` file.

```python
from rasa_sdk.forms import FormAction

class SalesForm(FormAction):
    def name(self):
        return "sales_form"
```

### Required Slots

Next we have to define the `required_slots` method which specifies which pieces of information to ask for. A sample for the sales information might look like:

```python
@staticmethod
def required_slots(tracker):
    return [
        "job_function",
        "use_case",
        "budget",
        "person_name",
        "company",
        "business_email",
    ]
```

### Submitting the Form

The next step is defining the `submit` method, to do something with the information the user has provided once the form is complete:

```python
def submit(self, dispatcher: CollectingDispatcher, tracker: Tracker, domain: Dict[Text, Any]):
    dispatcher.utter_message("Thanks for getting in touch, we’ll contact you soon")
    return []
```

### Handling Unexpected User Input

The decision to handle these types of user input should always come from reviewing real conversations. If a user sends something unexpected, handle it using the `out_of_scope` intent to give a default response.

```yaml
* out_of_scope
  utter_out_of_scope
```

### Implementing Failures Gracefully

If the assistant encounters unexpected input, ensure it fails gracefully, providing messages that guide the user back to the conversation.

```yaml
responses:
  utter_out_of_scope:
  - text: Sorry, I can’t handle that request.
```

Re-train your model and test it. The bot should now be capable of handling FAQs and return relevant information based on user inputs.
