The migration looked like an obvious win on economics. In one EvalShift run, the candidate model was:
- 58.8% cheaper
- 75.2% faster
- 0 failed or truncated calls
Run economics. Same 16 calls on both sides, no failures, and every number a finance reviewer cares about moved the right way.
Then the migration report returned:
FAIL
Not because the model crashed. Not because the API changed. Not because the output stopped parsing.
It changed what the agent actually did.
The verdict card. Five of seven budgets passed; the two that did not are the two that describe behavior.
What failed
I replayed 16 real examples against the source and candidate models. Across the run, 13.6% of evaluated comparisons regressed.
The overall regression-rate budget actually passed.
Two other checks did not:
- Tool-selection divergence hit 25%, against a 10% limit.
- The overall equivalence rate fell to 61.4%, below the required 75%.
The written verdict and its findings. The recommendation is not to migrate until the tool-selection and semantic regressions are fixed.
That distinction matters. Looking only at latency, cost, successful requests, or even a few manually inspected outputs would have made this migration look pretty attractive.
The behavioral diff told a different story.
The failures weren't cosmetic
One example asked for an opinion on working late.
The source model answered the question directly.
The candidate instead issued a search_web call and returned no text.
The diff for that example. Source trace on the left, target trace on the right, and the reason it was flagged at the top.
Other cases had the same general problem in different forms:
- an action was reported as completed even though the corresponding tool was never called;
- a request was routed to a different tool;
- an unnecessary tool call appeared where the source answered directly.
These are not necessarily signs that the candidate model is "bad." They show that changing the model changed the application.
For an agent, the model is part of the control flow.
Aggregate quality can hide this
The evaluator breakdown made the tradeoff clearer.
Routing arguments and routing conformance were broadly equivalent in this run, while tool-selection divergence, semantic similarity, and the pairwise equivalence judge showed regressions.
Overall, by evaluator. Two rows say equivalent, three say regressed, and each comes with its own effect size, confidence interval and confidence label.
A single average score would flatten all of that into one number.
For a migration, I care more about the question:
What changed, on which examples, and is that change acceptable for this application?
This is why I built EvalShift
I kept running into model migrations that were tested roughly like this:
change model → try several prompts → outputs look fine → ship.
That works until the difference is something subtle like an extra tool call, a missing action, or different routing behavior.
EvalShift replays the same suite against the source and target model, compares the behavior, and produces the migration decision and individual diffs before the model string gets changed in production. The CLI is local-first and produces a self-contained HTML report; hosted upload is optional. How that differs from an observability tool or a prompt-eval runner is on the comparison pages.
The interesting result from this run wasn't that the candidate was worse.
It was that "59% cheaper and 75% faster" wasn't enough information to decide whether the migration was safe.





