# Build your first Rasa agent

Source: https://rasa.community/quickstart/
Author: Rasa team
Published: 2026-09-09

You will build **Juniper**, a plant-shop assistant that answers stock questions using a Python tool. Ask about a monstera and it looks up the count. Ask about an orchid and it explains that the shop has no record for it. You will see the evidence behind the reply, then change the data and run the agent again.

This is the complete local path: one downloadable project, one model configuration and one stock tool. You do not need Git, Docker, a coding assistant, a microphone or another tutorial. A terminal and a text editor are enough.

## 1. Get your two keys and install uv

Have these ready before training:

| What you need                                | Where it comes from                                          | What it does                                 |
| -------------------------------------------- | ------------------------------------------------------------ | -------------------------------------------- |
| Rasa Developer Edition licence               | The key sent by Rasa after your [licence request](/license/) | Enables the Rasa runtime                     |
| OpenAI API key with access to `gpt-4.1-mini` | Your model-provider account                                  | Powers the agent's language model            |
| uv                                           | The commands below                                           | Installs Python and the project dependencies |

An accepted licence request is not an issued licence. You can download the project and run its offline checks while waiting for the key. Your model-provider account is separate from your Rasa licence; model requests may incur provider charges. The project sends your chat messages and fictional stock-tool results to that provider, so use the example questions rather than personal data.

<details open>
<summary>macOS or Linux: install uv</summary>

