Route every support ticket against the policy that actually applies
A ticket arrives. It needs to go to the right queue — billing, refunds, account access, a person — with the right priority. Somebody does this by hand today, all day.
Routing is the textbook job for a decision model like Jev from TypeSafe AI: the answer is one of a known list, nobody needs a paragraph, and it happens on every single ticket. TypeSafe names routing and triage among the things Jev is for.
But there is a trap that most routers fall straight into.
The trap: reading only the message
The obvious build sends the ticket text to the model and asks it to classify the message. It works on the easy tickets, which are most of them, and the demo looks wonderful.
Then a refund request arrives from a customer whose contract says refunds go straight to their account manager. The message looks like every other refund request. The router sends it to the refunds queue — confidently, because nothing in the text it was given suggested otherwise.
The model was not wrong about what it saw. It was never shown the thing that mattered.
Regions make this sharper. The same request can fall under different consumer-rights rules, cooling-off periods, or complaint routes depending on where the customer is. A message never says which law applies, and a wrong route there can mean a missed statutory deadline.
The state has to include the rules
So the state you give Jev must contain the rules governing this customer, not only their message. Which rules depends on their plan, their region, and any amendment they signed — a chain from customer to plan, plan to support terms, terms to exception.
That chain is what FastMemory walks, using links your documents already contain, and it returns the route it took.
Build it
1. Build the map from your support policies, plan terms and customer agreements:
cargo install fastmemory # or: pip install fastmemory
fastmemory build ./support-terms
No model call per document, so rebuild the day terms change — ideally in the same step that publishes them, so it is nobody's extra job.
2. Write the routing question. This is the whole design, so spend real time on it. Make it a choice question whose criteria are your queues, each with a sentence saying what belongs there. Then add the two options people forget: account manager, for customers whose terms route them there, and unclear, so a strange ticket has an honest place to go instead of being forced into the nearest bucket with a confident score.
Add a second question for priority, as a score, and write its criteria from your own service terms. What counts as urgent is a contract question, not a mood.
3. Wire it together. A ticket arrives; fastmemory query returns the governing chain; you send Jev the message plus that chain as state, with the routing and priority questions; you store the answer, the probabilities and the route with the ticket.
The request shape, as documented on Cloudflare's model page, is a state and a set of named questions, each with a type (choice, score or yes/no), instructions and criteria. Check the page for current details — Jev is in early access.
The threshold decides whether people trust it
Set a confidence threshold. Above it, the ticket moves automatically. Below it, a person decides — and they do not start from nothing: they see the ticket, the route, and what the model nearly chose.
Set the threshold from your own history, not from instinct. Your closed tickets are a labelled set: every one ended up somewhere, decided by a person. Run a few months of them through, compare, and hold some back that you never tune against. Measure with the policy chain and without it — that difference is what this build is for.
When a customer complains
You can show exactly why a ticket went where it did: this message, these terms, this route, this probability. If the terms were out of date, the route shows it. If the decision was borderline, the probability shows it. Either way you fix a specific thing. Most routing failures turn out to be a document out of date, not a decision gone wrong.
Routing is not replying
Jev routes; it does not write. Pass the same chain to whoever writes the reply — a person, or a language model where one earns its place. The retrieval happened once and everything downstream reuses it.
Honest caveats, and where this is wrong
- There is no official integration; you combine the tools yourself.
- Jev is in early access — run it beside your current router before it replaces anything.
- If every customer is governed by the same terms, the chain adds nothing: route on the message alone.
- If your queues run into the hundreds, you are probably describing a search, not a decision.
Try it
Find a dozen tickets from last month that were routed wrong — the ones that annoyed somebody. For each, write down which document would have routed it correctly. If the answer is usually the customer's own terms, you have found exactly the gap this closes.
FastMemory is free and open source: github.com/FastBuilderAI/memory.