cd /news/ai-agents/choosing-a-model-on-the-pareto-front… · home topics ai-agents article
[ARTICLE · art-135367] src=philippdubach.com ↗ pub= topic=ai-agents verified=true sentiment=· neutral

Choosing a Model on the Pareto Frontier with Jev

Philipp Dubach released pi-jev-router, an open-source extension for the pi coding agent that uses TypeSafe's Jev System One model to classify each task and route it to a model on the Pareto frontier based on quality, cost, and latency. The extension defaults to shadow mode, which records a recommendation without switching models, and applies routing only at task boundaries in automatic mode. The selector filters candidates by tool support, input modalities, expiry, and context capacity with 30 percent headroom, and blends Artificial Analysis and EQ-Bench Creative Writing v3 Elo priors with recorded verifier pass rates using the weight w_n = n/(n+5).

by read8 min views1 publishedSep 19, 2026

I have been using pi as a coding agent with one model set as the default. My earlier experiment with reasoning levels examined how much performance, cost, and latency move when one setting changes. pi-jev-router makes the model itself a task-level decision. Jev classifies the work; a local selector estimates the available models’ quality, cost, and latency, then chooses from their Pareto frontier.

Jev is TypeSafe’s first System One model. Its outputs are structured decisions: Choice selects from a fixed list, Score evaluates an ordered rubric, and Noul returns a probability for a yes-or-no question. It does not generate the code or prose that completes the task.

The extension sends Jev a task envelope rather than the full conversation. In one request, it asks for the work category, reasoning difficulty, consequences of failure, whether the brief is sufficient, and whether the work should be decomposed. The local policy then maps the task to planning, code, or writing, with an explicit role taking precedence when one is supplied. The current selector uses work kind and risk; it records complexity without using it to adjust the trade-off.

The simplest policy assigns a fixed route to each kind of work. The project keeps such a profile for comparison: Sonnet for planning, OpenRouter’s Pareto Code Router for code, and GPT-5.4-mini for writing.

OpenRouter’s Pareto Code Router already provides a coding-specific route. I also wanted a policy for architecture and prose, where a coding benchmark is a poor basis for selection. Even within code, a benchmark score does not tell me whether a model will pass the tests in my repository.

Routing happens before a task starts. The extension defaults to shadow mode, which records a recommendation without switching models; automatic mode applies it at the task boundary. It leaves queued steering and follow-up messages alone. This gives me a way to inspect decisions before allowing them to change the session.

The selector first removes models that cannot serve the task. It checks tool support, input modalities, expiry, and context capacity, with 30 percent headroom over the estimate. Planning and code normally require reasoning support. For tasks classified as higher risk, it initially requires three recorded runs of that work kind. These last two filters can be relaxed if they leave no candidates, and the recommendation records that relaxation. The experience requirement is therefore a routing preference, not a hard safety guarantee.

Each remaining model receives a quality score $q$, estimated task cost $c$, and estimated latency $t$. The quality prior comes from Artificial Analysis for planning and code, and EQ-Bench Creative Writing v3 Elo for writing. Scores are min–max normalised within the catalogue for each kind of work. A model without a benchmark entry receives the 60th-percentile prior, an optimistic convention that lets unfamiliar models compete for low-risk work.

Recorded results gradually replace that prior. For a model with $s$ verifier passes in $n$ runs of the relevant work kind, the implementation uses

$$ w_n = \frac{n}{n+5}, \qquad q = w_n\frac{s+1}{n+2} + (1-w_n)q_{\mathrm{prior}}. $$

The smoothed pass rate is the posterior mean under a uniform Beta prior if the outcomes are treated as Bernoulli observations. The outer blend is a heuristic. It combines a relative benchmark score with a verifier pass rate, two quantities that happen to lie between zero and one but have different meanings. I would not interpret $q=0.8$ as an 80 percent chance of completing the next task correctly. EQ-Bench is also an imperfect prior for the technical writing I actually want. Cost starts with catalogue token prices, the estimated input size, and an allowance of four turns with 1,500 output tokens each. It blends toward observed mean task cost using the same weight $w_n$. Latency blends observed means with a shared prior for the work kind. The weighted fallback only applies a latency penalty once observations exist for at least two models.

A model is dominated when another feasible model has at least as much estimated quality, no greater cost, and no greater latency, with a strict improvement on at least one axis. Removing these models leaves the Pareto frontier. This is an exact comparison of the supplied estimates.

I wrote my thesis on convex portfolio optimisation, so my first instinct was to formulate the trade-off in CVXPY. The analogy only goes so far. A portfolio allocates continuous weights across assets. This router sends each task to one model, and the candidate set is small enough to enumerate directly.