Open Terminal and run the [official uv installer](https://docs.astral.sh/uv/getting-started/installation/):

```sh
curl -LsSf https://astral.sh/uv/install.sh | sh
```

Close and reopen the terminal, then run `uv --version`.

</details>

<details>
<summary>Windows: install uv</summary>

Open PowerShell and run the official uv installer:

```powershell
powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
```

Close and reopen PowerShell, then run `uv --version`. The project commands in the rest of this guide are the same on Windows, macOS and Linux.

</details>

The starter selects Python 3.12 and pins **Rasa Pro 3.20.0.dev6**. This is a Mantle beta build, matching this community's Skills tutorials. Keep the pin for this exercise; installing an arbitrary latest version can change the engine or configuration format. The lockfile fixes the dependency set. This is a local learning project, not a production deployment.

## 2. Download and open the project

[Download the complete starter ZIP](/quickstart/rasa-first-agent.zip). Extract it, then open the extracted `rasa-first-agent` folder in your editor. Use the editor's **Open in Integrated Terminal** command, or open a terminal and `cd` to that folder. Your terminal must be in the folder containing `pyproject.toml`.

Run:

```sh
uv sync --locked
uv run python check.py setup
```

The first command installs the selected Python version if needed and the locked dependencies. It can take longer on the first run. The second creates `.env` without overwriting an existing file.

You should see `Created .env. Open it in your editor and fill in the two keys.` If you already ran setup, it will say your existing values were preserved.

This is the complete project you will use:

```text
rasa-first-agent/
├── .env.example                 # empty credential fields
├── .env                         # your local keys, created by setup
├── pyproject.toml + uv.lock      # pinned runtime and dependencies
├── agent.yml                    # Juniper's identity and limits
├── integrations.yml             # model and local chat channels
├── check.py                     # offline setup and tool checks
└── skills/check_stock/
    ├── skill.md                 # when and how to look up stock
    └── tools.py                 # fictional data and the lookup tool
```

## 3. Put the keys in your local .env

Open `.env` in your editor. Fill in the two empty values, keeping each complete key on one line:

```dotenv
RASA_LICENSE=your_complete_rasa_licence_key
OPENAI_API_KEY=your_openai_api_key
```

Replace the example values with your own keys and save the file. Do not paste them into this website, a chat message, a screenshot or a Git commit. The included `.gitignore` excludes `.env`. The Rasa commands read it from the project directory, so keep using that directory.

The model configuration is already supplied in `integrations.yml`: the `orchestrator` model group uses OpenAI's `gpt-4.1-mini` and reads `OPENAI_API_KEY`. No additional model choice or configuration edit is needed for this path.

## 4. Check, train and open the agent

First run the local tool checks:

```sh
uv run python check.py
```

Look for:

```text
PASS: known plant, out of stock, unknown plant, no data writes.
```

This executes the real decorated stock tool against synthetic data. It does **not** validate your licence, call a model or prove that the conversational agent works. A message saying both key fields are filled only checks that they are nonempty.

Now run the actual Rasa steps:

```sh
uv run rasa train
uv run rasa inspect
```

Training must complete and create a model under `models/` before you continue. Inspector is the local chat and debugging interface. Open the URL printed in your terminal, normally [localhost:5005/webhooks/inspector/](http://localhost:5005/webhooks/inspector/). Leave the terminal running while you chat. If the browser did not open automatically, copy the printed URL into it.

## 5. Prove where the answer came from

In Inspector, start a new conversation and send the questions below. Open the execution trace for each turn and find `check_stock`. Exact sentence wording can vary; the facts and tool calls must meet these checks.

| Send this                        | Inspect this evidence                                                             | Accept the result only when                                                 |
| -------------------------------- | --------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `How many monstera do you have?` | `check_stock` receives `monstera`; its result has `found: true` and `quantity: 7` | The reply reports 7, grounded in that tool result                           |
| `What about fern?`               | A new lookup receives `fern`, returning `quantity: 0`                             | The reply says out of stock; it does not reuse 7                            |
| `Do you have orchids?`           | An unknown plant lookup returns `found: false` and available plant names          | The reply explains that there is no record, rather than claiming zero stock |
| `Reserve two monstera for me`    | There is no reservation or payment tool in this project                           | The reply explains the limit and does not claim a reservation               |

If a response sounds convincing but there is no matching tool call, the check has failed. Inspect `skills/check_stock/skill.md`, which tells the agent to call the tool for each stock question. Then inspect `tools.py`, which owns the data. A language-model instruction shapes behaviour; it is not a general security boundary. This example cannot write to a shop because no shop connection or write tool exists.

The first three rows distinguish **known stock**, **zero stock** and **unknown stock**. That difference is part of the product behaviour, not just a Python detail. You have a first working agent when all four checks pass in your own Inspector session.

## 6. Make one change and run it again

In `skills/check_stock/tools.py`, change only the monstera quantity:

```python
STOCK = {"monstera": 4, "fern": 0, "cactus": 12}
```

Save the file. Stop Inspector with **Ctrl+C** in its terminal, then run:

```sh
uv run python check.py
uv run rasa train
uv run rasa inspect
```

Start a new conversation and ask about monstera again. The tool result and reply should now report **4**. Repeat the fern and orchid checks: changing one quantity must not erase the difference between zero and unknown. If the reply still says 7, confirm you saved the file in this project, trained a fresh model and restarted Inspector.

You have now completed the loop: edit a source file, check the tool, build the model and verify the conversation. Keep a short record of the four test questions, observed tool results, model version and any failures. An engineer can own this run record; a conversation designer or product colleague can review whether the replies explain the stock and reservation limits clearly.

## If something stops you

| Symptom                                           | Do this next                                                                                                                                                                               |
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `uv` is not recognised                            | Reopen the terminal after installation, then run `uv --version`. Check the [uv installation instructions](https://docs.astral.sh/uv/getting-started/installation/) if it is still missing. |
| No `pyproject.toml` found                         | Open the extracted inner `rasa-first-agent` folder in your terminal, not its parent or the ZIP preview.                                                                                    |
| Package install fails                             | Check network access and available disk space. Keep `.python-version` and `uv.lock` unchanged; retry `uv sync --locked`. Do not solve it by installing a different Rasa version globally.  |
| Licence validation fails                          | Confirm Rasa has actually issued the key. Save the complete single-line value as `RASA_LICENSE` in this project's `.env`; rerun training from the same folder.                             |
| Model authentication, model access or quota error | Check `OPENAI_API_KEY`, access to `gpt-4.1-mini` and the provider account's available quota. A Rasa licence does not grant model-provider access.                                          |
| Inspector cannot find a model                     | Finish `uv run rasa train` successfully before starting Inspector.                                                                                                                         |
| Port 5005 is already in use                       | Stop the earlier Inspector process with Ctrl+C and rerun the command.                                                                                                                      |
| Tool checks pass but the conversation fails       | Read the failed turn's tool trace, compare it with the table above and record the discrepancy. Offline tool tests do not test model routing or wording.                                    |

For help, share the failing command, Rasa version and a redacted error in the [community](/join/). Keep licence strings, API keys and personal messages out of the report.

## What to build next

Use the [tools and memory tutorial](/library/tutorials/tools-and-memory/) to add another capability, or explore the [showcase](/showcase/) for a build in your domain. The [library](/library/) is where you deepen a specific design, evaluation or engineering skill.

Before using real customer data, agree the task and permitted actions with a product/domain owner, add authentication and authorisation at your data boundary, and build an evaluation set that covers failures as well as the normal path. The stock exercise does not establish production reliability, access control or a release decision.

This guide is maintained against the pinned package and the downloadable source. For platform-wide alternatives, use Rasa's [installation documentation](https://rasa.com/docs/pro/installation/python/), [Developer Quickstart](https://rasa.com/docs/learn/quickstart/pro/) and [Rasa Pro release](https://pypi.org/project/rasa-pro/3.20.0.dev6/). The offline checks exercise tool behaviour; the licensed Inspector steps above are your live acceptance check.