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.
@@ -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,15 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.pyo
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .env
8
+ .venv/
9
+ venv/
10
+ *.swp
11
+ *.swo
12
+ .DS_Store
13
+ .idea/
14
+ .vscode/
15
+ __pycache__/
@@ -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.