> ## Documentation Index
> Fetch the complete documentation index at: https://docs.corepillar.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# How routing works

> The complete Auto routing algorithm in ModelHub: how models are tiered by price, how each message is scored, how the tier is chosen, when a second opinion is asked for, and how each answer is graded afterwards.

Every model charges per token, and the most capable ones cost many times what the cheapest ones do. Most workplace questions do not need the expensive model. Auto routing exists to send each message to the cheapest model that can answer it well, and to show its reasoning so you can check it.

This page documents the algorithm exactly as it runs. For the user-facing summary, see [Models and routing](/modelhub/chat/models-and-routing).

```mermaid theme={null}
flowchart LR
  A[Your message] --> B[Optimise, if on]
  B --> C[Score 0 to 1]
  C --> D{Near a boundary?}
  D -- yes --> E[Small model classifies the tier]
  D -- no --> F[Tier from score]
  E --> G[Required tier]
  F --> G
  G --> H{You picked a model?}
  H -- yes --> I[Use your pick]
  H -- no --> J[Cheapest connected model at or above the tier]
  I --> K[Answer]
  J --> K
  K --> L[Grade the fit and record savings]
```

## Step 1: sorting models into tiers

There is no hand-maintained list of "good" and "cheap" models. Each model is placed in a tier when routing runs, in this order:

1. **Large by family name.** Identifiers containing `opus` or `fable`, or `gpt-6-astra`, are Large regardless of price.
2. **Small by family name.** Identifiers containing `haiku`, `-mini`, `-nano`, `-lite` or `-luna` are Small regardless of price.
3. **By blended price.** Otherwise, the blended price is the average of the model's input and output price per million tokens, from CorePillar's model catalogue:

| Tier | Blended price per million tokens |
| - | - |
| **Small** | \$3.50 or less |
| **Mid** | more than $3.50, up to $8.50 |
| **Large** | more than \$8.50 |

A model with a listed price of zero falls back to Mid. A model identifier that is not in the catalogue at all is priced at a default \$3.00 blended and so lands in Small, unless its name matches a family rule.

The boundaries sit in gaps between price clusters, so a small price change does not reshuffle the tiers. The $8.50 line sits between the general-purpose models at up to $8 and a cluster at \$9 (Claude Sonnet 4.5 and 4.6, Kimi K3), so those land in Large.

Examples from the current catalogue of 62 models across 11 providers:

| Model | Blended \$/M | Tier |
| - | - | - |
| GPT-6 Luna | 0.30 | Small |
| GPT-4.1 mini | 1.00 | Small |
| Claude Haiku 4.5 | 3.00 | Small |
| GPT-4.1 | 5.00 | Mid |
| Claude Sonnet 5 | 6.00 | Mid |
| GPT-4o | 6.25 | Mid |
| Claude Sonnet 4.6 | 9.00 | Large |
| GPT-5.6 Sol | 12.00 | Large |
| Claude Opus 5.5 | 12.00 | Large |
| GPT-6 Astra | 30.00 | Large |

If the same model is connected to a project twice (for example after a key rotation), it counts once. The row with an API key attached wins; between equals, the later one wins.

## Step 2: scoring the message

Each message gets a difficulty score from 0 to 1. It is computed from the text that will be sent, so if [Optimise](/modelhub/chat/optimise) is on, the trimmed text is scored.

The score **starts at 0.28**, deliberately below the Small ceiling of 0.42. An unremarkable message therefore routes to Small, and something has to argue for more.

### Signals that raise the score

| Signal | Adds | Label in Details |
| - | - | - |
| Length: `min(0.26, 0.2 × log10(characters ÷ 80))`. Only counted when above 0.02, which starts at about 101 characters; it reaches the 0.26 cap at about 1,600 characters. | up to **+0.26** | "N characters" |
| Contains a fenced code block (three backticks) | **+0.16** | "contains code" |
| More than one question mark: 0.04 per question mark | up to **+0.12** | "N questions" |
| "prove", "derive", "theorem", "complexity analysis", "big-O" | **+0.30** | "formal reasoning" |
| "architect", "design a/an/the system, schema or API", "trade-off(s)" | **+0.24** | "design work" |
| "debug", "root cause", "why is/does/did … fail/break/crash/hang" | **+0.20** | "debugging" |
| "refactor", "migrate", "port", "rewrite" | **+0.18** | "code transformation" |
| "step by step", "walk me through", "explain how", "in detail" | **+0.14** | "extended explanation" |
| "compare", "versus", "vs", "pros and cons", "evaluate" | **+0.12** | "comparison" |
| "plan", "strategy", "roadmap", "approach for" | **+0.12** | "planning" |
| "optimise/optimize", "improve performance", "speed up" | **+0.12** | "optimisation" |
| The conversation already has 6 or more earlier exchanges | **+0.08** | "N-turn thread" |

**Difficulty phrases count at most twice.** They are checked in the order listed. The first one that matches adds its full weight, the second adds **half** its weight, and any further matches are ignored. "Design a schema and explain the trade-offs, step by step" is harder than "design a schema", but not three times harder.

### Signals that lower the score

| Signal | Subtracts | Label |
| - | - | - |
| Opens with "hi", "hey", "hello", "thanks", "thank you", "ok", "okay", "got it" or "cool" | **−0.30** | "greeting" |
| "what is", "who is", "when is/was", "define", "meaning of", "stands for" | **−0.16** | "factual lookup" |
| "translate", "rephrase", "reword", "shorten", "summarise/summarize briefly" | **−0.12** | "text transformation" |
| "spell", "capital of", "convert", "how many" | **−0.12** | "simple recall" |

