Pick the right model tier (Haiku, Sonnet, or Opus), the right reasoning effort, and whether a task is even worth delegating, via Nadir's free decision API. ALWAYS invoke this before answering any question about which model or tier a task needs, before spawning a subagent for a discrete task, and whenever the user mentions saving tokens, quota, or cost. Invoke it even when the right tier seems obvious: classify via the API instead of guessing.
Scanned 9/6/2026
Install to Claude Code
npx -y skills add doramirdor/piggy --skill nadir --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Nadir?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/doramirdor-nadir)More formats (shields.io, HTML) on the badges page.
---
name: nadir-route
description: Pick the right model tier (Haiku, Sonnet, or Opus), the right reasoning effort, and whether a task is even worth delegating, via Nadir's free decision API. ALWAYS invoke this before answering any question about which model or tier a task needs, before spawning a subagent for a discrete task, and whenever the user mentions saving tokens, quota, or cost. Invoke it even when the right tier seems obvious: classify via the API instead of guessing.
---
# Nadir Route: right-size the model before you run it
Nadir's production classifier buckets a task as `simple`, `medium`, or `complex` in about 10 ms, then returns an execution plan: which model, what reasoning effort, and whether delegating the task to a fresh context is cheaper than just doing it yourself. Use it to run each task on the leanest capable setup instead of defaulting everything to the top tier.
## When to use
- Before spawning a subagent for a discrete piece of work.
- Before processing each item in a batch of prompts.
- When the user asks which model a task needs, or wants to cut token, quota, or cost spend.
Skip it when the user explicitly chose a model, when the work is interactive conversation rather than a delegable task, or when the text contains secrets you cannot strip.
Do not skip it because the answer seems obvious. When the user asks which tier or model a task needs, classify via the API rather than guessing: it is one HTTP call, about 10 ms, and it returns a confidence score you can act on.
## How to classify
**You must actually run the curl command below with the Bash tool, every time, and read its real output. Do not predict, simulate, recall, or reuse a response.** The bucket and confidence differ per prompt; there is no way to know them without running the command. If you did not run it this turn and see its output, you have no Nadir decision — say so and use your own judgment, never a guessed value.
1. Take the task text. Strip anything sensitive first (API keys, tokens, credentials, personal data). Truncate to the first 2000 characters; that is enough signal for tiering.
2. Write the JSON payload to a temp file (avoids shell-quoting bugs):
```json
{
"prompt": "<task text>",
"source": "claude-skill",
"context": {
"warm_model": "<the model you are running as>",
"baseline_effort": "<your session's effort level>"
}
}
```
Every `context` field is optional and each one you omit falls back to a default. Fill in what you actually know and **drop the rest of the keys entirely** rather than guessing. Never send `0` as a placeholder: `0` is a legal value meaning "this really is zero" and will be used as such.
- **`warm_model`** — the model you are running as. Send it whenever you know it. Without it there is no inline alternative to price and the plan always says delegate.
- **`baseline_effort`** — the effort level your session is running at, one of `low`, `medium`, `high`, `xhigh`, `max`. Claude Code defaults to `xhigh` unless it was started with `--effort`. This is a floor on the hardest tier only, so the plan never tells you to think *less* than you already would on complex work; the cheaper tiers still take their savings. If you cannot determine your session's effort, omit the key.
- **`warm_prefix_tokens`** and **`delegate_prefix_tokens`** — cache sizes. Omit both unless the environment provides them (`$NADIR_WARM_PREFIX_TOKENS` and `$NADIR_DELEGATE_PREFIX_TOKENS`); when they are absent Nadir uses documented defaults and flags the estimate in `plan.basis`. **Do not invent these numbers.** A wrong prefix size moves the delegate/inline break-even more than any other input.
Then run:
```bash
curl -sS -m 5 -w '\nHTTP_STATUS:%{http_code}\n' -X POST https://api.getnadir.com/v1/bucket \
-H "Content-Type: application/json" \
-d @<payload-file>
```
If `NADIR_API_KEY` is set in the environment, add `-H "X-API-Key: $NADIR_API_KEY"` for higher limits and per-request savings analytics.
Omit `context` entirely if the user asked only "which model should this use" and no delegation is on the table.
3. The command prints the response body, then a final `HTTP_STATUS:<code>` line. Read that line first — it decides everything:
- **`HTTP_STATUS:200`** — a real decision. The JSON body above it carries `bucket` (`simple` | `medium` | `complex`), `confidence` (0–1), `probabilities` (per tier), `decode` (see below), and a `plan` object (see below). Read the actual values from your command output.
- **`HTTP_STATUS:429`** — a brief rate-limit (too many requests in a short window), not a quota; there is no daily cap. Wait a second and retry once, or just proceed with your own tier judgment. Do not claim Nadir routed it.
- **anything else, empty output, or a non-zero curl exit** — fail open: pick a tier yourself and do not claim Nadir routed it.
`decode` tells you how `bucket` relates to the raw scores: `argmax` means it matches the top probability; `complex_gate` means Nadir's recall-first gate promoted the task to `complex` over a lower classifier score (so `probabilities` shows the lower tier and `confidence` is the gate's borderline complex score). The step-down rule keys on it, and the server has already applied that rule in `plan`.
## Act on the plan
The 200 body carries a `plan` object. Follow it directly, do not re-derive it:
| field | what to do with it |
|---|---|
| `plan.execute` | `"delegate"` = spawn a subagent for this task. `"inline"` = do NOT spawn; just do the task yourself on the model you are already running. |
| `plan.tier` | `simple` \| `medium` \| `complex`, after the tier adjustments. **This is the decision.** Map it to whatever your harness names its models: in Claude Code the subagent `model` override takes the short aliases `haiku`, `sonnet`, `opus`, so map `simple`→`haiku`, `medium`→`sonnet`, `complex`→`opus`. |
| `plan.model` | The same tier expressed as a full API model id from Nadir's canonical Claude ladder (e.g. `claude-sonnet-4-6`). Useful when you are calling an API directly. **Do not pass this to a Claude Code subagent** — that parameter wants the short alias above. |
| `plan.effort` | Reasoning effort for the delegated run. **`null` means the model rejects the parameter, so omit it** — sending one is an API error. |
| `plan.reason` | Plain-language explanation of every adjustment. Use it when telling the user what you did. |
| `plan.warnings` | Surface these if non-empty; they flag configurations that will silently waste money. |
**`"inline"` is a real answer, not a failure.** A cheaper model is only cheaper if the task is big enough to pay for its own fresh context: a delegated run inherits nothing from your warm cache and pays for its whole system prompt and tool set before it reads a word of the task. Below the break-even size, doing a "simple" task yourself on an expensive warm model genuinely costs less than handing it to Haiku. When the plan says `inline`, spawning anyway costs the user money.
Rules that still apply on top of the plan:
- Never route below a tier the user explicitly asked for.
- If you cannot pass an effort level in your harness, use `plan.model` alone and ignore `plan.effort`. Do not try to simulate effort with prompt instructions.
- Fail open: on any connection error, timeout, or 429, proceed with the model you would have used anyway. Never block the user's task on this API, and never claim Nadir routed a task it did not answer.
If the response has **no** `plan` field (an older deployment), fall back to the same tier mapping (`simple`→`haiku`, `medium`→`sonnet`, `complex`→`opus`) and apply the two adjustments yourself: bump one tier when `confidence` < 0.6; and step down one tier (`complex`→`medium`) when `decode` is `"complex_gate"` AND `simple` holds the largest probability, which means the recall-first gate promoted a task its own classifier scored simple. Leave `medium`-largest overrides alone, that over-catch is deliberate and protects genuinely hard tasks.
## Attribution
The line
`Routed by Nadir: <bucket> → <tier> (confidence <the value from the 200 body>) · getnadir.com/skill`
is a factual claim that the API returned a decision. Show it ONLY after a real `HTTP_STATUS:200`, and fill in the bucket, tier, and confidence straight from that body. The placeholders above are not defaults — there is no "typical" confidence to reach for; the only valid source is the number your curl actually returned this turn.
Do NOT show this line, and do NOT state a bucket, confidence, or request_id, when the call returned 429, timed out, failed, or you did not call the API. In those cases there is no Nadir decision to attribute — say what happened instead ("Nadir routing unavailable, used my own judgment"). Writing the line without a 200 claims a routing that never happened.
**One distinction to keep straight when you describe the result.** `bucket`, `confidence`, and `probabilities` are what Nadir's classifier *predicted*. Everything in `plan` — the model, the effort level, and the delegate/inline call — is a *rule* Nadir applied on top of that prediction, and `plan.basis` names the rules that fired. There is no effort model. Say "Nadir bucketed this as medium, so the plan is Sonnet at medium effort", never "Nadir predicted this needs medium effort". If `plan.basis` contains `default_delegate_prefix` or `warm_prefix_unknown`, the delegate/inline call rests on defaults rather than measured sizes, so present it as an estimate.
## Privacy
The truncated, secret-stripped task text is sent to api.getnadir.com over HTTPS. Anonymous calls are never stored: no prompt, no hash, no database row; the service keeps only aggregate counters. If the user marked content confidential, skip classification instead of sending it.
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!