Randomising assignments across many comparable tasks would make expected quality and cost convex combinations of the model-level values. A budget-constrained allocation could then be a continuous optimisation problem. I wanted one reproducible choice for each task, so I compared selection rules on the finite frontier.

The default is a knee heuristic. For the positive-cost frontier, the implementation transforms the coordinates to

$$ x_i = \frac{\log(c_i/c_{\min})}{\log(c_{\max}/c_{\min})}, \qquad y_i = \frac{q_i-q_{\min}}{q_{\max}-q_{\min}}. $$ It draws a chord between the cheapest and most expensive members and chooses the point with the greatest perpendicular distance from that chord. On a diminishing-returns curve, this tends to select the bend before further quality gains become expensive.

This rule needs no user-supplied trade-off weights. It still contains choices. Log cost treats proportional price increases equally; the quality prior determines what counts as an improvement; filtering candidates changes the frontier and its endpoints. A knee calculated in raw dollars can differ from one calculated in log dollars.

Nor is distance from a chord the same as maximum differential curvature. There is no smooth fitted curve here. The code selects the largest absolute distance, so it does not distinguish a favourable bend from one on the opposite side of the chord. Latency participates in the dominance filter but is absent from this two-dimensional knee calculation. A model that survives because it is fast gets no further credit for speed at that stage.

When there are fewer than three frontier members, no spread, or a collinear frontier, the selector falls back to a weighted value function:

$$ U_i = q_i - \lambda\log_2(c_i/c_{\min}) - \mu\log_2(t_i/t_{\min}). $$ Here, $\lambda$ is the quality-score penalty for doubling cost, and $\mu$ for latency. The latency term is disabled when there is no usable signal. These weights are fixed by work kind. The dynamic profile therefore has a weight-free primary rule and a weighted fallback, as well as fallback models when catalogue selection fails.

An epsilon-constraint is easy to interpret: choose the cheapest model whose quality score exceeds a chosen floor. If that score were a calibrated success probability, the floor could express a reliability requirement. With the current blended score, it is only a threshold on a proxy.

The explorer below compares that rule with the knee, weighted sums, Chebyshev scalarisations, compromise programming, and TOPSIS. It uses a fixed representative snapshot, not a live catalogue lookup. Select Knee point to see the router’s primary rule. The quality-bar control for epsilon-constraint is relative to the displayed frontier’s quality range. Every candidate within a work kind has the same latency estimate in this snapshot, so it cannot illustrate measured speed differences.

A weighted sum can select only supported efficient points in the coordinates being scalarised. Chebyshev methods can also recover unsupported Pareto points with suitable weights. That distinction matters when a frontier is non-convex, but several methods returning the same model at one setting tells us little about its global shape. Some agreement is built into the explorer: its utopian-reference achievement scalarising function reduces to the augmented Chebyshev expression.

For this implementation, I kept the knee as the default because it avoids tuning a quality floor or exchange-rate weights for each work kind. I would use an explicit constraint if I had a defensible minimum reliability requirement. Neither choice repairs a bad quality estimate. I then built limited evaluations that contain three TypeScript tasks: an LRU cache with TTL, a SemVer sorting fix, and a concurrency-limited retry queue. The other two ask for a distributed rate-limiter design and an incident postmortem. Each strategy runs in separate workspaces and sessions, followed by an external verifier. Code runs unit tests; planning and writing receive much shallower checks for required concepts, structure, and style.

The dynamic profile reduced reported generation cost by 65 percent. Its three code tasks went to z-ai/glm-5.3-flash at about $0.0035 each, against $0.088 on fixed Sonnet: roughly one twenty-fifth of the cost for the same three passing verifiers. These task-specific selections differ from the representative frontier above because the inputs and feasible sets differ.

The postmortem went to openai/gpt-5.4-mini for $0.0129, against $0.1343 on Sonnet. Planning used the weighted fallback and selected Sonnet again, costing $0.1759. That one task accounted for about 88 percent of the routed bill. Average worker time was 47.2 seconds per task, against 45.0 for fixed Sonnet. The routed code tasks were slower; the much faster writing task offset most of that difference.

There is a statistical limitation beyond sample size. The selector reads previous results from the same evaluation directory. Separate workspaces prevent conversational carry-over, but earlier runs on these tasks inform later selections. This is a development evaluation, not a held-out estimate of routing performance. A planning document can also pass a keyword check while proposing a poor design, and a postmortem can obey sentence-length rules without being good prose.

The source, selector tests, and evaluation harness are available on GitHub. In pi, /router shadow records recommendations without applying them, and /router frontier shows the candidates behind the latest decision.

── more in #ai-agents 4 stories · sorted by recency
── more on @philipp dubach 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/choosing-a-model-on-…] indexed:0 read:8min 2026-09-19 ·