Only the **first** of these that matches counts, checked in the order listed.

The final score is clamped to between 0 and 1.

## Step 3: turning the score into a tier

| Score | Required tier |
| - | - |
| 0 to 0.42 | Small |
| above 0.42, up to 0.68 | Mid |
| above 0.68 | Large |

Measured examples (first message of a conversation, Optimise off):

| Message | Signals | Score | Tier |
| - | - | - | - |
| "hey" | greeting −0.30 | 0.00 | Small |
| "What is the capital of France?" | factual lookup −0.16 | 0.12 | Small |
| "Summarise this in three bullets" | none | 0.28 | Small |
| "Compare Postgres and MySQL for our use case" | comparison +0.12 | 0.40 | Small, then second opinion |
| "Debug why checkout hangs under load, step by step" | debugging +0.20, extended explanation +0.07 | 0.55 | Mid |
| "Prove this sort is O(n log n) and derive the recurrence" | formal reasoning +0.30 | 0.58 | Mid, then second opinion |
| "Design a schema for a multi-tenant billing system and explain the trade-offs, step by step" | design work +0.24, extended explanation +0.07 | 0.59 | Mid, then second opinion |

## Step 4: the second opinion

Rules are confident in the middle of a range and guess at the edges. When a score lands **within 0.1 of a boundary** (roughly 0.32 to 0.52, or 0.58 to 0.78), a small, fast model is asked to classify the message instead.

| Detail | Value |
| - | - |
| Model | Claude Haiku 4.5, on CorePillar's platform key (not your organization's keys) |
| What it sees | The **masked** message, never the raw text, up to 4,000 characters |
| Instruction | Choose the smallest tier that can answer correctly. Small: recall, definitions, formatting, translation, short rewrites, greetings. Mid: ordinary code, explanations, summarising a document, routine analysis. Large: multi-step reasoning, system design, subtle debugging, long synthesis, anything where a confident wrong answer would be costly. |
| Effect | Its answer replaces the score-based tier. The Details reason then reads "classified as …" instead of "scored as …". |
| Time limit | 4 seconds |
| Failure | If it is slow, fails or returns something unparseable, the score-based tier stands and the message goes through. |

It runs at the same time as the AI part of privacy screening, which every message waits for anyway, so it adds no time to the answer.

## Step 5: choosing the model

* **If you picked a model**, it is used. Routing never overrides an explicit choice. The reason reads "You picked this model".
* **On Auto**, ModelHub takes every connected model whose tier is at or above the required tier and picks the one with the lowest blended price.
* **If none reaches the required tier**, it uses the most capable connected model, so a project with only small models still answers.

The reason shown in Details is one of "scored as a simple turn", "scored as moderately complex", "scored as needing deep reasoning", or the same with "classified" when the second opinion decided. It describes the tier of the model that ran.

## Step 6: grading the decision afterwards

When the answer is complete, ModelHub checks whether the choice was right, using something the router could not know in advance: **how much the model actually wrote.** This is arithmetic, not another AI call; paying a second model to grade the first would double the cost the feature exists to reduce.

The grade compares the tier the **score** called for (the second opinion is not used here) with the tier of the model that ran.

| Situation | Verdict | Confidence | Note |
| - | - | - | - |
| Ran a bigger tier than needed, and wrote 180 output tokens or fewer | **Overpowered** (shown as **Overkill**) | 0.60 + 0.15 per tier too big + 0.15, max 0.95 | "short answer, large model" |
| Ran a bigger tier than needed, wrote between 181 and 699 tokens | **Overpowered** | 0.60 + 0.15 per tier too big, max 0.95 | "a cheaper tier would cover this" |
| Ran a bigger tier than needed, but wrote 700 tokens or more | **Right sized**: the length justified it | 0.65 | "matched to the task" |
| Ran a smaller tier than needed | **Underpowered** | 0.60 + 0.20 per tier short, max 0.90 | "this turn wanted more capability" |
| Ran the tier that was needed | **Right sized** | 0.70 | "matched to the task" |

For an Overpowered answer, ModelHub names the cheapest connected model at the needed tier and prices **this exact answer** on it, using the real token counts. That becomes the **Use** suggestion and the saving shown on the answer card. For an Underpowered answer, the card suggests the cheapest connected model that reaches the needed tier, or failing that the strongest model above the one that ran.

## Savings

For each answer where Auto chose the model, ModelHub records:

`saved = cost of this answer on the most expensive connected model − what it actually cost`

using the provider's real token counts, floored at zero. Answers on a model you picked yourself are credited with no saving. These add up to **Saved by auto-routing** on the [AI Usage](/modelhub/usage) page.

## Guarantees

* **Your explicit choice always wins.** Routing only acts on Auto.
* **Nothing is hidden.** Every answer shows which model ran, what it cost, the verdict, and the signals behind the score.
* **Routing never blocks a message.** The scoring is local arithmetic; the second opinion has a short timeout and falls back silently.
* **A dead key is not a dead end.** If the chosen model's API key is revoked or rejected by the provider, the organization's other keys for the same provider are tried before the message fails. This only happens before the first word arrives; a key is never swapped mid-answer.

## Limits worth knowing

* The score reads the shape of the message (length, code, keywords), not its meaning. A short message that is genuinely hard can score low; pick a Large model yourself when you know.
* Keyword matches are in English.
* Tiers come from price, which tracks capability closely but not perfectly.
* With only one model connected, every message goes to it and there is nothing to save.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.