Skip to content
RasaGet a free licence
Menu

tutorial

Chapter 4 of 4

Train and test your Mantle plant-shop assistant

by Rod Rivera Published

Train Juniper, try its conversation and distinguish configuration checks from evidence that it handles a customer’s request.

You have built Juniper, the fictional plant-shop assistant, and checked its configuration. Now you will add your local credentials, train it and try a conversation.

A successful configuration check and a successful training run answer different questions. This chapter shows how to review both before deciding whether the assistant handles a customer’s request correctly.

Credentials, then life

make env

That copies .env.example to .env. Open .env in any editor and fill in:

VariableWhere it comes from
RASA_LICENSEFree Developer Edition key — a long one-line JWT
OPENAI_API_KEYYour OpenAI account

Remember Chapter 3, break #7: this file is gitignored, the hook scans for keys everywhere else, and that combination is what makes this step safe.

make install    # uv downloads rasa-pro (a few minutes, first time only)
make train      # validate + teach the engine your agent
make chat       # 🎉
you  do you have anything that survives a dark bathroom?
bot  Yes — a ZZ plant or a snake plant would be happy there.
     Want me to check what's in stock?

If anything failed instead, don’t debug from scratch — the mantle-upgrade-and-debug skill opens with a failure→cause table: eleven real error messages mapped to their actual causes and fixes. Mantle symptoms often point far from their causes; the table is the shortcut across that gap. It’s also just Markdown — keep it open in a tab.

An honest word about your green checkmarks

You now have two layers of verification, and knowing the difference is what separates “it’s green” from “it works”:

LayerCommandProvesDoesn’t prove
Lintpython3 scripts/lint_mantle.pyInternally consistent; no known trapsThat the engine accepts it
Enginemake trainThe installed engine accepts and builds itThat conversations go well

The checker runs locally without installing Rasa or calling a model, so it can run in a commit hook. The engine check needs a real install and a licence — that’s why it can’t. A green lint is necessary, not sufficient, and the pack’s own docs say so in exactly those words. When you tell a teammate “Juniper is green”, say which green you mean.

Conversation quality needs separate checks. Try the assistant in the Inspector, then use the evaluation harness to inspect recorded actions and model-judged answers. Passing the configuration checker alone cannot establish that the conversation handles the task correctly.

The everyday loop

From here on, building Juniper looks like this:

1. Ask Claude Code for a change
     "Use the mantle-skill-authoring skill to add a care_tips skill"
2. It builds against the playbook, runs the lint, shows you the result
3. You read the diff  ← do not skip this step
4. git commit  → the hook runs the lint one more time
5. Occasionally: make train && make chat to feel the change

Step 3 deserves its sentence in bold: read the diff. The skills make correct-shaped files, the lint catches known traps — but “known traps” is a finite list and your judgment is not. The tooling removes the silent failure modes so your attention is free for the interesting question: is this agent actually behaving well?

The reviewer role — a second pair of eyes, on demand

The pack ships a second role for exactly that judgment work. When a change matters — before merging anything, in a team setting — say:

Review this change as mantle-reviewer.

The reviewer role is deliberately paranoid, and its habits are worth stealing for your own reviews:

  • It re-runs the lint itself rather than trusting a reported green.
  • It re-checks the five silent traps by hand, even though the lint covers them — belt and braces, because these produce zero runtime errors.
  • It gives version bumps extra teeth (does the target wheel actually ship the engine? did a careless find-and-replace produce a nonsense X → X upgrade line in the docs? — yes, that has really shipped).
  • And it names what it did not check. An honest partial review beats a confident-sounding complete one. If it had no licence to train with, it says so instead of implying it verified everything.

That last habit is the deepest lesson in the pack, and it applies to humans too.

Keeping Juniper healthy over time

  • Upgrades: the engine line moves fast. When you bump the pin, follow the upgrade section of the mantle-upgrade-and-debug skill — it includes the check most people skip (does the target version actually contain the engine?) and the one nobody expects (new top-level agent.yml keys appear in dev releases; tool_timeout arrived that way, unannounced).
  • Review release-specific checks: the current compatibility report already records Mantle in a stable release. Revisit engine-version-pin when upgrading so its allowed versions match the runtime you actually tested.
  • New traps: if you hit a silent failure the lint didn’t catch, you’ve found something valuable. The check functions in lint_mantle.py provide examples of how to encode a failure; read the nearest check and consider contributing it back to the community resources repo. That’s how every existing check got there.

Where to go next

  • Tool Scope and Memory Scope — the natural sequel: Juniper’s memory is simple; this builds a bank agent where memory architecture is the product.
  • The catalog itself: RasaHQ/rasa-community-resources — contains voice agents, CRM integrations and patterns to study. Check each project’s README and the compatibility report for its tested scope.

You built an agent, broke it seven ways, caught every break, brought it to life, and know exactly what your tools do and don’t prove. That’s not a beginner’s setup anymore. That’s a workshop. 🛠️