Intent routing
Before it does any work, Promptly decides what kind of question it just received and sends it down the right path. A greeting shouldn't trigger a catalog search. A returns-policy question shouldn't wake up the product tools. Intent routing is what keeps the assistant fast and cheap without making it dumber.
There is nothing to configure here — it runs on every message. This page explains what it's doing, so that when an answer surprises you, you know which path produced it.
🖼️ [Image] — A diagram of one message branching into the product, knowledge, mixed, and small-talk paths.
The five verdicts
| Intent | Typical question | What runs |
|---|---|---|
| Product | "show me red sneakers under €80" | Planning with catalog tools; knowledge search is dropped. |
| Knowledge | "what's your return policy?" | Answered from your knowledge base; product tools are dropped. |
| Mixed | "do you have waterproof boots, and what's the return window?" | Planning with everything available. |
| Unknown | "hi", "thanks", "what's the weather", "something nice for a gift?" | A short direct reply — no catalog search, no knowledge lookup. |
| Escalation | "get me a person" | Handed to your escalation configuration before any planning. |
That's the complete list. There's no separate "greeting" or "off-topic" verdict — everything that isn't clearly a product question, a knowledge question, or a request for a human lands in Unknown, which is a busier category than its name suggests.
What Unknown actually does
Unknown gets a single short reply from the model, written to one of three modes:
- Small talk — greetings, thanks, acknowledgements. Two sentences maximum, at most one emoji.
- Off-topic — maths, weather, jokes, recipes. Answered briefly and warmly, then turned back toward what you sell, with a light touch rather than a refusal.
- Vague but real — "something nice for a gift", "I need help". Instead of the deadening "What exactly are you looking for?", the bot leads with a reassurance, then offers two or three concrete options drawn from your actual catalog — plus an explicit "doesn't matter / surprise me" escape hatch, so a visitor who genuinely has no preference isn't trapped in a questionnaire.
There's also a safety mode: a visitor in medical, legal, or emergency distress gets acknowledgement and a pointer to real professional help, with no jokes and no emoji.
Clarification is capped at one round per conversation — the bot asks once, then works with whatever it gets. It won't ask when a concrete product type is already named, and it will never offer an option that isn't in your catalog.
Why routing matters
- Faster. A pure policy question skips product tools entirely. A greeting touches no database at all.
- Cheaper. Fewer steps means fewer tokens, and tokens are billed to your own provider account. See Languages & cost tracking.
- More accurate. Each path is tuned for its job, so product queries get filtering and sorting logic while informational queries get your documentation.
When it's unsure, it widens
Classification comes back with a confidence score, and anything below 0.7 is promoted to Mixed rather than acted on. Same for any failure — a timeout, an unparseable answer, an error of any kind all resolve to Mixed. The bias is deliberate: the broad path is slower and costs a little more, but it never skips the tool that would have found the answer.
This is also why you'll occasionally see a knowledge lookup on what looks like a pure product question. That's the safety net, not a bug.
Caching
Routing decisions are cached twice over, which is why the second person to ask the same thing gets an answer noticeably faster:
- Exact match — the same question, normalised for case, spacing, and punctuation.
- Semantic match — a differently worded question that means the same thing, matched by meaning at 92% similarity or better. "What's your refund policy?" hits the cache entry left by "how do returns work".
How long a verdict is trusted depends on how stable that kind of question is:
| Intent | Cached for |
|---|---|
| Knowledge | 24 hours |
| Product | 1 hour |
| Mixed | 30 minutes |
| Unknown / Escalation | 5 minutes |
Any low-confidence verdict is kept for 5 minutes regardless of category, so a shaky guess never sticks around. Caches are per workspace — your traffic never influences anyone else's routing. See Data isolation & storage modes.
Escalation is checked first
Before routing runs at all, Promptly evaluates your escalation triggers on the raw message. Three kinds fire:
- Keywords you've configured, matched forgivingly — accents are ignored and word endings tolerated, so "reklamacija" also catches "reklamaciju".
- A repeated question — the same message asked N times over (three by default) means the answers aren't landing.
- Low classifier confidence — the bot genuinely didn't understand, so it offers a human instead of guessing.
A trigger set to automatic hands the conversation over immediately, ahead of every path above. A trigger set to offer lets the bot answer and appends the offer of a human — and won't repeat that offer if it's already been made in the last few turns. Configure all of this in Escalation settings.
Frustration and tone are not used as a trigger. Nothing in the pipeline scores sentiment to escalate on, so if you want angry customers routed to a person, do it with keywords.
Which model does the classifying
The classifier runs on the Planner model from your API key — the same slot the planning step uses, not a separate model you configure. That's one more reason to point Planner at something fast: it's on the critical path of every single message. See Model roles.
What routing needs
Intent routing is part of the planning pipeline in the Chat module, alongside multi-step reasoning. When the planner isn't active for a workspace, the assistant still answers every message — it just uses the simpler single-pass flow, with no separate classification step, no small-talk shortcut, and no per-intent tool pruning.
🎬 [Video] — The same bot handling a greeting, a policy question, and a product search, each resolving down a different path.