STOP WASTING PAID TOKENS. START POOLING ACCOUNTS TODAY. [ GET YOUR VAULT ]
← BACK TO BLOG

Your agents shouldn't know which model they're using

Martin Shein
Mar 25, 2026 · 4 min read
Copied!
Your agents shouldn't know which model they're using

Every agent I run used to name its own model. llama-3.1-8b-instant here, a Codex id there, a Mistral string in the enricher. It reads fine in a diff and it is a slow-motion outage: the day a provider retires or throttles that id, every agent that named it stops at the same moment, and the fix is a deploy per service.

A chalk drawing: a pin through a card labelled PINNED NAME, a severed line, and a gold dot falling out from under a bracket labelled ALL STOP.

That is the actual cost of naming a model. Not the price per token, the coupling. You have written a provider's product decisions into your own source.

Ask for the job instead

So SpiderGate takes a different value in the model field. Instead of a vendor's model id, you send the name of the work:

{ "model": "spideriq/coding", "messages": [...] }

spideriq/coding, spideriq/extraction, agent/chat. The caller declares what the request is for and the gateway decides what serves it. That is the whole primitive, and everything else here is a consequence of it.

A chalk drawing: an envelope labelled THE JOB, an arrow, and a rounded box labelled THE CHOICE holding a single gold dot.

It is an ordinary indirection, the same trick as a DNS name in front of an IP, and it buys the same thing: the right to change what is behind the name without telling everyone who uses it.

An alias is a chain, not a model

The part that makes it hold up under load is that an alias does not resolve to one model. It resolves to a ranked list.

There are 32 aliases today, in three families, and between them they carry 91 ordered slots. That averages 2.8 models deep per alias. When the first choice rate limits, errors or times out, the second slot takes the call.

A chalk drawing: a crossed-out box labelled FIRST CHOICE with an arrow curving down to a second box labelled NEXT IN LINE holding a gold dot.

The three families exist because the traffic is genuinely different. spideriq/* is 18 aliases for workers, the scrapers and batch enrichers where cost dominates. agent/* is 9 aliases for live conversation, where a coherent multi-turn session beats a cheap token. opvs/* is 5 aliases for the OPVS agent platform, which splits by job size rather than by task.

Health decides the order, not a static list

Before the chain is tried it gets reordered. Models on healthy providers move to the front, models on struggling ones move to the back, and nothing is dropped. That last part matters more than it sounds: a provider having a bad ten minutes is deprioritised, not removed, so it comes back on its own without anyone editing a config.

A chalk drawing: two circles on a rail, one arcing toward the back, labelled MOVED BACK and STILL THERE, with a gold dot beside the second.

If the whole chain is exhausted the request falls through to its family's general alias rather than failing outright. And when the model that answered is not the one the alias led with, the non-streaming response carries an X-SpiderGate-Fallback-From header naming the first choice, so a fallback is something you can see in your own logs rather than something you infer from a latency graph.

The routing engine underneath is BerriAI's litellm.Router, which does the least-busy selection, the retries and the cooldown. What SpiderGate puts on top is the task alias, the per-tenant auth and a usage record for every call.

The reason I trust this more than my own documentation

Here is the honest part. While writing this I checked the alias list against the database instead of against the docs, and the docs were wrong. The page said 26 aliases. There were 32. An entire family, opvs/*, was undocumented. Sixteen of the 26 rows named a model that no longer led that chain, because the models had moved underneath: spideriq/extraction had gone from Groq to Cerebras, spideriq/fast and spideriq/free to NVIDIA NIM, four agent/* aliases from one Codex id to another.

That drift is not an argument against writing docs. It is the argument for the alias. Sixteen routing changes happened and not one caller had to change a line, because no caller had named a model. The documentation rotted; the callers did not.

It is also why the live list is an endpoint rather than a page. It needs no auth:

curl "https://spideriq.ai/api/gate/v1/aliases"

You get every alias, its full chain in priority order, and its 30-day usage. Read models[0] for what an alias currently leads with and the array length for how deep it runs. If you are hardcoding anything, hardcode against that.

Using it

The endpoint is OpenAI-compatible, so an OpenAI client pointed at the base URL works unchanged:

from openai import OpenAI

client = OpenAI(
    base_url="https://spideriq.ai/api/gate/v1",
    api_key="<client_id>:<api_key>:<api_secret>",
)

resp = client.chat.completions.create(
    model="spideriq/coding",
    messages=[{"role": "user", "content": "Refactor this function."}],
)

One credential, one URL, 1,216 catalogued models with 61 of them key-backed behind it. You can still pass a concrete model id when you genuinely need exactly one model, and you lose the failover in exchange. That trade is worth making occasionally and it should be a decision, not a default.

The full list with each chain is in the task alias reference.

← BACK TO BLOG