Adaptive Routing
by @joelnishanth
Routes LLM requests to a local model first (Ollama, LM Studio, llamafile), validates the response quality, and escalates to cloud only when the local result...
clawhub install adaptive-routingπ About This Skill
name: adaptive-routing description: "Routes LLM requests to a local model first (Ollama, LM Studio, llamafile), validates the response quality, and escalates to cloud only when the local result fails. Tracks local vs escalated vs cloud outcomes in a persistent dashboard. Use when: (1) user asks to run a task with a local model first, (2) user wants to reduce cloud API costs or keep requests private, (3) user wants post-outcome quality validation before committing to a local result, (4) user asks to see token savings or the routing dashboard, (5) any request where local-vs-cloud routing should be decided automatically with a quality gate. Supports Ollama, LM Studio, and llamafile as local providers." metadata: { "openclaw": { "emoji": "π", "requires": { "bins": ["python3"] }, "install": [] } }
Adaptive Routing
Route requests to a local LLM first. Validate the response quality. Escalate to cloud only when the local result fails the quality check. Track every outcome in a persistent dashboard.
Quick Start
1. Check if a local LLM is running
python3 skills/adaptive-routing/scripts/check_local.py
Returns JSON: { "any_available": true, "best": { "provider": "ollama", "models": [...] } }
2. Route a request
python3 skills/adaptive-routing/scripts/route_request.py \
--prompt "Summarize this meeting transcript" \
--tokens 800 \
--local-available \
--local-provider ollama
Returns: { "decision": "local", "reason": "...", "complexity_score": -1, "complexity_threshold": 3 }
3. Execute with the chosen provider
Send the request to your local provider (Ollama, LM Studio, or llamafile). See references/local-providers.md for curl examples.
4. Validate the response
python3 skills/adaptive-routing/scripts/validate_result.py \
--response "The meeting covered three topics..." \
--exit-code 0
Returns: { "passed": true, "score": 1.0, "reason": "ok", "should_escalate": false }
If should_escalate: true, re-run step 3 with your cloud provider instead.
5. Log the outcome
# Local success (no escalation needed)
python3 skills/adaptive-routing/scripts/track_savings.py log \
--kind local_success --tokens 800 --model gpt-4oEscalated (local failed validation, used cloud)
python3 skills/adaptive-routing/scripts/track_savings.py log \
--kind escalated --tokens 800 --model gpt-4o
6. Show the dashboard
python3 skills/adaptive-routing/scripts/dashboard.py
Full Routing Workflow
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 1. check_local.py β is a local provider running? β
β β
β 2. route_request.py β local or cloud? β
β Β· sensitivity check (private data β local) β
β Β· complexity score (high score β cloud) β
β Β· availability gate (no local β cloud) β
β β
β 3. Execute with local provider β
β β
β 4. validate_result.py β did the response pass? β
β Β· passed=true β use result (kind=local_success) β
β Β· passed=false β re-run cloud (kind=escalated) β
β β
β 5. track_savings.py log β record the outcome β
β β
β 6. dashboard.py β show cumulative savings β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Routing Rules (Summary)
| Condition | Route |
| ----------------------------------------------------------------------------- | -------- |
| No local provider available | βοΈ Cloud |
| Prompt contains sensitive data (password, secret, api key, ssn, etc.) | π Local |
| Complexity score β₯ threshold (default 3) | βοΈ Cloud |
| Complexity score < threshold | π Local |
After routing locally, validate_result.py applies a second gate:
| Signal | Escalate? | | ---------------------------- | --------- | | Empty response | Yes | | Process exit code != 0 | Yes | | Timed out | Yes | | Tool error | Yes | | Clean response, score β₯ 0.75 | No |
For full scoring details, see references/routing-logic.md.
Configuration
Create ~/.openclaw/adaptive-routing/config.json to tune thresholds:
{
"complexity_threshold": 3,
"token_high_watermark": 4000,
"token_low_watermark": 500,
"redact_output": true
}
Pass --config /path/to/config.json to route_request.py to use a custom path.
Executing with a Local Provider
Once route_request.py returns "decision": "local", send the request:
Ollama
curl http://localhost:11434/api/generate \
-d '{"model": "llama3.2", "prompt": "YOUR_PROMPT", "stream": false}'
LM Studio / llamafile (OpenAI-compatible)
curl http://localhost:1234/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model": "local-model", "messages": [{"role": "user", "content": "YOUR_PROMPT"}]}'
Dashboard
The dashboard reads from ~/.openclaw/adaptive-routing/savings.json (auto-created).
βββββββββββββββββββββββββββββββββββββββββββββββββ
β π Adaptive Routing Β· Dashboard β
βββββββββββββββββββββββββββββββββββββββββββββββββ€
β Local LLM: β
ollama (llama3.2...) β
βββββββββββββββββββββββββββββββββββββββββββββββββ€
β Total requests: 42 β
β Local (passed): 31 (73.8%) β
β Escalated to cloud: 4 β
β Cloud (direct): 7 β
β Escalation rate: 11.4% β
βββββββββββββββββββββββββββββββββββββββββββββββββ€
β Tokens (local): 84,200 β
β Tokens (cloud): 9,600 β
β Cost saved (USD): $0.4210 β
βββββββββββββββββββββββββββββββββββββββββββββββββ
Reset savings data:
python3 skills/adaptive-routing/scripts/track_savings.py reset
Additional References
π‘ Examples
1. Check if a local LLM is running
python3 skills/adaptive-routing/scripts/check_local.py
Returns JSON: { "any_available": true, "best": { "provider": "ollama", "models": [...] } }
2. Route a request
python3 skills/adaptive-routing/scripts/route_request.py \
--prompt "Summarize this meeting transcript" \
--tokens 800 \
--local-available \
--local-provider ollama
Returns: { "decision": "local", "reason": "...", "complexity_score": -1, "complexity_threshold": 3 }
3. Execute with the chosen provider
Send the request to your local provider (Ollama, LM Studio, or llamafile). See references/local-providers.md for curl examples.
4. Validate the response
python3 skills/adaptive-routing/scripts/validate_result.py \
--response "The meeting covered three topics..." \
--exit-code 0
Returns: { "passed": true, "score": 1.0, "reason": "ok", "should_escalate": false }
If should_escalate: true, re-run step 3 with your cloud provider instead.
5. Log the outcome
# Local success (no escalation needed)
python3 skills/adaptive-routing/scripts/track_savings.py log \
--kind local_success --tokens 800 --model gpt-4oEscalated (local failed validation, used cloud)
python3 skills/adaptive-routing/scripts/track_savings.py log \
--kind escalated --tokens 800 --model gpt-4o
6. Show the dashboard
python3 skills/adaptive-routing/scripts/dashboard.py
βοΈ Configuration
Create ~/.openclaw/adaptive-routing/config.json to tune thresholds:
{
"complexity_threshold": 3,
"token_high_watermark": 4000,
"token_low_watermark": 500,
"redact_output": true
}
Pass --config /path/to/config.json to route_request.py to use a custom path.