Route a request and reject what you do not handle
A support message, a banking request or an operations question arrives in free text. You need one answer from a fixed list: which team, which domain, which intent. You also need the service to say "not ours" for requests you do not handle, and "not sure" when it cannot tell, so that neither becomes a wrong route.
The shape of a routing decision#
A routing decision in Helixor is a decision head: a small model that reads the request and returns a probability for every option in a fixed set. Nothing outside the set can come back. Three parts make it safe to act on:
- A closed option set.
You list the destinations. The banking example below has five intents,
report_fraud,freeze_account,transfer_funds,dispute_chargeandcheck_balance, and a sixth option,out_of_scope. - Out of scope is an answer.
Requests you do not handle get their own option, trained on real examples of them. "Not ours" is then a decision with a probability, not a low score on the nearest real destination.
- An abstain gate.
The head measures how concentrated its probabilities are. When they are spread across options, it abstains instead of picking one. The threshold is derived from held-out examples the head never trained on, not set by hand.
Your code then has three branches, never a guess: route to the chosen option, close the request as out of scope, or send it to a person.
Run a routing decision today#
The hosted reasoning service answers routing questions for goals it has admitted. Two of them are exactly this task: clinc.banking_oos.v1 routes a banking request to one of five intents or out_of_scope, and ops.domain_selection.v1 routes supply-chain and customer-support requests. The alert-triage goal, sec.alert_triage.v1, routes a security alert to a containment action, or to a person when the head is not sure. Ask the reasoning service, and handle abstentions walks through the request, the three verdicts and the code that acts only on an answer.
For requests that arrive as fields rather than free text, you do not need a model: a rule over the fields routes them, in your process, with the rule named in the result. Design a support-ticket routing pack builds one, and Classify an incoming business request shows where a model's reading ends and the rules take over.
Train a head on your own examples
Send your labelled examples and a held-out split to POST /v1/decide/heads/certify Preview. The service trains the head, calibrates it on the held-out split and admits it as a goal only if it passes its gates; otherwise it refuses and says which gate failed. Ask the reasoning service has the request.
How well compact heads route#
The measured results are in Certified MRL decision heads: accuracy, accuracy when the head answers, coverage and calibration on held-out requests, for each way of reading the text, with the certificate of every admitted head. Read accuracy when it answers together with coverage: a head that answers less often is right more often when it does. Answer only when the decision is reliable explains how to choose that trade.
Choosing how the head reads text#
| Reading | Choose it when |
|---|---|
| Word and character n-grams | Requests reuse the words of your examples, and you want no model at all in the path. It is the fastest row above. |
| Sentence embeddings | People phrase the same request many different ways. A frozen sentence-embedding model turns the text into numbers first; the head itself stays a few thousand parameters. |
| Embedding plus n-grams | You want both: the embedding for paraphrases, and the exact words for product names and codes. |
In every case the head is small enough to inspect, and every head that is admitted has passed its held-out gates first. Certified MRL decision heads has the method and the results.