← All Blogs

Jev won't fix your router

By AI/ML Engineer
Published Read Time: 7 min

Jev is the most interesting model release in a while, and it will not improve your routing. That isn't a knock on Jev. It's a claim about which variable routing actually needs, and about the four attempts it took us to work out that the variable isn't in the text.

Some context first, because it changes how much of this transfers to you. We route agent traffic: coding agents running in a loop, mostly tool calls, file reads, edits and test runs. We've been running a small classifier in front of that for about five months, deciding which model gets each turn.

What Jev gets right

Jev doesn't generate text. You hand it a state blob and a set of typed questions, pick from these options, score against these levels, is this true, and it returns typed values with probabilities attached, all answered in a single pass.

For routing, this sounds like a no-brainer. Load up your favorite models and their capabilities, then let Jev cook. At its core, the task is simple: pick the next model to route to. If you're paying frontier-model prices just to get back the word "urgent," you should be paying attention.

LangChain's launch post names model routing as the flagship Jev use case: classify how hard the task is, send easy things to cheap models and hard things to capable ones. That’s exactly the shape we've been running. So when a model shows up that makes that decision 400x cheaper and 200x faster than a frontier LLM, the question isn't "should we use it." It's "what would it actually change?"

The answer, for us, is: not much. But the reason is more specific than "classifiers don't work," and the specifics are the whole point.

Trials (and errors)

We went looking for difficulty in the text four times. Here is what happened, in order.

  1. Clustering prompts. We embedded nearly a million distinct prompts and swept the number of clusters looking for natural structure in what people ask for. Silhouette came back at roughly 0.03 at every value of k. Near-zero silhouette is weak evidence on its own in high-dimensional space, so this didn't settle anything, but it was the first sign. (It did turn up one thing worth knowing: 34.5% of user-role turns in agent traffic aren't typed by a person at all. They're machine-generated. We were partly clustering our own harness.)

  2. Skill taxonomy with soft demand. Eight capability classes, a soft demand vector over them, score each model as demand dotted with capability minus a price penalty. This is, almost exactly, the design Jev makes trivial to build. It hit our kill gate, the bar a candidate has to clear before we spend more on it. Not because the model underperformed, but because the labels didn't hold up.

  3. Seven-way turn taxonomy. This one worked. Providing info, planning, learning, user mistake, tool call, confirmation, refinement. Band accuracy 0.733 within a conversation and 0.673 across held-out organizations, against a 0.552 majority baseline, with the embedding contributing most of the lift over structural features alone.

That result is real and we shipped on it. It’s also the moment we should have noticed what we were actually measuring. We had set out to predict how hard a turn was. What we had built predicted what kind of turn it was.

  1. LLM-verified complexity labels. So we tested the original question directly. We stopped trusting our own labels and generated better ones: frontier-model consensus, three models labeling independently with a fourth adjudicating, on 148 episodes where we knew the real downstream outcome. The labelers saw the full turn, not just the prompt. We used outcomes to validate the labels rather than as labels themselves, since an outcome alone doesn't separate a hard task from an unlucky one.

A text-only probe on those labels beat the majority-class baseline by +0.014 on skill. On complexity it scored 0.406 against a 0.420 majority baseline. It came in below guessing. And when we went back and audited the difficulty label itself against what actually happened next in the session, it scored AUC 0.502. Coin-flip. The label we had been trying to predict for four attempts was measuring effort, not quality. It was never a model selector.

The distinction we were missing

Put trials 3 and 4 next to each other and the pattern is hard to miss. What kind of turn this is, is recoverable from the text. How hard it is, is not. Those are different variables, they behave differently, and routing needs the second one. Intent classification is genuinely text-learnable, which is why trial 3 worked and why every intent-classification demo you'll see this month will also work. It just isn't the thing that picks the model.

What worked instead

The classifier we shipped predicts the agent's next action per upstream call, and it works because of where the turn sits in the loop.

Cheap Markov and lag features, what happened on the previous calls, roughly double six-way accuracy over the same model with no history: 0.28 to 0.61 within a session, 0.20 to 0.51 across held-out organizations. Adding the prompt embedding on top lifts band-AUC from 0.860 to 0.879 session-grouped, and 0.804 to 0.823 org-grouped, across 100,055 calls and 9 organizations.

It also runs in-process in Go on the hot path, which is worth saying plainly: Jev's speed and cost advantage is measured against frontier LLMs, and our classifier was never a frontier LLM. It was already small, already cheap, already fast. Making it 400x cheaper than a model we weren't using doesn't move anything.

Once you see it, the examples are everywhere. In our traffic, edit calls produce more output than any other action, more than reason, which is the one that sounds like the expensive kind of thinking. You cannot tell that from reading a prompt. You can tell it instantly from knowing that the agent has already read four files and is now writing.

What our feature layout looks like now

The clearest statement of what we believe is the feature vector we actually serve. Alongside the embedding, every routing decision reads:

  • how many tool calls, tool results, and tool errors came before this turn
  • what the current intent is (explore, edit, run a test, and so on)
  • which harness is sending the request (Claude Code, Codex, and so on)
  • a block of belief dynamics from the filter itself: entropy, movement, expected dwell, and the change in turn log-likelihood

That last one needs a word of explanation. We run a filter over the hidden session state, so at every turn the router carries a belief about what phase the session is in, and some confidence in that belief. Those get fed back in as features. The model's own uncertainty about where it is turns out to be informative about what comes next.

Almost none of this is in the prompt. Most of it cannot be, because it's a property of the trajectory rather than the message.

So what does Jev change?

Jev will classify your turn correctly. That’s the part that genuinely works from text. Then it will hand that classification to a router that needs to know something else.

Jev makes answering the question nearly free. It does not tell you whether you're asking the question that picks the model, and it cannot build the state that would let you ask a better one. The advice going around is narrower than "use Jev to route." If you already have a state representation good enough that a classifier over it beats your baseline, Jev will make serving that classifier dramatically cheaper and faster, and you should probably use it. If you're planning to hand it the user's message and a Score question about difficulty, you'll get your majority-class baseline, 200x faster.

The bottleneck was never the classifier. It was instrumentation.

If you want to route well, log:

  • the trajectory, every tool call and result in order, not just the final message
  • tool errors, separately from tool calls
  • loop position, how deep into the session this turn is
  • the harness and the tools available on it
  • downstream outcomes, so you have something real to check your labels against