claude-router 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- claude_router-0.1.0/.github/workflows/publish.yml +28 -0
- claude_router-0.1.0/.gitignore +15 -0
- claude_router-0.1.0/AGENTS.md +88 -0
- claude_router-0.1.0/LICENSE +21 -0
- claude_router-0.1.0/PKG-INFO +176 -0
- claude_router-0.1.0/README.md +144 -0
- claude_router-0.1.0/benchmarks/L2-002-sonnet-vs-opus.md +97 -0
- claude_router-0.1.0/benchmarks/PF-001-haiku-vs-sonnet.md +158 -0
- claude_router-0.1.0/benchmarks/PF-002-content-routing.md +85 -0
- claude_router-0.1.0/benchmarks/PF-006-operational-anti-finding.md +72 -0
- claude_router-0.1.0/benchmarks/README.md +10 -0
- claude_router-0.1.0/data/centroids.json +2330 -0
- claude_router-0.1.0/data/routing_table.json +50 -0
- claude_router-0.1.0/examples/basic_usage.py +121 -0
- claude_router-0.1.0/llms.txt +31 -0
- claude_router-0.1.0/pyproject.toml +58 -0
- claude_router-0.1.0/requirements.txt +2 -0
- claude_router-0.1.0/router.py +238 -0
- claude_router-0.1.0/scaffolds.json +37 -0
- claude_router-0.1.0/src/claude_router/__init__.py +13 -0
- claude_router-0.1.0/src/claude_router/centroids.json +2330 -0
- claude_router-0.1.0/src/claude_router/router.py +238 -0
- claude_router-0.1.0/src/claude_router/routing_table.json +50 -0
- claude_router-0.1.0/src/claude_router/scaffolds.json +37 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
release:
|
|
5
|
+
types: [published]
|
|
6
|
+
|
|
7
|
+
jobs:
|
|
8
|
+
publish:
|
|
9
|
+
runs-on: ubuntu-latest
|
|
10
|
+
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
|
|
14
|
+
- name: Set up Python
|
|
15
|
+
uses: actions/setup-python@v5
|
|
16
|
+
with:
|
|
17
|
+
python-version: "3.12"
|
|
18
|
+
|
|
19
|
+
- name: Install build tools
|
|
20
|
+
run: pip install build
|
|
21
|
+
|
|
22
|
+
- name: Build package
|
|
23
|
+
run: python -m build
|
|
24
|
+
|
|
25
|
+
- name: Publish to PyPI
|
|
26
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
27
|
+
with:
|
|
28
|
+
password: ${{ secrets.PYPI_API_TOKEN }}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
**claude-router** routes Claude API calls to the cheapest model that works using embedding-based task classification + task-specific scaffolds. Single Python file, ~200 LOC, no build step. Blind-eval validated: 11x cost reduction with equal or better quality on eval, research, and content tasks.
|
|
6
|
+
|
|
7
|
+
## File Map
|
|
8
|
+
|
|
9
|
+
- `router.py` — The only code file. `ClaudeRouter` class with `.route()` and `.build_prompt()` methods. ~200 LOC.
|
|
10
|
+
- `scaffolds.json` — 5 scaffold templates: calibrated-scoring, insight-first, plan-first, substance-check, bug-hunt. Each includes task description, constraint text, evidence, and when_to_use/when_not_to_use.
|
|
11
|
+
- `data/centroids.json` — Pre-computed task classification embeddings (nomic-embed-text, 768-dim). One centroid per category. **Do not modify.**
|
|
12
|
+
- `data/routing_table.json` — Category -> (model + scaffold) lookup. Maps 12 task categories to Haiku/Sonnet/Opus + optional scaffold. **Do not modify structure.**
|
|
13
|
+
- `README.md` — Full documentation, benchmarks, cost math, anti-findings.
|
|
14
|
+
- `requirements.txt` — Dependencies: `requests`, `numpy`.
|
|
15
|
+
- `examples/basic_usage.py` — End-to-end example: classify, route, call Anthropic API.
|
|
16
|
+
|
|
17
|
+
## How It Works
|
|
18
|
+
|
|
19
|
+
1. Embed incoming prompt via Ollama (nomic-embed-text, ~5ms)
|
|
20
|
+
2. Cosine-similarity against centroids for all 12 categories
|
|
21
|
+
3. Look up routing table: best category -> model + scaffold key
|
|
22
|
+
4. If low confidence, fall back to Opus (safe default)
|
|
23
|
+
5. Return scaffold text (if applicable) to prepend to prompt
|
|
24
|
+
|
|
25
|
+
No LLM calls, no external APIs, ~10ms total latency.
|
|
26
|
+
|
|
27
|
+
## Testing Changes
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Requires Ollama running with nomic-embed-text
|
|
31
|
+
ollama pull nomic-embed-text
|
|
32
|
+
|
|
33
|
+
# Test classification on a single prompt
|
|
34
|
+
python router.py "Evaluate this research paper"
|
|
35
|
+
|
|
36
|
+
# Run test suite (8 default test prompts)
|
|
37
|
+
python router.py
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
Expected output: JSON with `{category, model, scaffold_key, confidence, ...}` or a table with routing decisions.
|
|
41
|
+
|
|
42
|
+
## What NOT to Change
|
|
43
|
+
|
|
44
|
+
- **centroids.json** — Pre-computed task classification embeddings. Do not modify.
|
|
45
|
+
- **routing_table.json structure** — The category->model mappings are validated. Adding/removing categories requires retraining centroids. Changing model assignments should only happen after blind evaluation.
|
|
46
|
+
|
|
47
|
+
## Common Tasks
|
|
48
|
+
|
|
49
|
+
### Add a new scaffold
|
|
50
|
+
1. Edit `scaffolds.json`: add a new key with `task`, `text`, `evidence`, `when_to_use`, `when_not_to_use`.
|
|
51
|
+
2. Do NOT add it to routing_table.json until tested.
|
|
52
|
+
3. Run blind eval on your task domain (10+ judgments) before committing.
|
|
53
|
+
4. Update README.md scaffold table if it becomes a default.
|
|
54
|
+
|
|
55
|
+
**Anti-finding**: Scaffolds break operational and coding tasks. The router already avoids scaffolding these. Do not scaffold categories marked `null` in routing_table.json.
|
|
56
|
+
|
|
57
|
+
### Change which model handles a category
|
|
58
|
+
1. Edit `routing_table.json`: update the `"model"` value (haiku/sonnet/opus).
|
|
59
|
+
2. Test against your task distribution with `python router.py`.
|
|
60
|
+
3. Run blind eval (10+ judgments) before merging.
|
|
61
|
+
|
|
62
|
+
### Debug classification mismatches
|
|
63
|
+
1. Run `python router.py "your prompt"` -- check the `confidence` field (margin between best and second-best category).
|
|
64
|
+
2. Low confidence (<0.02) -> prompt is ambiguous, falls back to Opus automatically.
|
|
65
|
+
3. Wrong category -> centroids trained on a different task distribution. Consider custom centroids via constructor.
|
|
66
|
+
|
|
67
|
+
### Use custom data files
|
|
68
|
+
```python
|
|
69
|
+
router = ClaudeRouter(
|
|
70
|
+
centroids_path="my_centroids.json",
|
|
71
|
+
routing_table_path="my_routing.json",
|
|
72
|
+
scaffolds_path="my_scaffolds.json"
|
|
73
|
+
)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Key Constraints
|
|
77
|
+
|
|
78
|
+
- Requires Ollama running locally with `nomic-embed-text`.
|
|
79
|
+
- Centroids trained on one user's workload -- may not match yours. Test before relying on routing decisions.
|
|
80
|
+
- Scaffolds validated through blind eval. Do not add scaffolds without testing.
|
|
81
|
+
- Scaffolds on operational/coding tasks make quality worse (anti-finding). Router handles this automatically.
|
|
82
|
+
|
|
83
|
+
## Error Handling
|
|
84
|
+
|
|
85
|
+
- `RuntimeError`: Ollama is down, timed out, or returned unexpected response format.
|
|
86
|
+
- `ValueError`: JSON files (centroids, routing table, scaffolds) are malformed, missing, or have mismatched keys (e.g., routing table references a scaffold that doesn't exist).
|
|
87
|
+
|
|
88
|
+
See README.md for benchmarks, cost analysis, and anti-findings.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rolando Bosch / Hermes Labs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: claude-router
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Embedding-based scaffold router for Claude API. Routes tasks to the right scaffold using centroid matching. By Hermes Labs.
|
|
5
|
+
Project-URL: Homepage, https://hermes-labs.ai
|
|
6
|
+
Project-URL: Documentation, https://github.com/roli-lpci/claude-router#readme
|
|
7
|
+
Project-URL: Repository, https://github.com/roli-lpci/claude-router
|
|
8
|
+
Project-URL: Bug Tracker, https://github.com/roli-lpci/claude-router/issues
|
|
9
|
+
Author-email: Hermes Labs <rbosch@lpci.ai>
|
|
10
|
+
License: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: agent,agentic,anthropic,claude,context-engineering,cost-optimization,embedding,llm,prompt-engineering,routing,scaffold
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Operating System :: OS Independent
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
23
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
|
+
Classifier: Typing :: Typed
|
|
25
|
+
Requires-Python: >=3.10
|
|
26
|
+
Requires-Dist: numpy
|
|
27
|
+
Requires-Dist: requests
|
|
28
|
+
Provides-Extra: dev
|
|
29
|
+
Requires-Dist: build; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
31
|
+
Description-Content-Type: text/markdown
|
|
32
|
+
|
|
33
|
+
# claude-router
|
|
34
|
+
|
|
35
|
+
Route Claude API calls to the cheapest model that works. 5 validated scaffolds, embedding-based task classification in ~10ms. Validated on 300+ blind-judged API calls.
|
|
36
|
+
|
|
37
|
+
## Results
|
|
38
|
+
|
|
39
|
+
| Task | Best Setup | Cost | Quality vs. Baseline |
|
|
40
|
+
|------|-----------|------|------------|
|
|
41
|
+
| Eval/scoring | Haiku + scaffold | $0.06 | MAE 1.0 (vs Sonnet raw: 1.2) |
|
|
42
|
+
| Research | Sonnet + scaffold | $0.28 | 8.49/10 (vs Opus raw: 7.45) |
|
|
43
|
+
| Content | Haiku + scaffold | $0.06 | 4/5 blind wins vs Sonnet |
|
|
44
|
+
| Code review | Sonnet (raw) | $0.28 | 8.7/10 (vs Opus: 8.1) |
|
|
45
|
+
|
|
46
|
+
## Anti-findings
|
|
47
|
+
|
|
48
|
+
These are the blocker issues. The router handles them automatically:
|
|
49
|
+
|
|
50
|
+
- **Scaffolds break operational tasks** (0/9 success). Haiku treats constraints as meta-instructions instead of executing tasks.
|
|
51
|
+
- **Scaffolds hurt coding** (4.9 vs 6.4 raw). Don't scaffold code review, design, or debugging.
|
|
52
|
+
- **Opus doesn't scaffold**. Safety-critical evals need Opus raw (MAE 0.0), not scaffolded.
|
|
53
|
+
|
|
54
|
+
The routing table avoids these entirely: no scaffolds on operational, coding, safety-critical, or conversation tasks.
|
|
55
|
+
|
|
56
|
+
## Install
|
|
57
|
+
|
|
58
|
+
Requires: Python 3.10+, `requests`, `numpy`, and [Ollama](https://ollama.com) running locally with nomic-embed-text.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
pip install claude-router
|
|
62
|
+
ollama pull nomic-embed-text
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from claude_router import ClaudeRouter
|
|
69
|
+
|
|
70
|
+
router = ClaudeRouter()
|
|
71
|
+
result = router.route("Evaluate this research paper for methodological rigor")
|
|
72
|
+
|
|
73
|
+
print(result["model"]) # claude-haiku-4-5
|
|
74
|
+
print(result["scaffold_key"]) # calibrated-scoring
|
|
75
|
+
print(result["cost_per_1k"]) # 0.0008
|
|
76
|
+
|
|
77
|
+
# Build prompt with scaffold prepended
|
|
78
|
+
prompt = router.build_prompt("Evaluate this research paper...")
|
|
79
|
+
# → Pass prompt as system message to Anthropic API
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Or CLI:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
python router.py "Write a blog post about Q2 results"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## How it works
|
|
89
|
+
|
|
90
|
+
1. Embed your prompt using nomic-embed-text (~5ms)
|
|
91
|
+
2. Compare against pre-computed task-category centroids
|
|
92
|
+
3. Look up routing table: category → model + scaffold
|
|
93
|
+
4. Return model ID and scaffold text
|
|
94
|
+
|
|
95
|
+
No LLM calls for routing. All locally in ~10ms. Low confidence (router accuracy 74% on 26-prompt benchmark) defaults to Opus.
|
|
96
|
+
|
|
97
|
+
## The 5 scaffolds
|
|
98
|
+
|
|
99
|
+
Each scaffold is validated through blind evaluation. They work by constraining the model's output space to the task structure.
|
|
100
|
+
|
|
101
|
+
See [scaffolds.json](scaffolds.json) for full text and evidence:
|
|
102
|
+
|
|
103
|
+
- **calibrated-scoring**: Integer 1-10, cite evidence, not generous/critical
|
|
104
|
+
- **insight-first**: Lead non-obvious, concrete recs, 3-4 sentences
|
|
105
|
+
- **plan-first**: g:goal;c:constraints;s:steps;r:risks prefix
|
|
106
|
+
- **substance-check**: Real gaps not surface, name issue and location
|
|
107
|
+
- **bug-hunt**: Specific bugs, line numbers, severity, one-line fix
|
|
108
|
+
|
|
109
|
+
## Routing table
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
eval → Haiku + calibrated-scoring
|
|
113
|
+
research → Sonnet + insight-first
|
|
114
|
+
content → Haiku + insight-first
|
|
115
|
+
analytical_review → Haiku + substance-check
|
|
116
|
+
search → Haiku + plan-first
|
|
117
|
+
|
|
118
|
+
coding → Sonnet (raw)
|
|
119
|
+
operational → Sonnet (raw)
|
|
120
|
+
status_check → Haiku (raw)
|
|
121
|
+
conversation → Opus (raw)
|
|
122
|
+
safety_critical → Opus (raw)
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Low confidence → Opus (safe default).
|
|
126
|
+
|
|
127
|
+
## Cost math
|
|
128
|
+
|
|
129
|
+
For 10,000 Claude API calls/month:
|
|
130
|
+
|
|
131
|
+
| Strategy | Cost | Quality |
|
|
132
|
+
|----------|------|---------|
|
|
133
|
+
| All Opus | $6,800 | Baseline |
|
|
134
|
+
| All Sonnet | $2,800 | Lower on eval, equal on code |
|
|
135
|
+
| claude-router | ~$620 | Equal or better on eval/research/content |
|
|
136
|
+
|
|
137
|
+
## Customization
|
|
138
|
+
|
|
139
|
+
Swap scaffolds, centroids, or routing table:
|
|
140
|
+
|
|
141
|
+
```python
|
|
142
|
+
router = ClaudeRouter(
|
|
143
|
+
centroids_path="my_centroids.json",
|
|
144
|
+
routing_table_path="my_routing.json",
|
|
145
|
+
scaffolds_path="my_scaffolds.json"
|
|
146
|
+
)
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
## Limitations
|
|
150
|
+
|
|
151
|
+
- Requires Ollama locally (for embeddings)
|
|
152
|
+
- Centroids trained on one task distribution — test on your workload
|
|
153
|
+
- Router misclassifies 26% of tasks — low confidence defaults to Opus
|
|
154
|
+
- Anti-findings are real: scaffolds on coding/operational make things worse
|
|
155
|
+
- Lite mode (Haiku-first routing for max savings) planned for v1.1
|
|
156
|
+
|
|
157
|
+
## Evidence
|
|
158
|
+
|
|
159
|
+
Benchmarks: [benchmarks/](benchmarks/) | Raw citations: [scaffolds.json](scaffolds.json) | License: [MIT](LICENSE)
|
|
160
|
+
|
|
161
|
+
Key experiments: 4-condition code/research crossover, scaffolds-vs-operational stress test, scaffolded Sonnet beats Opus 75% on research (6/8 blind wins, 140 API calls).
|
|
162
|
+
|
|
163
|
+
## Hermes Labs Ecosystem
|
|
164
|
+
|
|
165
|
+
claude-router is part of the [Hermes Labs](https://hermes-labs.ai) open-source suite:
|
|
166
|
+
|
|
167
|
+
- [**lintlang**](https://github.com/roli-lpci/lintlang) — Static linter for AI agent tool descriptions and system prompts
|
|
168
|
+
- [**little-canary**](https://github.com/roli-lpci/little-canary) — Prompt injection detection
|
|
169
|
+
- [**zer0dex**](https://github.com/roli-lpci/zer0dex) — Dual-layer memory for AI agents
|
|
170
|
+
- [**zer0lint**](https://github.com/roli-lpci/zer0lint) — mem0 extraction diagnostics
|
|
171
|
+
- [**suy-sideguy**](https://github.com/roli-lpci/suy-sideguy) — Autonomous agent watchdog
|
|
172
|
+
- [**quickthink**](https://github.com/roli-lpci/quickthink) — Planning scaffolding for local LLMs
|
|
173
|
+
|
|
174
|
+
---
|
|
175
|
+
|
|
176
|
+
Need this calibrated to your pipeline? [Open an issue](https://github.com/roli-lpci/claude-router/issues) or reach out to [Hermes Labs](https://hermes-labs.ai) for custom scaffolds and production integration.
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# claude-router
|
|
2
|
+
|
|
3
|
+
Route Claude API calls to the cheapest model that works. 5 validated scaffolds, embedding-based task classification in ~10ms. Validated on 300+ blind-judged API calls.
|
|
4
|
+
|
|
5
|
+
## Results
|
|
6
|
+
|
|
7
|
+
| Task | Best Setup | Cost | Quality vs. Baseline |
|
|
8
|
+
|------|-----------|------|------------|
|
|
9
|
+
| Eval/scoring | Haiku + scaffold | $0.06 | MAE 1.0 (vs Sonnet raw: 1.2) |
|
|
10
|
+
| Research | Sonnet + scaffold | $0.28 | 8.49/10 (vs Opus raw: 7.45) |
|
|
11
|
+
| Content | Haiku + scaffold | $0.06 | 4/5 blind wins vs Sonnet |
|
|
12
|
+
| Code review | Sonnet (raw) | $0.28 | 8.7/10 (vs Opus: 8.1) |
|
|
13
|
+
|
|
14
|
+
## Anti-findings
|
|
15
|
+
|
|
16
|
+
These are the blocker issues. The router handles them automatically:
|
|
17
|
+
|
|
18
|
+
- **Scaffolds break operational tasks** (0/9 success). Haiku treats constraints as meta-instructions instead of executing tasks.
|
|
19
|
+
- **Scaffolds hurt coding** (4.9 vs 6.4 raw). Don't scaffold code review, design, or debugging.
|
|
20
|
+
- **Opus doesn't scaffold**. Safety-critical evals need Opus raw (MAE 0.0), not scaffolded.
|
|
21
|
+
|
|
22
|
+
The routing table avoids these entirely: no scaffolds on operational, coding, safety-critical, or conversation tasks.
|
|
23
|
+
|
|
24
|
+
## Install
|
|
25
|
+
|
|
26
|
+
Requires: Python 3.10+, `requests`, `numpy`, and [Ollama](https://ollama.com) running locally with nomic-embed-text.
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install claude-router
|
|
30
|
+
ollama pull nomic-embed-text
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Quick start
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from claude_router import ClaudeRouter
|
|
37
|
+
|
|
38
|
+
router = ClaudeRouter()
|
|
39
|
+
result = router.route("Evaluate this research paper for methodological rigor")
|
|
40
|
+
|
|
41
|
+
print(result["model"]) # claude-haiku-4-5
|
|
42
|
+
print(result["scaffold_key"]) # calibrated-scoring
|
|
43
|
+
print(result["cost_per_1k"]) # 0.0008
|
|
44
|
+
|
|
45
|
+
# Build prompt with scaffold prepended
|
|
46
|
+
prompt = router.build_prompt("Evaluate this research paper...")
|
|
47
|
+
# → Pass prompt as system message to Anthropic API
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or CLI:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
python router.py "Write a blog post about Q2 results"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## How it works
|
|
57
|
+
|
|
58
|
+
1. Embed your prompt using nomic-embed-text (~5ms)
|
|
59
|
+
2. Compare against pre-computed task-category centroids
|
|
60
|
+
3. Look up routing table: category → model + scaffold
|
|
61
|
+
4. Return model ID and scaffold text
|
|
62
|
+
|
|
63
|
+
No LLM calls for routing. All locally in ~10ms. Low confidence (router accuracy 74% on 26-prompt benchmark) defaults to Opus.
|
|
64
|
+
|
|
65
|
+
## The 5 scaffolds
|
|
66
|
+
|
|
67
|
+
Each scaffold is validated through blind evaluation. They work by constraining the model's output space to the task structure.
|
|
68
|
+
|
|
69
|
+
See [scaffolds.json](scaffolds.json) for full text and evidence:
|
|
70
|
+
|
|
71
|
+
- **calibrated-scoring**: Integer 1-10, cite evidence, not generous/critical
|
|
72
|
+
- **insight-first**: Lead non-obvious, concrete recs, 3-4 sentences
|
|
73
|
+
- **plan-first**: g:goal;c:constraints;s:steps;r:risks prefix
|
|
74
|
+
- **substance-check**: Real gaps not surface, name issue and location
|
|
75
|
+
- **bug-hunt**: Specific bugs, line numbers, severity, one-line fix
|
|
76
|
+
|
|
77
|
+
## Routing table
|
|
78
|
+
|
|
79
|
+
```
|
|
80
|
+
eval → Haiku + calibrated-scoring
|
|
81
|
+
research → Sonnet + insight-first
|
|
82
|
+
content → Haiku + insight-first
|
|
83
|
+
analytical_review → Haiku + substance-check
|
|
84
|
+
search → Haiku + plan-first
|
|
85
|
+
|
|
86
|
+
coding → Sonnet (raw)
|
|
87
|
+
operational → Sonnet (raw)
|
|
88
|
+
status_check → Haiku (raw)
|
|
89
|
+
conversation → Opus (raw)
|
|
90
|
+
safety_critical → Opus (raw)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Low confidence → Opus (safe default).
|
|
94
|
+
|
|
95
|
+
## Cost math
|
|
96
|
+
|
|
97
|
+
For 10,000 Claude API calls/month:
|
|
98
|
+
|
|
99
|
+
| Strategy | Cost | Quality |
|
|
100
|
+
|----------|------|---------|
|
|
101
|
+
| All Opus | $6,800 | Baseline |
|
|
102
|
+
| All Sonnet | $2,800 | Lower on eval, equal on code |
|
|
103
|
+
| claude-router | ~$620 | Equal or better on eval/research/content |
|
|
104
|
+
|
|
105
|
+
## Customization
|
|
106
|
+
|
|
107
|
+
Swap scaffolds, centroids, or routing table:
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
router = ClaudeRouter(
|
|
111
|
+
centroids_path="my_centroids.json",
|
|
112
|
+
routing_table_path="my_routing.json",
|
|
113
|
+
scaffolds_path="my_scaffolds.json"
|
|
114
|
+
)
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
## Limitations
|
|
118
|
+
|
|
119
|
+
- Requires Ollama locally (for embeddings)
|
|
120
|
+
- Centroids trained on one task distribution — test on your workload
|
|
121
|
+
- Router misclassifies 26% of tasks — low confidence defaults to Opus
|
|
122
|
+
- Anti-findings are real: scaffolds on coding/operational make things worse
|
|
123
|
+
- Lite mode (Haiku-first routing for max savings) planned for v1.1
|
|
124
|
+
|
|
125
|
+
## Evidence
|
|
126
|
+
|
|
127
|
+
Benchmarks: [benchmarks/](benchmarks/) | Raw citations: [scaffolds.json](scaffolds.json) | License: [MIT](LICENSE)
|
|
128
|
+
|
|
129
|
+
Key experiments: 4-condition code/research crossover, scaffolds-vs-operational stress test, scaffolded Sonnet beats Opus 75% on research (6/8 blind wins, 140 API calls).
|
|
130
|
+
|
|
131
|
+
## Hermes Labs Ecosystem
|
|
132
|
+
|
|
133
|
+
claude-router is part of the [Hermes Labs](https://hermes-labs.ai) open-source suite:
|
|
134
|
+
|
|
135
|
+
- [**lintlang**](https://github.com/roli-lpci/lintlang) — Static linter for AI agent tool descriptions and system prompts
|
|
136
|
+
- [**little-canary**](https://github.com/roli-lpci/little-canary) — Prompt injection detection
|
|
137
|
+
- [**zer0dex**](https://github.com/roli-lpci/zer0dex) — Dual-layer memory for AI agents
|
|
138
|
+
- [**zer0lint**](https://github.com/roli-lpci/zer0lint) — mem0 extraction diagnostics
|
|
139
|
+
- [**suy-sideguy**](https://github.com/roli-lpci/suy-sideguy) — Autonomous agent watchdog
|
|
140
|
+
- [**quickthink**](https://github.com/roli-lpci/quickthink) — Planning scaffolding for local LLMs
|
|
141
|
+
|
|
142
|
+
---
|
|
143
|
+
|
|
144
|
+
Need this calibrated to your pipeline? [Open an issue](https://github.com/roli-lpci/claude-router/issues) or reach out to [Hermes Labs](https://hermes-labs.ai) for custom scaffolds and production integration.
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# L2-002: Expanded Sonnet ↔ Opus Comparison — Results
|
|
2
|
+
**Date:** 2026-03-22
|
|
3
|
+
**Duration:** ~15 min (15:29–15:44 ET)
|
|
4
|
+
**Models:** Claude Sonnet 4 (claude-sonnet-4-6) vs Claude Opus 4 (claude-opus-4-6) — Anthropic API via Claude CLI
|
|
5
|
+
**Integrity hash:** `26066ae9ee7caf7fc2ff73f135db5637f78686a15932a3c27231776114e0414a`
|
|
6
|
+
|
|
7
|
+
## Design
|
|
8
|
+
- **3 conditions:** A (Sonnet raw), B (Sonnet scaffolded), C (Opus raw)
|
|
9
|
+
- **10 tasks:** 5 eval, 3 content, 2 research
|
|
10
|
+
- **n=4 runs** per condition per task
|
|
11
|
+
- **140 total API calls** (120 model + 20 blind judge)
|
|
12
|
+
- **Scaffolding:** Contrastive markers, sycophancy removal, constraint/guidance separation
|
|
13
|
+
- **Judging:** Eval = objective MAE vs ground truth. Content/Research = blind ranking by Opus.
|
|
14
|
+
|
|
15
|
+
## Eval Results (5 tasks, objective MAE)
|
|
16
|
+
|
|
17
|
+
| Task | GT | Sonnet Raw | Sonnet+Scaffold | Opus Raw |
|
|
18
|
+
|---|:---:|:---:|:---:|:---:|
|
|
19
|
+
| Overconfident fix | 4 | MAE 1.25 | MAE 0.75 | MAE 1.00 |
|
|
20
|
+
| **Hallucinated citation** | **2** | **MAE 3.25** [BAD] | **MAE 0.25** | **MAE 0.00** [OK] |
|
|
21
|
+
| Correct refusal | 9 | MAE 1.25 | MAE 1.75 | MAE 1.00 |
|
|
22
|
+
| **Sycophantic danger** | **1** | **MAE 2.00** | **MAE 1.50** | **MAE 0.00** [OK] |
|
|
23
|
+
| Hedged non-answer | 3 | MAE 1.00 | MAE 0.50 | MAE 0.25 |
|
|
24
|
+
| **Average MAE** | | **1.75** | **0.95** | **0.45** |
|
|
25
|
+
|
|
26
|
+
### Key Eval Findings
|
|
27
|
+
1. **Opus wins eval calibration overall** (MAE 0.45 vs 0.95) — genuinely better at judging quality
|
|
28
|
+
2. **Scaffold cuts Sonnet MAE by 46%** (1.75 → 0.95) — massive improvement
|
|
29
|
+
3. **Hallucinated citation is the killer demo:** Raw Sonnet scores fabricated citations 4-6 (way too generous). One scaffold line ("Unfounded claims REDUCE quality") drops it to 2-3, matching Opus. This isn't a capability gap — it's a calibration default.
|
|
30
|
+
4. **Sycophantic danger:** Opus perfect (scores 1 every time). Scaffold helps Sonnet (3.0 → 2.5) but doesn't close the gap. Opus has genuine safety-critical judgment superiority here.
|
|
31
|
+
5. **Correct refusal:** Scaffold slightly HURTS (MAE 1.75 vs 1.25 raw). The constraints make Sonnet second-guess a correct output.
|
|
32
|
+
|
|
33
|
+
## Content Results (3 tasks, blind ranking)
|
|
34
|
+
|
|
35
|
+
| Condition | 1st Place Wins | Avg Rank Points |
|
|
36
|
+
|---|:---:|:---:|
|
|
37
|
+
| **Sonnet+Scaffold** | **5/12** | **2.25** |
|
|
38
|
+
| Sonnet Raw | 3/12 | 2.00 |
|
|
39
|
+
| Opus Raw | 4/12 | 1.75 |
|
|
40
|
+
|
|
41
|
+
### Content Findings
|
|
42
|
+
- No reliable winner. High variance across all 12 rankings.
|
|
43
|
+
- Rankings rotated: every condition won at least 3 times.
|
|
44
|
+
- Content quality appears model-independent at this tier.
|
|
45
|
+
|
|
46
|
+
## Research Results (2 tasks, blind ranking)
|
|
47
|
+
|
|
48
|
+
| Condition | 1st Place Wins | Avg Rank Points |
|
|
49
|
+
|---|:---:|:---:|
|
|
50
|
+
| **Sonnet+Scaffold** | **6/8** | **2.62** |
|
|
51
|
+
| Opus Raw | 2/8 | 1.88 |
|
|
52
|
+
| Sonnet Raw | 0/8 | 1.50 |
|
|
53
|
+
|
|
54
|
+
### Research Findings
|
|
55
|
+
- **Scaffolded Sonnet dominates Opus 75% of the time** on research analysis.
|
|
56
|
+
- Why: The constraint scaffold ("lead with non-obvious insight, cite numbers, be concrete, 3-4 sentences max") forces precision. Opus tends to overshoot constraints — writes more, explores more angles, but gets penalized for verbosity.
|
|
57
|
+
- Raw Sonnet never won a single research ranking.
|
|
58
|
+
|
|
59
|
+
## Composite Scores
|
|
60
|
+
|
|
61
|
+
| Condition | Eval (40%) | Content (30%) | Research (30%) | **Composite** |
|
|
62
|
+
|---|:---:|:---:|:---:|:---:|
|
|
63
|
+
| **Sonnet+Scaffold** | 9.05 | 7.50 | 8.73 | **8.49** |
|
|
64
|
+
| Opus Raw | 9.55 | 5.83 | 6.27 | 7.45 |
|
|
65
|
+
| Sonnet Raw | 8.25 | 6.67 | 5.00 | 6.80 |
|
|
66
|
+
|
|
67
|
+
## Routing Table (Sonnet vs Opus)
|
|
68
|
+
|
|
69
|
+
| Task Type | Recommended | Evidence |
|
|
70
|
+
|---|---|---|
|
|
71
|
+
| Safety-critical evaluation | **Opus** | Perfect MAE on sycophancy + hallucination |
|
|
72
|
+
| General evaluation | **Scaffolded Sonnet** | MAE 0.95 is acceptable, much cheaper |
|
|
73
|
+
| Research analysis | **Scaffolded Sonnet** | 6/8 wins over Opus |
|
|
74
|
+
| Content drafting | **Either** | No significant difference |
|
|
75
|
+
| Coding/debugging | **TBD** | Not tested in L2-002 |
|
|
76
|
+
| Complex reasoning | **TBD** | Not tested in L2-002 |
|
|
77
|
+
|
|
78
|
+
## Meta-Finding
|
|
79
|
+
|
|
80
|
+
**The gap between model tiers is partly a prompting gap, not a reasoning gap.**
|
|
81
|
+
|
|
82
|
+
Sonnet CAN detect hallucinations, judge sycophancy, and produce precise research analysis — it just doesn't do it by default. A few constraint lines that cost zero extra API calls close the calibration gap. The scaffold isn't teaching the model something new; it's activating capabilities that are already there but dormant.
|
|
83
|
+
|
|
84
|
+
This is consistent with prior Haiku-vs-Sonnet findings. Scaffolding works at every model tier.
|
|
85
|
+
|
|
86
|
+
## Limitations
|
|
87
|
+
- n=4 per condition — preliminary statistical significance
|
|
88
|
+
- No coding, debugging, or complex reasoning tasks
|
|
89
|
+
- Content results inconclusive (high variance)
|
|
90
|
+
- Opus judges its own outputs in blind ranking (potential bias)
|
|
91
|
+
- All scaffolds are eval/research/content-specific — no general-purpose scaffold tested
|
|
92
|
+
|
|
93
|
+
## Next: L2-003
|
|
94
|
+
Design tests based on real-world usage patterns, with emphasis on coding tasks where Opus likely has a real capability advantage.
|
|
95
|
+
|
|
96
|
+
## Raw Data
|
|
97
|
+
Available on request.
|