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

# How routing works

> PRYSM classifies the intent of each prompt and selects the best-value model — in one of three modes.

When you send a request with `model: "auto"`, PRYSM inspects the prompt, classifies
its **intent**, picks a **routing mode**, and selects the model that delivers the best
result for the lowest cost. The decision is returned in the response's
[`prysm.routing`](/api-reference/chat-completions#response) block, so it's never
a black box.

<Tip>
  Want to see the decision without paying for a completion? Call
  [`/route`](/api-reference/route) (or `client.route(...)`) for a dry run that returns
  the chosen model and an estimated cost.
</Tip>

## The three modes

PRYSM routes in one of three modes. It selects a mode automatically from the prompt,
and you can force one per request with `routing_mode`.

<CardGroup cols={3}>
  <Card title="Quality" icon="gem">
    Complex, high-stakes work. Routes to premium/frontier models for maximum accuracy
    and nuance.
  </Card>

  <Card title="Balanced" icon="scale-balanced">
    The default. The best single model for the task at a sensible price.
  </Card>

  <Card title="Agility" icon="bolt">
    Short, simple prompts. Routes to the fastest, cheapest capable model.
  </Card>
</CardGroup>

### How the mode is chosen

| Condition                                                      | Mode         |
| -------------------------------------------------------------- | ------------ |
| An `analysis` or `reasoning` signal **and** more than 20 words | **Quality**  |
| A `simple` signal **or** fewer than 8 words                    | **Agility**  |
| Everything else                                                | **Balanced** |

Override the automatic choice per request:

<CodeGroup>
  ```python Python theme={null}
  client.chat.completions.create(
      model="auto",
      messages=[{"role": "user", "content": "Summarize this report"}],
      extra_body={"routing_mode": "quality"},
  )
  ```

  ```typescript Node theme={null}
  await client.complete("Summarize this report", { mode: "quality" });
  ```

  ```bash cURL theme={null}
  curl https://api.prysm1.com/v1/chat/completions \
    -H "Authorization: Bearer $PRYSM_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "auto",
      "messages": [{ "role": "user", "content": "Summarize this report" }],
      "routing_mode": "quality"
    }'
  ```
</CodeGroup>

## Intent signals

PRYSM detects intent from keywords and language. A prompt can match several signals at
once; routing weighs them together with the word count and mode.

| Signal       | Fires on prompts about…                                    |
| ------------ | ---------------------------------------------------------- |
| `code`       | functions, debugging, languages, APIs, SQL, regex, deploys |
| `write`      | drafting, essays, blogs, emails, copy, editing, tone       |
| `analysis`   | analyze, research, compare, evaluate, strategy, reports    |
| `math`       | calculations, equations, statistics, proofs, calculus      |
| `translate`  | translation between languages                              |
| `realtime`   | today, latest, current, news, prices, live data            |
| `simple`     | quick lookups, definitions, "what is", conversions         |
| `multimodal` | images, photos, diagrams, charts, video                    |
| `reasoning`  | step-by-step logic, philosophy, ethics, debate, proofs     |

PRYSM also detects **Chinese** and **Japanese** text and biases toward models that
specialize in those languages.

<Note>
  The signals PRYSM actually detected for a request are echoed back in
  `prysm.routing.signals_detected`, so you can always see what drove the decision.
</Note>

## Worked examples

These show the default (no BRAIN.md) behavior:

<AccordionGroup>
  <Accordion title="&#x22;capital of France?&#x22; → Agility" icon="bolt">
    Three words and a `simple` signal trigger Agility. PRYSM routes to a fast budget
    model (e.g. `deepseek-v4-flash` at \$0.14/MTok) — paying frontier prices for a fact
    lookup would be waste.
  </Accordion>

  <Accordion title="&#x22;write a Python function to parse CSV&#x22; → Balanced" icon="scale-balanced">
    A `code` signal with a moderate length lands in Balanced. Short code prompts route
    to `deepseek-v4-flash` ("95% cheaper than GPT-5.2"); longer or higher-stakes code
    routes to `claude-sonnet-4.5` for instruction-following and quality.
  </Accordion>

  <Accordion title="&#x22;analyze the trade-offs between microservices and a monolith for a 40-person team, considering …&#x22; → Quality" icon="gem">
    An `analysis` signal with more than 20 words triggers Quality. PRYSM routes to a
    premium reasoning model (e.g. `gpt-5.2`) — accuracy matters more than saving a
    fraction of a cent here.
  </Accordion>
</AccordionGroup>

## Direct model selection

You don't have to use `auto`. Pass any [catalog model ID](/models) to pin a single
request to that model — routing is skipped and the mode is reported as `direct`:

```python theme={null}
client.chat.completions.create(
    model="claude-sonnet-4.5",
    messages=[{"role": "user", "content": "Draft a launch announcement"}],
)
```

If the ID isn't recognized, PRYSM falls back to a safe budget default rather than
erroring.

## Shaping routing with BRAIN.md

Auto-routing is a strong default, but you're in control. A
[`BRAIN.md`](/concepts/brain-md) file lets you pin models to specific signals, lock a
single model, cap per-request cost, and block models entirely — all version-controlled
alongside your code. Guardrails like cost caps and blocks always win over routing
preferences; see [AgentGuard](/concepts/agentguard).
