Install
openclaw skills install @raydatalab/hermes-smart-routerUse when switching models, saving costs, or routing queries. Automatically picks the cheapest model that can handle the job — "translate hello" routes to $0/M local, "design a database" routes to $3/M pro. 100% local classification, zero API calls for routing.
openclaw skills install @raydatalab/hermes-smart-router"Translate hello to German" → local $0/M tok
"Explain how DNS works" → flash $0.15/M tok (GPT-4o-mini)
"Design a distributed database" → pro $3/M tok (Claude Sonnet)
Smart Router classifies every query locally (Ollama embeddings + semantic-router) and picks the cheapest tier that can handle it. Simple queries route to free local models. Complex reasoning routes to frontier models. You pay for what you need — not what your config happens to be set to.
Classification runs entirely on your machine. Zero API calls for routing decisions. Zero keys needed. ~3s on first call, <1ms after.
Load this skill when:
/model, /tier, or switches models mid-sessionDo NOT load for: greetings, one-liners, translations, queries under 20 characters.
Call router.resolve() before answering any non-trivial query.
from smart_router.router import get_router
router = get_router()
decision = router.resolve(user_message, current_tier=ACTIVE_TIER)
# → {"tier": "pro", "model": {...}, "needs_switch": true,
# "reason": "Upgrade from flash to pro — Complex code...",
# "recommendation": "💡 Switch to pro: `/model anthropic claude-sonnet-4` — ..."}
If decision["recommendation"] is not None, paste it at the top of your
response — it's ready to use, no formatting needed.
If decision["recommendation"] is None, just answer normally.
If the call errors or times out, skip it and answer — never retry.
ACTIVE_TIER is your current tier (local/flash/pro). Check with /tier or ask.
Skip routing for: greetings ("hello", "thanks"), translations, one-liner facts, queries under 20 characters. Everything else — route.
| Tier | Example Model | Input Price/1M tok | Use When |
|---|---|---|---|
local | Ollama (llama3, qwen, etc.) | $0 | Simple Q&A, translations, offline |
flash | GPT-4o-mini, Gemini Flash, Claude Haiku | ~$0.15–0.80 | General knowledge, casual coding |
pro | Claude Sonnet, GPT-4o, Gemini Pro | ~$2.50–3 | Complex reasoning, architecture |
Pricing per official API pages (OpenAI, Anthropic, Google). See individual provider docs for exact rates. Per-token pricing means a single 1K-token question costs $0.003 on flash vs $0.003 on pro — but over thousands of queries per month, the difference compounds.
semantic-router[ollama] and smart_routersmart_router:
enabled: true
default_tier: flash
encoder_model: nomic-embed-text
tiers:
local:
provider: custom
model: llama3.2:3b
base_url: http://localhost:11434/v1
flash:
provider: openai
model: gpt-4o-mini
pro:
provider: anthropic
model: claude-sonnet-4
ollama:
auto_start: true
idle_timeout: 300
| Command | Description |
|---|---|
/route <query> | Show tier selection (dry run) |
/route-stats | Session routing statistics |
/ollama start / stop / status | Ollama lifecycle |
/tier | Show current tier and model |
router.resolve(). The most common failure mode.
If the agent answers without routing, manually trigger with /route <query>.decision["ollama_ready"] is false, start Ollama
first (/ollama start) or skip routing for this query.router.resolve() pulls nomic-embed-text (~274MB).
Subsequent calls are instant. Warm up with python3 -m smart_router route "test"
before heavy sessions./model manually.bash scripts/install.sh
python3 -m smart_router route "What is the capital of France?"
python3 -m smart_router chat
python3 -m pytest tests/