FifeRouter

1 September 2026 · routing classification

The classification ladder — explicit, cache, embedding, LLM, default

Five rungs, cheapest first, and each one exists because the rung below it is not always available. Most requests never reach the third.

Classifying a request costs something, and it happens before any useful work. That makes it the one place in a router where cleverness is most tempting and least affordable.

So it is a ladder. Each rung is tried in order and the first that answers with enough confidence wins.

explicit    the caller already told us
cache       this conversation was classified last turn
embedding   compare against the concept exemplars
llm         ask a model, for the low-confidence tail only
default     and never an error

Rung 1 — explicit

A header. x-fife-concept: moneypath.verify.

Free, exact, and the rung people forget to build. Callers who know what they are sending should be able to say so, and a router that insists on inferring something the caller already knows is doing work to arrive at an answer it was handed.

It also gives integrators an escape hatch when the classifier gets something wrong, which matters more than it sounds: the alternative is a support conversation about embeddings.

Rung 2 — the conversation cache

A conversation is usually about one thing. Classifying every turn of a twenty-turn exchange is nineteen redundant classifications, and worse, it lets the concept drift mid-conversation — turn 12 gets classified slightly differently and suddenly a different policy row applies.

So a conversation is classified once and the result is remembered. The cache key is the conversation, not the prompt: two different questions in the same thread are the same work.

Rung 3 — embedding

Compare the request against the exemplar sentences in each concept file. Cheap, local, no network call, and good enough for most traffic — which is the actual claim being made, not that it is the best available classifier.

The exemplars are why authored concepts pay off here. Adding a route means adding three or four sentences, and the classifier picks it up with no retraining, no corpus and no deployment beyond the config file.

Rung 4 — the LLM

For the low-confidence tail only. If the embedding comparison does not clear the confidence floor, ask a model.

This rung is the one that has to be defended, because it is the obvious place to start if you are not counting. A model call per request makes classification cost the same order as the work being classified, which means the router has made the system more expensive in exchange for making it cheaper.

CON-routing-overhead-budget puts the whole of routing under 5% of end-to-end p95. Nothing on the request path may make a network call the ladder can avoid, and this rung earns its place only by being rare.

Rung 5 — the default

No error. Ever. An unclassifiable request goes to the default concept, with that concept's constraints applying in full — which is a longer argument, made separately, because "fail open" has a wrong reading that is one word away from the right one.

Why a ladder and not a classifier

The alternative design is one good classifier tuned for accuracy. It would probably classify better than this does.

What it would not do is degrade in a known direction. Each rung here exists because the one below it is not always available: the header is absent, the conversation is new, the embedding is ambiguous, the model call fails or is too slow. A ladder makes each of those a step down rather than a failure, and each step down is visible in the decision record:

"classifier_rung": "embedding",
"confidence": 1.0,
"escalated": false,
"fell_open": false,
"classify_ms": 4

Four milliseconds, on the third rung, without escalating. You can read that off a request and know exactly how the answer was reached — and if the escalation rate starts climbing, you know your exemplars have stopped covering your traffic before anybody complains.


← All posts