Skip to content
← All writing

Route cheap models to orchestration, not to the work

4 min readUpdated
.md
Cover illustration for Route cheap models to orchestration, not to the work

Assign models by agent role, not by task. Orchestration and classification are routing problems with tiny output spaces, so a small model handles them as well as a frontier one. Reserving frontier models for actual reasoning cut my cost per completed task by just over half.

The first version of my agent harness used one model for everything. It was the obvious choice: one provider, one set of prompts, one place to tune. It also meant a frontier model was deciding which sub-agent should handle a request, reading a tool manifest, and emitting about forty tokens of JSON. That decision cost the same per token as the reasoning we actually cared about.

Splitting model selection by role rather than by task is where the cost curve bent.

Why is orchestration a routing problem, not a reasoning problem?

An orchestrator agent does a narrow job. It reads a user message, looks at a list of available specialists, and emits a choice. There is very little latent reasoning in that step, and the output space is tiny. Once the tool manifest is well described, a small model is close to indistinguishable from a large one at it.

The mapping lives in one file. Model identifiers are the real ones: Workers AI models are prefixed @cf/, and Anthropic publishes its model identifiers separately.

const ROLE_MODELS = {
  orchestrator: '@cf/meta/llama-3.1-8b-instruct',
  classifier: '@cf/meta/llama-3.1-8b-instruct',
  summariser: 'claude-haiku-4-5',
  reasoner: 'claude-opus-5',
} as const

type Role = keyof typeof ROLE_MODELS

export async function runRole(env: Env, role: Role, prompt: string) {
  const model = ROLE_MODELS[role]

  // Workers AI models run on the binding; frontier models go out over the API.
  if (model.startsWith('@cf/')) {
    return env.AI.run(model, { prompt })
  }

  return callAnthropic(env, model, prompt)
}

The Workers AI binding is declared in the Wrangler config, so no key management is needed for the cheap tier:

[ai]
binding = "AI"

The important property is that the mapping is declarative and lives in one place. When a provider ships something cheaper, you change a string. You do not go hunting for the seven call sites where a model name was inlined.

Measure per role before you optimise

I only found the orchestration overhead because token metering was tagged by role from the start. Aggregate token counts told me I was spending a lot. Per-role counts told me that a third of spend was going to a step whose entire output was a sub-agent name.

RoleShare of callsShare of spend beforeAfter
Orchestrator41%33%4%
Reasoner22%48%61%
Summariser37%19%35%

Spend did not just move around. Total cost per completed task dropped by a bit over half, and the reasoner got a larger share of a smaller bill, which is the direction you want.

Before reaching for a cheaper model, check what you are re-sending. Anthropic’s prompt caching removes a large part of the cost of a stable system prompt, and it applies regardless of which tier you settle on.

Fallback is part of the design, not an afterthought

Cheap models fail more often, and they fail differently. A small orchestrator will occasionally emit a sub-agent name that does not exist. That is fine, as long as the harness treats an invalid choice as a signal rather than an exception:

  1. Validate the choice against the live manifest.
  2. On a miss, retry once at the same tier with the manifest restated.
  3. On a second miss, escalate to the next tier up and record the escalation.

The escalation rate is the number to watch. If it climbs above a few percent for a given role, that role is mis-tiered and the mapping needs to change. If it sits near zero for weeks, the role is probably over-provisioned and you can try a cheaper tier.

The goal is not the cheapest possible model. It is the cheapest model whose failure mode you have already handled.

What this does not solve

Per-role routing does nothing for a badly shaped task. If a single agent turn is doing retrieval, reasoning and formatting at once, no amount of model selection will make it cheap, because the expensive part is the context you keep re-sending. Decomposition comes first. Routing is what you do once the roles are actually distinct.

Sources

Written by Elson Tan, Head of Technology and co-founder at Nedex Group, working on AI harness and agent infrastructure.

AboutRSS
  • 4 min read

    Metering tokens when the bill is the product

    Billing per message is easy and wrong: one user sends a sentence, another uploads a report. Metering the tokens you actually spend is harder, and the hard parts are idempotency, allowance checks and what to do mid-conversation.

  • 4 min read

    Citations that survive the question

    A RAG answer with a source name under it is not a citation. If a teacher cannot open the page and see the sentence, the system has not shown its work. Carrying page numbers through retrieval is most of the job.

  • 4 min read

    Persist once, reference by id, hydrate on demand

    An agent that reads your uploaded file perfectly and then forgets it on the next turn is not a memory bug. It is a context design where file content was only ever turn-transient. The fix also cuts token cost.

Get in touch

Tell me who you are and what you are working on.

Your details are used only to reply to this message.