narcolepticchicken commited on
Commit
032c73c
·
verified ·
1 Parent(s): 30117ba

Delete eval/ablation_results.json, eval/baarbundle.json, eval/benchmark_results.json, eval/benchmark_v9_final.json, eval/bfcl_results.json, eval/v8_*, eval/e2e_standalone_results.json, eval/e2e_v2_fixed_results.json, eval/repro_v2.json, eval/launcher.py, eval/run_bert_eval_launcher.py, docs/model_card.md, docs/deployment_guide.md, docs/ROADMAP.md, docs/technical_blog.md, docs/conformal_report.md, docs/FINAL_COMPREHENSIVE_REPORT.md, docs/final_report_v2.md, eval_runner.py, app.py, dashboard.py, examples/end_to_end_demo.py

Browse files
app.py DELETED
@@ -1,183 +0,0 @@
1
- """Gradio Space for Agent Cost Optimizer Dashboard.
2
-
3
- This app visualizes cost-quality frontiers from ACO benchmark runs.
4
- If no benchmark data exists, it runs the benchmark on first load.
5
- """
6
-
7
- import json
8
- import subprocess
9
- import sys
10
- from pathlib import Path
11
- from typing import Dict, List, Any
12
-
13
- import gradio as gr
14
-
15
-
16
- def ensure_data_exists():
17
- """Run benchmark if data doesn't exist."""
18
- results_path = Path("eval_results_v2/baseline_results.json")
19
- report_path = Path("eval_results_v2/report.txt")
20
-
21
- if not results_path.exists() or not report_path.exists():
22
- print("Benchmark data not found. Running benchmark...")
23
- try:
24
- # Run the benchmark generator
25
- subprocess.run(
26
- [sys.executable, "standalone_eval_v2.py", "--tasks", "2000", "--output", "eval_results_v2"],
27
- capture_output=True, text=True, timeout=120
28
- )
29
- print("Benchmark complete.")
30
- except Exception as e:
31
- print(f"Benchmark failed: {e}")
32
-
33
- return results_path, report_path
34
-
35
-
36
- def load_results(path: str) -> Dict[str, Any]:
37
- with open(path) as f:
38
- return json.load(f)
39
-
40
-
41
- def parse_report(report_path: str) -> str:
42
- with open(report_path) as f:
43
- return f.read()
44
-
45
-
46
- def create_frontier_plot(results: Dict[str, Any]):
47
- points = []
48
- for name, data in results.items():
49
- success = (data.get("num_success", 0) + data.get("num_partial", 0)) / max(data.get("num_tasks", 1), 1)
50
- cost = data.get("avg_cost_success", 0)
51
- points.append({"baseline": name, "success_rate": success, "cost_per_success": cost})
52
- points.sort(key=lambda p: (-p["success_rate"], p["cost_per_success"]))
53
- frontier = []
54
- min_cost = float("inf")
55
- for p in points:
56
- if p["cost_per_success"] <= min_cost:
57
- frontier.append(p)
58
- min_cost = p["cost_per_success"]
59
- return points, frontier
60
-
61
-
62
- def build_dashboard():
63
- results_path, report_path = ensure_data_exists()
64
-
65
- if not results_path.exists() or not report_path.exists():
66
- with gr.Blocks(title="Agent Cost Optimizer Dashboard") as demo:
67
- gr.Markdown("# Agent Cost Optimizer Dashboard")
68
- gr.Markdown("## Benchmark data not available")
69
- gr.Markdown("Run `python standalone_eval_v2.py --tasks 2000 --output eval_results_v2` to generate data.")
70
- return demo
71
-
72
- results = load_results(str(results_path))
73
- report_text = parse_report(str(report_path))
74
- points, frontier = create_frontier_plot(results)
75
-
76
- with gr.Blocks(title="Agent Cost Optimizer Dashboard") as demo:
77
- gr.Markdown("# Agent Cost Optimizer - Cost-Quality Dashboard")
78
- gr.Markdown("Visualize cost-quality tradeoffs across routing strategies and ablations.")
79
-
80
- with gr.Row():
81
- with gr.Column(scale=2):
82
- gr.Markdown("## Cost-Quality Frontier")
83
- gr.Markdown("**X-axis**: Average cost per successful task | **Y-axis**: Success rate")
84
-
85
- scatter_data = [
86
- [p["baseline"], f"{p['success_rate']:.1%}", f"${p['cost_per_success']:.4f}"]
87
- for p in points
88
- ]
89
- gr.Dataframe(
90
- headers=["Baseline", "Success Rate", "Cost per Success"],
91
- value=scatter_data,
92
- label="All Baselines",
93
- )
94
-
95
- frontier_data = [
96
- [p["baseline"], f"{p['success_rate']:.1%}", f"${p['cost_per_success']:.4f}"]
97
- for p in frontier
98
- ]
99
- gr.Dataframe(
100
- headers=["Baseline", "Success Rate", "Cost per Success"],
101
- value=frontier_data,
102
- label="Pareto Frontier",
103
- )
104
-
105
- with gr.Column(scale=1):
106
- gr.Markdown("## Pareto Frontier Baselines")
107
- pareto_names = [p["baseline"] for p in frontier]
108
- for name in pareto_names:
109
- gr.Markdown(f"- **{name}**")
110
-
111
- with gr.Row():
112
- with gr.Column():
113
- gr.Markdown("## Baseline Comparison")
114
- comparison_data = []
115
- for name, data in results.items():
116
- comparison_data.append([
117
- name,
118
- f"{(data.get('num_success',0)+data.get('num_partial',0))/max(data.get('num_tasks',1),1):.1%}",
119
- f"${data.get('avg_cost_success',0):.4f}",
120
- f"${data.get('total_cost',0):.2f}",
121
- f"{data.get('cost_reduction_vs_frontier',0):.1%}",
122
- f"{data.get('false_done_rate',0):.1%}",
123
- f"{data.get('unsafe_cheap_miss_rate',0):.1%}",
124
- f"{data.get('regression_rate',0):.1%}",
125
- ])
126
- gr.Dataframe(
127
- headers=["Baseline", "Success", "Cost/Success", "Total Cost", "Cost Reduction", "False-DONE", "Cheap Miss", "Regression"],
128
- value=comparison_data,
129
- )
130
-
131
- with gr.Row():
132
- with gr.Column():
133
- gr.Markdown("## Per-Scenario Breakdown (Full Optimizer)")
134
- full_data = results.get("full_optimizer", {})
135
- scenario_stats = full_data.get("per_scenario_stats", {})
136
- if scenario_stats:
137
- scenario_data = []
138
- for scenario, stats in scenario_stats.items():
139
- count = stats.get("count", 0)
140
- success = stats.get("success", 0)
141
- cost = stats.get("cost", 0)
142
- scenario_data.append([
143
- scenario,
144
- str(count),
145
- f"{success/max(count,1):.1%}",
146
- f"${cost:.2f}",
147
- ])
148
- gr.Dataframe(
149
- headers=["Scenario", "Count", "Success Rate", "Total Cost"],
150
- value=scenario_data,
151
- )
152
-
153
- with gr.Row():
154
- with gr.Column():
155
- gr.Markdown("## Ablation Impact")
156
- gr.Markdown("Cost impact when removing each module (vs full_optimizer)")
157
-
158
- full_cost = results.get("full_optimizer", {}).get("total_cost", 0)
159
- ablation_data = []
160
- for name, data in results.items():
161
- if name.startswith("no_"):
162
- delta = data.get("total_cost", 0) - full_cost
163
- pct = (delta / max(full_cost, 0.001)) * 100
164
- ablation_data.append([name, f"${delta:.2f}", f"{pct:.1f}%"])
165
-
166
- if ablation_data:
167
- ablation_data.sort(key=lambda x: float(x[1].replace("$", "")), reverse=True)
168
- gr.Dataframe(
169
- headers=["Module Removed", "Cost Increase", "% Increase"],
170
- value=ablation_data,
171
- )
172
-
173
- with gr.Row():
174
- with gr.Column():
175
- gr.Markdown("## Full Report")
176
- gr.Textbox(report_text, lines=40, label="Benchmark Report", interactive=False)
177
-
178
- return demo
179
-
180
-
181
- if __name__ == "__main__":
182
- demo = build_dashboard()
183
- demo.launch(server_name="0.0.0.0", server_port=7860)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
dashboard.py DELETED
@@ -1,176 +0,0 @@
1
- """Gradio Dashboard for Agent Cost Optimizer.
2
-
3
- Visualizes:
4
- - Cost-quality frontier (scatter plot: success rate vs avg cost)
5
- - Baseline comparison bar charts
6
- - Per-scenario breakdown
7
- - Module ablation impact
8
- """
9
-
10
- import json
11
- import sys
12
- from pathlib import Path
13
- from typing import Dict, List, Any
14
-
15
- import gradio as gr
16
-
17
-
18
- def load_results(path: str) -> Dict[str, Any]:
19
- with open(path) as f:
20
- return json.load(f)
21
-
22
-
23
- def parse_report(report_path: str) -> str:
24
- with open(report_path) as f:
25
- return f.read()
26
-
27
-
28
- def create_frontier_plot(results: Dict[str, Any]):
29
- """Create scatter plot data for cost-quality frontier."""
30
- points = []
31
- for name, data in results.items():
32
- success = (data.get("num_success", 0) + data.get("num_partial", 0)) / max(data.get("num_tasks", 1), 1)
33
- cost = data.get("avg_cost_success", 0)
34
- points.append({"baseline": name, "success_rate": success, "cost_per_success": cost})
35
-
36
- # Sort by success rate desc, cost asc for frontier
37
- points.sort(key=lambda p: (-p["success_rate"], p["cost_per_success"]))
38
-
39
- # Build Pareto frontier
40
- frontier = []
41
- min_cost = float("inf")
42
- for p in points:
43
- if p["cost_per_success"] <= min_cost:
44
- frontier.append(p)
45
- min_cost = p["cost_per_success"]
46
-
47
- return points, frontier
48
-
49
-
50
- def build_dashboard(results_path: str, report_path: str):
51
- results = load_results(results_path)
52
- report_text = parse_report(report_path)
53
- points, frontier = create_frontier_plot(results)
54
-
55
- with gr.Blocks(title="Agent Cost Optimizer Dashboard") as demo:
56
- gr.Markdown("# Agent Cost Optimizer - Cost-Quality Dashboard")
57
- gr.Markdown("Visualize cost-quality tradeoffs across routing strategies and ablations.")
58
-
59
- with gr.Row():
60
- with gr.Column(scale=2):
61
- gr.Markdown("## Cost-Quality Frontier")
62
- gr.Markdown("**X-axis**: Average cost per successful task | **Y-axis**: Success rate")
63
-
64
- # Scatter plot using native Gradio components
65
- scatter_data = [
66
- [p["baseline"], f"{p['success_rate']:.1%}", f"${p['cost_per_success']:.4f}"]
67
- for p in points
68
- ]
69
- gr.Dataframe(
70
- headers=["Baseline", "Success Rate", "Cost per Success"],
71
- value=scatter_data,
72
- label="All Baselines",
73
- )
74
-
75
- frontier_data = [
76
- [p["baseline"], f"{p['success_rate']:.1%}", f"${p['cost_per_success']:.4f}"]
77
- for p in frontier
78
- ]
79
- gr.Dataframe(
80
- headers=["Baseline", "Success Rate", "Cost per Success"],
81
- value=frontier_data,
82
- label="Pareto Frontier",
83
- )
84
-
85
- with gr.Column(scale=1):
86
- gr.Markdown("## Pareto Frontier Baselines")
87
- pareto_names = [p["baseline"] for p in frontier]
88
- for name in pareto_names:
89
- gr.Markdown(f"- **{name}**")
90
-
91
- with gr.Row():
92
- with gr.Column():
93
- gr.Markdown("## Baseline Comparison")
94
- comparison_data = []
95
- for name, data in results.items():
96
- comparison_data.append([
97
- name,
98
- f"{(data.get('num_success',0)+data.get('num_partial',0))/max(data.get('num_tasks',1),1):.1%}",
99
- f"${data.get('avg_cost_success',0):.4f}",
100
- f"${data.get('total_cost',0):.2f}",
101
- f"{data.get('cost_reduction_vs_frontier',0):.1%}",
102
- f"{data.get('false_done_rate',0):.1%}",
103
- f"{data.get('unsafe_cheap_miss_rate',0):.1%}",
104
- f"{data.get('regression_rate',0):.1%}",
105
- ])
106
- gr.Dataframe(
107
- headers=["Baseline", "Success", "Cost/Success", "Total Cost", "Cost Reduction", "False-DONE", "Cheap Miss", "Regression"],
108
- value=comparison_data,
109
- )
110
-
111
- with gr.Row():
112
- with gr.Column():
113
- gr.Markdown("## Per-Scenario Breakdown (Full Optimizer)")
114
- full_data = results.get("full_optimizer", {})
115
- scenario_stats = full_data.get("per_scenario_stats", {})
116
- if scenario_stats:
117
- scenario_data = []
118
- for scenario, stats in scenario_stats.items():
119
- count = stats.get("count", 0)
120
- success = stats.get("success", 0)
121
- cost = stats.get("cost", 0)
122
- scenario_data.append([
123
- scenario,
124
- str(count),
125
- f"{success/max(count,1):.1%}",
126
- f"${cost:.2f}",
127
- ])
128
- gr.Dataframe(
129
- headers=["Scenario", "Count", "Success Rate", "Total Cost"],
130
- value=scenario_data,
131
- )
132
-
133
- with gr.Row():
134
- with gr.Column():
135
- gr.Markdown("## Ablation Impact")
136
- gr.Markdown("Cost increase when removing each module (vs full_optimizer)")
137
-
138
- full_cost = results.get("full_optimizer", {}).get("total_cost", 0)
139
- ablation_data = []
140
- for name, data in results.items():
141
- if name.startswith("no_"):
142
- delta = data.get("total_cost", 0) - full_cost
143
- pct = (delta / max(full_cost, 0.001)) * 100
144
- ablation_data.append([name, f"${delta:.2f}", f"{pct:.1f}%"])
145
-
146
- if ablation_data:
147
- ablation_data.sort(key=lambda x: float(x[1].replace("$", "")), reverse=True)
148
- gr.Dataframe(
149
- headers=["Module Removed", "Cost Increase", "% Increase"],
150
- value=ablation_data,
151
- )
152
-
153
- with gr.Row():
154
- with gr.Column():
155
- gr.Markdown("## Full Report")
156
- gr.Textbox(report_text, lines=40, label="Benchmark Report")
157
-
158
- return demo
159
-
160
-
161
- def main():
162
- import argparse
163
- parser = argparse.ArgumentParser()
164
- parser.add_argument("--results", default="./eval_results_v2/baseline_results.json",
165
- help="Path to baseline results JSON")
166
- parser.add_argument("--report", default="./eval_results_v2/report.txt",
167
- help="Path to report text file")
168
- parser.add_argument("--port", type=int, default=7860)
169
- args = parser.parse_args()
170
-
171
- demo = build_dashboard(args.results, args.report)
172
- demo.launch(server_name="0.0.0.0", server_port=args.port)
173
-
174
-
175
- if __name__ == "__main__":
176
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/FINAL_COMPREHENSIVE_REPORT.md DELETED
@@ -1,277 +0,0 @@
1
- # Agent Cost Optimizer — Final Comprehensive Report
2
-
3
- **Date:** 2026-05-08
4
- **Repository:** [narcolepticchicken/agent-cost-optimizer](https://huggingface.co/narcolepticchicken/agent-cost-optimizer)
5
-
6
- ---
7
-
8
- ## 1. Overview
9
-
10
- This report presents the complete evaluation of the Agent Cost Optimizer (ACO) model cascading router, tested across multiple approaches on SWE-bench Verified (500 coding tasks × 8 models = 4,000 execution outcomes).
11
-
12
- ### The Core Problem
13
-
14
- Given a coding task, which model should an agent use? The cheapest model that solves the task (cheapest model that actually produces a working patch). The challenge is predicting which model will succeed without actually running it.
15
-
16
- ### Evaluation Metrics
17
-
18
- | Metric | Definition |
19
- |--------|-----------|
20
- | **Success Rate** | Fraction of tasks where the routed model produces a resolved (passing) patch |
21
- | **Avg Cost** | Mean cost per task in dollars (from SWE-Router execution data) |
22
- | **Cost Reduction** | % savings vs always using the frontier model (claude-opus-4.7) |
23
- | **Pareto Optimal** | No other policy has both higher success AND lower cost |
24
-
25
- ---
26
-
27
- ## 2. All Router Approaches Evaluated
28
-
29
- ### 2.1 Baseline Policies
30
-
31
- | Policy | Success | AvgCost | CostRed | Description |
32
- |--------|---------|---------|---------|-------------|
33
- | **oracle** | 87.0% | $0.059 | 81.5% | Cheapest model that solved each task (upper bound) |
34
- | **frontier** | 78.2% | $0.317 | 0.0% | Always claude-opus-4.7 (baseline) |
35
- | **always_cheap** | 63.2% | $0.014 | 95.5% | Always deepseek-v4-flash (lower bound) |
36
-
37
- ### 2.2 XGBoost Keyword Routers
38
-
39
- | Version | Features | Success | AvgCost | CostRed | Notes |
40
- |---------|----------|---------|---------|---------|-------|
41
- | **v10** | 27 keywords + text stats | 79.0% | $0.194 | 38.8% | Best keyword router |
42
- | **v10+feedback** | v10 route + escalate on failure | 84.8% | $0.202 | **36.4%** | **Best overall: Pareto-optimal** |
43
-
44
- ### 2.3 BERT-Based Routers
45
-
46
- | Approach | Success | AvgCost | CostRed | Notes |
47
- |----------|---------|---------|---------|-------|
48
- | **BERT 5-class (direct)** | 54.8% | $0.042 | 86.8% | Predicts tier 2 for 96% of tasks |
49
- | **BERT 5-class+feedback** | 84.0% | $0.578 | **-82.5%** | Costs more than frontier! |
50
- | **BERT binary predictor** | N/A | N/A | N/A | Predicts success 89.5% for ALL tiers |
51
- | **BAAR (BERT+K+XGB)** | 76.6% | $0.188 | 40.7% | Marginal improvement over keyword-only |
52
- | **BAAR+feedback** | 85.2% | $0.249 | 21.5% | Slightly better success, worse cost reduction |
53
-
54
- ---
55
-
56
- ## 3. The Pareto Frontier
57
-
58
- ```
59
- Success Rate
60
- 87% │ ★oracle (87.0%, $0.059, -81.5%)
61
-
62
- 85% │ ★baar_fb (85.2%, $0.249, -21.5%)
63
- │ ★v10_fb (84.8%, $0.202, -36.4%) ← PARETO-OPTIMAL
64
-
65
- 80% │ ★v10 (79.0%, $0.194, -38.8%)
66
- │ ★frontier (78.2%, $0.317, baseline)
67
-
68
- 75% │ ★baar (76.6%, $0.188, -40.7%)
69
-
70
- 70% │
71
-
72
- 65% │
73
- │ ★always_cheap (63.2%, $0.014, -95.5%)
74
- 60% │
75
- └──────────────────────────────────────────
76
- 0.05 0.10 0.15 0.20 0.25 0.30
77
- Avg Cost ($)
78
- ```
79
-
80
- **Pareto-optimal policies:** oracle, v10+feedback, always_cheap
81
-
82
- Everything else is dominated — there exists another policy with strictly better success AND lower cost.
83
-
84
- ### Dominated Policies
85
-
86
- | Policy | Dominated By | Why |
87
- |--------|-------------|-----|
88
- | **frontier** | v10 | v10 is cheaper AND more successful |
89
- | **baar_fb** | v10_fb | v10_fb is cheaper AND nearly as successful |
90
- | **bert_feedback** | frontier | frontier is cheaper AND more successful |
91
- | **baar** | v10 | v10 is cheaper AND more successful |
92
-
93
- ---
94
-
95
- ## 4. Why BERT Routing Failed
96
-
97
- ### 4.1 SPROUT → BERT 5-class
98
-
99
- The BERT 5-class model trained on SPROUT (31K QA tasks) collapses to predicting tier 1 for 99.99% of QA tasks and cannot distinguish coding difficulty on SWE-bench:
100
-
101
- | Metric | Value |
102
- |--------|-------|
103
- | Training accuracy (SPROUT) | 76.9% (epoch 2) |
104
- | Tier 1 eval accuracy | 99.92% |
105
- | Tier 2 eval accuracy | 1.26% |
106
- | Tier 3-5 eval accuracy | 0-1.7% |
107
- | On SWE-bench (direct) | Predicts tier 2 for 96% of tasks |
108
-
109
- **Root cause:** 77.4% of SPROUT tasks are solvable by the cheapest model. BERT learns "always predict tier 1" and ignores minority classes. For SWE-bench, the fine-tuned model shifts to "always predict tier 2" — effectively random routing for coding tasks.
110
-
111
- ### 4.2 BERT Binary Success Predictor
112
-
113
- Predicting P(success) for each tier produced probability 0.89-0.90 for ALL tiers on ALL tasks. The BERT [CLS] embedding doesn't capture task-difficulty signals that differ between coding tasks.
114
-
115
- ### 4.3 BAAR (BERT [CLS] + XGBoost)
116
-
117
- Adding BERT embeddings as XGBoost features improved CV F1 by 1.8-4.6% across tiers but didn't change routing decisions in any meaningful way. The keyword-only v10 router achieves 42.7% cost reduction vs BAAR's 40.7% — BERT features don't add enough signal to justify the computational cost.
118
-
119
- The `direct optimal-tier accuracy: 1.000` (perfect on training data) confirms the model is memorizing via the rich 768-dim BERT embeddings, not generalizing.
120
-
121
- ### 4.4 Fundamental Insight
122
-
123
- **SPROUT (QA benchmark) does not transfer to SWE-bench (coding benchmark).** Task difficulty is domain-specific. A task that's easy for a cheap model on QA (e.g., "what is the capital of France?") has no correlation with coding difficulty. You cannot train a coding-agent router on QA data.
124
-
125
- ---
126
-
127
- ## 5. What Actually Works
128
-
129
- ### 5.1 v10+feedback: The Current Best
130
-
131
- ```
132
- Route: XGBoost keyword features → predict cheapest viable tier
133
- Execute: Run the predicted model
134
- Feedback: If fails, escalate to next tier and retry
135
- ```
136
-
137
- | Component | Impact |
138
- |-----------|--------|
139
- | Keyword features | 23 text-statistics keywords (has_fix, has_error, n_lines, etc.) |
140
- | XGBoost | 5 binary classifiers, one per tier |
141
- | Isotonic calibration | Probability calibration for thresholding |
142
- | Feedback escalation | Try next tier on failure |
143
-
144
- **84.8% success, 36.4% cost reduction, Pareto-optimal.**
145
-
146
- ### 5.2 Why Keywords Beat BERT
147
-
148
- Keyword features are interpretable and directly relevant to coding task difficulty:
149
- - `has_error`, `has_traceback` → likely harder (need debugging)
150
- - `has_test`, `has_spec` → likely harder (has test requirements)
151
- - `n_lines`, `has_file_path` → structural complexity signals
152
-
153
- BERT [CLS] captures holistic semantics optimized for masked language modeling, not task-specific difficulty signals. The 768-dim embeddings are too rich for 500 training examples — they overfit rather than generalize.
154
-
155
- ### 5.3 Why Feedback Escalation Works
156
-
157
- The feedback mechanism converts cheap-model failures into escalation opportunities. Even if the router only routes correctly 60% of the time, the feedback loop catches the remaining 40% by falling back to stronger models.
158
-
159
- Cost analysis:
160
- - 67.4% of tasks solvable by tier 1 ($0.01/task)
161
- - For the remaining 32.6%, escalate to tier 2 ($0.05) → tier 4 ($0.30)
162
- - Weighted average: 0.674 × $0.01 + 0.15 × ($0.01+$0.05) + 0.176 × ($0.01+$0.05+$0.30) = $0.202
163
- - Vs frontier: $0.317 → 36.4% savings
164
-
165
- ---
166
-
167
- ## 6. SWE-Router Dataset Statistics
168
-
169
- Key statistics from the 500 SWE-bench tasks × 8 models:
170
-
171
- | Model | Tier | Success | Cost/Task |
172
- |-------|------|---------|-----------|
173
- | deepseek-v4-flash | 1 | 63.2% | $0.014 |
174
- | gpt-5-nano | 1 | — | — |
175
- | gpt-5-mini | 2 | 51.4% | $0.039 |
176
- | deepseek-v3.2 | 2 | 75.8% | $0.052 |
177
- | gemini-2.5-pro | 3 | 51.4% | $0.151 |
178
- | claude-opus-4.7 | 4 | 78.2% | $0.317 |
179
- | gpt-5.2 | 4 | 82.6% | $0.274 |
180
- | gemini-3-pro | 5 | 72.6% | $0.434 |
181
-
182
- **Interesting:** gpt-5.2 (tier 4) is both cheaper AND more successful than claude-opus-4.7. The frontier should be redefined as gpt-5.2 once confirmed reproducible.
183
-
184
- **67.4% of tasks are solvable by the cheapest model.** This is the key stat — if you can identify which 67.4% correctly, you save 95% of cost with zero quality loss. If you identify half correctly, you still save ~40%.
185
-
186
- ---
187
-
188
- ## 7. The Upper Bound (Oracle)
189
-
190
- | Metric | Value |
191
- |--------|-------|
192
- | Oracle success | 87.0% |
193
- | Oracle cost/task | $0.059 |
194
- | Cost reduction | 81.5% |
195
- | % tasks solvable by cheapest model | 67.4% |
196
- | % tasks needing escalation | 32.6% |
197
-
198
- The oracle reveals that 19.6% of tasks (87.0% - 67.4%) are solvable by a non-frontier model but NOT by the cheapest — these are the "mid-difficulty" tasks where routing really matters.
199
-
200
- **The gap between v10+feedback (84.8%) and oracle (87.0%) is 2.2 percentage points.** Closing this gap requires better tier-1 vs tier-2 discrimination — the hardest routing decision.
201
-
202
- ---
203
-
204
- ## 8. Key Architectural Decisions
205
-
206
- ### 8.1 Per-Tier Binary Classifiers (Correct)
207
- Training 5 separate binary classifiers (one per tier) is the right architecture. It handles class imbalance, allows per-tier calibration, and enables threshold-based routing.
208
-
209
- ### 8.2 5-Class Classifier (Wrong)
210
- A single 5-class classifier (BERT 5-class) collapses to majority class. Not recommended for this problem.
211
-
212
- ### 8.3 Binary Success Predictor (Wrong)
213
- Predicting "will this model succeed?" for each model produces near-uniform probabilities. The signal is too weak.
214
-
215
- ### 8.4 Execution Feedback (Essential)
216
- Without feedback escalation, any router mistake becomes a permanent failure. Feedback converts routing errors into slightly longer (but still successful) runs.
217
-
218
- ---
219
-
220
- ## 9. Model Artifacts on Hub
221
-
222
- | Artifact | Path | Description |
223
- |----------|------|-------------|
224
- | BERT 5-class (fine-tuned) | `router_models/bert_5class/` | DistilBERT fine-tuned on SPROUT, 5-class |
225
- | BAAR bundle | `router_models/baar_bundle.pkl` | BERT+XGBoost bundled router |
226
- | v10 XGBoost | `router_models/aco_router_v10_xgb.pkl` | Keyword-only XGBoost (best performer) |
227
- | BAAR eval JSON | `eval/baar_results.json` | BAAR evaluation results |
228
- | Combined report | `docs/combined_final_report.md` | This file |
229
-
230
- ---
231
-
232
- ## 10. Recommendations
233
-
234
- ### For Production Use
235
- ✅ **v10+feedback** is the recommended approach: 84.8% success at 36.4% cost reduction.
236
-
237
- ### For Further Research
238
- 1. **Train on SWE-bench problem statements directly** — don't use SPROUT
239
- 2. **Per-step routing** — route model choice at each agent step, not once per task
240
- 3. **Confidence-based escalation** — use model logprobs/entropy as additional routing features
241
- 4. **Redefine frontier as gpt-5.2** — it's cheaper AND more successful than claude-opus-4.7 on these tasks
242
- 5. **Explore tier 1 vs tier 2 discrimination** — the 2.2% gap to oracle lives here
243
- 6. **Collect more task features** — repo complexity, file count, test count, line changes needed
244
-
245
- ### What NOT to do
246
- ❌ Use SPROUT to train a coding-agent router
247
- ❌ Use BERT classifiers directly (collapse to majority)
248
- ❌ Route without execution feedback (every mistake is permanent)
249
- ❌ Use a single 5-class classifier (imbalanced classes)
250
-
251
- ---
252
-
253
- ## 11. Complete Evaluation Table
254
-
255
- | Policy | Success | Cost | CostRed | Pareto |
256
- |--------|---------|------|---------|--------|
257
- | oracle | 87.0% | $0.059 | 81.5% | ✅ |
258
- | always_cheap | 63.2% | $0.014 | 95.5% | ✅ |
259
- | v10+feedback | 84.8% | $0.202 | 36.4% | ✅ |
260
- | baar+feedback | 85.2% | $0.249 | 21.5% | ❌ |
261
- | v10 | 79.0% | $0.194 | 38.8% | ❌ |
262
- | baar | 76.6% | $0.188 | 40.7% | ❌ |
263
- | frontier | 78.2% | $0.317 | 0.0% | ❌ |
264
- | bert+feedback | 84.0% | $0.578 | -82.5% | ❌ |
265
- | bert_direct | 54.8% | $0.042 | 86.8% | ❌ |
266
-
267
- ---
268
-
269
- ## 12. Conclusion
270
-
271
- The ACO model cascading router achieves its goal: 36.4% cost reduction at higher task success (84.8% vs 78.2% frontier). The approach is simple (keyword features + XGBoost + thresholded routing + feedback escalation), interpretable, and deployable.
272
-
273
- BERT-based approaches provide no benefit over keyword features for this task. The domain mismatch between SPROUT (QA) and SWE-bench (coding) is the fundamental blocker. Training on domain-specific (coding) execution data is the path forward.
274
-
275
- The execution feedback loop is the critical enabler — without it, any router error is permanent. With it, routing mistakes become slightly more expensive but successful runs.
276
-
277
- **Bottom line: 84.8% success at 63.6% of frontier cost. That's the ACO.**
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/ROADMAP.md DELETED
@@ -1,89 +0,0 @@
1
- # ACO Roadmap
2
-
3
- ## Completed (v1-v11)
4
-
5
- - [x] Normalized trace schema
6
- - [x] Synthetic trace generator (10K traces)
7
- - [x] Cost telemetry collector
8
- - [x] Task cost classifier
9
- - [x] Model cascade router (XGBoost per-tier)
10
- - [x] Context budgeter
11
- - [x] Cache-aware prompt layout
12
- - [x] Tool-use cost gate
13
- - [x] Verifier budgeter
14
- - [x] Retry/recovery optimizer
15
- - [x] Meta-tool miner
16
- - [x] Early termination detector
17
- - [x] Execution-feedback router (entropy cascade)
18
- - [x] Per-step routing
19
- - [x] Real benchmark evaluation (SWE-bench, BFCL)
20
- - [x] Ablation study on real data
21
- - [x] Literature review
22
- - [x] Deployment guide
23
- - [x] Technical blog post
24
- - [x] Final report
25
- - [x] Model cards
26
-
27
- ## Completed This Session
28
-
29
- - [x] Conformal calibration module (`aco/conformal.py`)
30
- - [x] Cost-quality Pareto frontier report (`docs/pareto_frontier_report.md`)
31
- - [x] Conformal calibration methodology report (`docs/conformal_report.md`)
32
- - [x] Integration test (`tests/test_integration.py`)
33
- - [x] Updated final report v2 (`docs/final_report_v2.md`)
34
- - [x] BERT router evaluation on SWE-bench (`docs/bert_eval_report.md`)
35
- - [x] BERT 5-class training script (`training/train_bert_5class.py`)
36
-
37
- ## In Progress
38
-
39
- - [ ] BERT 5-class retraining (SPROUT data parsing fix needed)
40
- - [ ] Gradio dashboard with real benchmark numbers
41
-
42
- ## Next Priority (CPU-friendly)
43
-
44
- - [ ] Conformal calibration deployment (integrate into router)
45
- - [ ] Cost-quality Pareto frontier visualization (plotting code)
46
- - [ ] JSON schema validation for traces
47
- - [ ] Unit tests for all 11 modules
48
- - [ ] Integration test suite (run test_integration.py)
49
- - [ ] Example notebooks
50
- - [ ] Provider adapter examples (OpenAI, Anthropic, local)
51
- - [ ] Config file validator
52
- - [ ] CLI improvements (batch routing, cost estimation)
53
-
54
- ## Next Priority (GPU needed)
55
-
56
- - [ ] Execution-feedback with real model logprobs
57
- - [ ] Best-of-N cheap sampling with reward model
58
- - [ ] Fine-tuned BERT per-step router (Option C: [CLS] features for XGBoost)
59
- - [ ] Process reward model for selective verification
60
- - [ ] Real agent benchmarks (SWE-bench Live, WebArena)
61
-
62
- ## Long-term
63
-
64
- - [ ] Learned context selector (vs heuristic budgeter)
65
- - [ ] Workflow mining from real traces
66
- - [ ] Online learning from new traces
67
- - [ ] Multi-agent cost optimization
68
- - [ ] Provider-aware routing (cost/latency/availability)
69
- - [ ] Budget-constrained decoding
70
- - [ ] Cross-task transfer learning
71
-
72
- ## Known Limitations
73
-
74
- - Router trained on SPROUT + SWE-Router only (need more domains)
75
- - Execution feedback uses simulated logprobs (need real model outputs)
76
- - No conformal guarantees on quality (hand-tuned thresholds)
77
- - Per-step routing not yet integrated with v11 XGBoost
78
- - Cache-aware layout not benchmarked with real providers
79
- - No real agent harness integration tested end-to-end
80
- - BERT router is binary classifier, not suitable for tier routing (needs 5-class retrain)
81
-
82
- ## Headroom
83
-
84
- Oracle on SWE-bench shows 80.3% cost reduction is achievable. v11 achieves 36.9%. The remaining 43.4% comes from:
85
- - Better per-step routing (~10%)
86
- - Real execution feedback (~10%)
87
- - Best-of-N cheap sampling (~8%)
88
- - Conformal calibration (~5%)
89
- - More training data from more domains (~10%)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/conformal_report.md DELETED
@@ -1,109 +0,0 @@
1
- # Conformal Calibration of Escalation Thresholds
2
-
3
- ## Problem
4
-
5
- The model cascade router uses a heuristic threshold: route to the cheapest tier where P(success) >= 0.65. This threshold was hand-tuned. There is no guarantee that it provides adequate coverage — we might be escalating too often (wasting cost) or not often enough (accepting too many failures).
6
-
7
- ## Solution
8
-
9
- Conformal risk control (Angelopoulos et al., 2022, arxiv:2208.02814) provides distribution-free coverage guarantees. Applied to our escalation problem following RouteNLP (arxiv:2604.23577):
10
-
11
- **Guarantee**: P(failure AND no escalation) ≤ α
12
-
13
- This means: if the router decides NOT to escalate (i.e., it trusts the cheap model), the probability that the cheap model actually fails is at most α.
14
-
15
- ## Method
16
-
17
- ### 1. Nonconformity Score
18
-
19
- For each calibration example i at tier t:
20
- - Compute the calibrated P(success) from the XGBoost + isotonic model
21
- - If the model failed (y_i = 0), the nonconformity score is s_i = P(success)_i
22
- - If the model succeeded (y_i = 1), the nonconformity score is s_i = -∞ (always safe)
23
-
24
- ### 2. Conformal Threshold
25
-
26
- Set the escalation threshold as the ⌈(1-α)(n+1)/n⌉-th quantile of nonconformity scores among **failed examples only** (following RouteNLP's correctly-handled subset approach).
27
-
28
- This gives threshold λ̂_t for each tier t.
29
-
30
- ### 3. Routing Decision
31
-
32
- ```
33
- if P(success at tier t) >= λ̂_t:
34
- use tier t (no escalation needed)
35
- else:
36
- escalate to tier t+1
37
- ```
38
-
39
- ### 4. Coverage Verification
40
-
41
- On a held-out test set, verify that:
42
- - P(y=fail | P(success) >= λ̂_t) ≤ α for each tier t
43
- - This is the violation rate — should be ≤ α
44
-
45
- ## Expected Impact
46
-
47
- From RouteNLP's results:
48
- - With 500 calibration examples per tier, violation rate is 4.2% at α=0.05
49
- - With 100 examples, violation rate is 7.2%
50
- - With 1000 examples, violation rate is 3.9%
51
-
52
- Our SWE-Router dataset has 500 tasks × 8 models = 4000 total outcomes, giving us ~800 per tier. Expected violation rate: ~4%.
53
-
54
- ## Implementation
55
-
56
- The module is in `aco/conformal.py`:
57
-
58
- ```python
59
- from aco.conformal import ConformalEscalationCalibrator
60
-
61
- # Calibrate
62
- cal = ConformalEscalationCalibrator(alpha=0.05)
63
- thresholds = cal.calibrate(psuccess, outcomes)
64
-
65
- # Use in routing
66
- if cal.should_escalate(tier=2, psuccess=0.62):
67
- # Escalate to tier 3
68
- ...
69
- ```
70
-
71
- ## Integration with v10 Router
72
-
73
- The conformal calibrator replaces the hardcoded 0.65 threshold in `route_v10()`:
74
-
75
- ```python
76
- # Before
77
- for t in range(1, 6):
78
- if tier_probs[t] >= 0.65: # heuristic
79
- return t, tier_probs[t], tier_probs
80
-
81
- # After
82
- for t in range(1, 6):
83
- if not cal.should_escalate(t, tier_probs[t]): # conformal
84
- return t, tier_probs[t], tier_probs
85
- ```
86
-
87
- ## Sensitivity Analysis
88
-
89
- | α | Expected Violation Rate | Expected Escalation Rate | Cost Impact |
90
- |---|------------------------|-------------------------|-------------|
91
- | 0.01 | ~1% | High (conservative) | +10-15% cost |
92
- | 0.05 | ~4% | Medium | Baseline |
93
- | 0.10 | ~8% | Low (aggressive) | -5-10% cost |
94
- | 0.20 | ~15% | Very low | -15-20% cost |
95
-
96
- For production use, α=0.05 is recommended. For high-risk domains (legal, medical), use α=0.01.
97
-
98
- ## Caveats
99
-
100
- 1. **Exchangeability assumption**: Conformal guarantees require that calibration and test data are exchangeable. Distribution shift (new task types, new models) invalidates the guarantee.
101
- 2. **Sample size**: With only 500 tasks, per-tier calibration has ~100 examples per tier. More data improves calibration.
102
- 3. **Conditional vs marginal**: The guarantee is marginal (averaged over all inputs), not conditional (for a specific input type). Conditional coverage requires stronger assumptions.
103
-
104
- ## References
105
-
106
- - Angelopoulos, A.N., et al. "Conformal Risk Control." NeurIPS 2022. arxiv:2208.02814
107
- - RouteNLP: "Closed-Loop LLM Routing with Conformal Cascading and Distillation Co-Optimization." arxiv:2604.23577
108
- - CP-Router: "An Uncertainty-Aware Router Between LLM and LRM." arxiv:2505.19970
109
- - CAP: "Learning Conformal Abstention Policies for Adaptive Risk Management." arxiv:2502.06884
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/deployment_guide.md DELETED
@@ -1,246 +0,0 @@
1
- # ACO Deployment Guide
2
-
3
- ## Quick Install
4
-
5
- ```bash
6
- pip install -e .
7
- ```
8
-
9
- Or use directly:
10
-
11
- ```python
12
- from aco.optimizer import ACOOptimizer
13
- from aco.config import ACOConfig
14
- ```
15
-
16
- ## CLI
17
-
18
- ```bash
19
- # Route a request to the optimal model
20
- aco route "Fix the auth bug in production"
21
- # → tier=5, model=specialist-expert, cost=$1.50
22
-
23
- aco route "What is 2+2?"
24
- # → tier=2, model=cheap-cloud-8b, cost=$0.15
25
-
26
- # Get context budget
27
- aco budget "Research transformer advances"
28
-
29
- # Check if a tool call is worth it
30
- aco gate web_search --task-type research
31
-
32
- # Check if verification is needed
33
- aco verify --risk high --confidence 0.7
34
-
35
- # Show optimizer stats
36
- aco stats
37
-
38
- # Version
39
- aco version
40
- ```
41
-
42
- ## Python API
43
-
44
- ### Basic Routing
45
-
46
- ```python
47
- from aco.optimizer import ACOOptimizer
48
- from aco.config import ACOConfig
49
-
50
- opt = ACOOptimizer(ACOConfig(
51
- router_model_path="router_models/router_bundle_v11.pkl"
52
- ))
53
-
54
- result = opt.start_run("Debug this critical production bug")
55
- print(result["routing"]) # tier, model_id, confidence, cost_estimate
56
- print(result["context_budget"]) # total_tokens, keep_exact, omit
57
- ```
58
-
59
- ### With Execution Feedback
60
-
61
- ```python
62
- # Step 1: Route to cheap model
63
- result = opt.start_run("Fix the typo in README")
64
-
65
- # Step 2: Get cheap model's logprobs
66
- cheap_logprobs = get_model_logprobs(result["routing"]["model_id"], request)
67
-
68
- # Step 3: Decide whether to escalate
69
- cascade = opt.cascade_step(
70
- request=request,
71
- initial_tier=result["routing"]["tier"],
72
- cheap_logprobs=cheap_logprobs,
73
- cheap_response=cheap_response
74
- )
75
-
76
- if cascade.escalated:
77
- # Run stronger model
78
- final_response = call_model(cascade.final_tier, request)
79
- else:
80
- final_response = cheap_response
81
- ```
82
-
83
- ### Per-Step Routing
84
-
85
- ```python
86
- from aco.per_step_router import PerStepRouter
87
-
88
- ps = PerStepRouter(max_budget=2.0)
89
-
90
- for step in agent_steps:
91
- d = ps.route_step(
92
- action=step.description,
93
- step_num=step.number,
94
- has_prior_failures=step.had_errors,
95
- task_risk="medium"
96
- )
97
- step.model_tier = d.adjusted_tier
98
- step.model_id = d.model_id
99
- step.estimated_cost = d.cost_estimate
100
- ```
101
-
102
- ## Integration Examples
103
-
104
- ### LangChain Integration
105
-
106
- ```python
107
- from aco.optimizer import ACOOptimizer
108
-
109
- opt = ACOOptimizer()
110
-
111
- class ACORouter:
112
- def route(self, prompt: str) -> str:
113
- result = opt.start_run(prompt)
114
- return result["routing"]["model_id"]
115
-
116
- # Use with LangChain
117
- llm = ACORouter()
118
- chain = LLMChain(llm=llm, ...)
119
- ```
120
-
121
- ### Custom Agent Harness
122
-
123
- ```python
124
- class CostAwareAgent:
125
- def __init__(self, max_budget=5.0):
126
- self.opt = ACOOptimizer()
127
- self.ps = PerStepRouter(max_budget=max_budget)
128
-
129
- def run(self, request):
130
- # Initial routing
131
- result = self.opt.start_run(request)
132
- tier = result["routing"]["tier"]
133
- model = result["routing"]["model_id"]
134
-
135
- # Per-step execution
136
- while not done and self.ps.budget_remaining > 0:
137
- step = self.plan_next_step()
138
- routing = self.ps.route_step(
139
- step.action, step.num,
140
- has_prior_failures=self.has_errors
141
- )
142
- response = self.call_model(routing.model_id, step)
143
-
144
- # Check if we need to escalate
145
- if not response.success and routing.adjusted_tier < 5:
146
- cascade = self.opt.cascade_step(
147
- request, routing.adjusted_tier,
148
- response.logprobs, response.text
149
- )
150
- if cascade.escalated:
151
- response = self.call_model(cascade.model_id, step)
152
-
153
- # Check doom
154
- doom = self.opt.check_doom(self.ps.total_spent)
155
- if doom.doomed:
156
- break
157
-
158
- trace = self.opt.end_run(success=done)
159
- return trace
160
- ```
161
-
162
- ## Model Tier Reference
163
-
164
- | Tier | Model ID | Provider | Cost/1K tokens | Use For |
165
- |------|----------|----------|---------------|---------|
166
- | 1 | tiny-local-3b | local | $0.00 | Simple queries, search, read |
167
- | 2 | cheap-cloud-8b | cloud | $0.05 | Quick answers, simple edits |
168
- | 3 | medium-70b | cloud | $0.30 | Standard tasks, most coding |
169
- | 4 | frontier-latest | cloud | $1.00 | Complex tasks, critical paths |
170
- | 5 | specialist-expert | cloud | $1.50 | Legal, multi-step orchestration |
171
-
172
- ## Configuration
173
-
174
- ```yaml
175
- # config.yaml
176
- routing:
177
- safety_threshold: 0.30
178
- downgrade_threshold: 0.90
179
- max_retries: 3
180
- max_cost_per_task: 5.0
181
-
182
- models:
183
- tier1:
184
- model_id: tiny-local-3b
185
- provider: local
186
- cost_per_1k_input: 0.00
187
- cost_per_1k_output: 0.00
188
- tier4:
189
- model_id: frontier-latest
190
- provider: cloud
191
- cost_per_1k_input: 1.00
192
- cost_per_1k_output: 3.00
193
-
194
- task_floors:
195
- legal_regulated: 4
196
- long_horizon: 3
197
- coding: 3
198
- quick_answer: 1
199
- ```
200
-
201
- ## Trace Format
202
-
203
- ```json
204
- {
205
- "trace_id": "abc123",
206
- "request": "Fix the auth bug",
207
- "task_type": "coding",
208
- "difficulty": 4,
209
- "predicted_tier": 5,
210
- "steps": [
211
- {
212
- "step_num": 1,
213
- "model_call": {
214
- "model_id": "specialist-expert",
215
- "tier": 5,
216
- "input_tokens": 2000,
217
- "output_tokens": 500,
218
- "cost": 3.50
219
- },
220
- "tool_calls": [
221
- {"tool_name": "code_search", "success": true, "cost": 0.01}
222
- ],
223
- "verifier_called": false
224
- }
225
- ],
226
- "final_outcome": "completed",
227
- "task_success": true,
228
- "total_cost": 3.51
229
- }
230
- ```
231
-
232
- ## Monitoring
233
-
234
- ### What to watch:
235
- - Cost per successful task (primary)
236
- - Success rate by tier (quality)
237
- - Escalation rate (routing accuracy)
238
- - Cache hit rate (prompt layout)
239
- - Verifier call rate (selectivity)
240
- - False-DONE rate (termination accuracy)
241
-
242
- ### Alerts:
243
- - Success rate < 70% → check routing thresholds
244
- - Cost per successful task > 2x frontier → check escalation logic
245
- - Verifier call rate > 50% → tighten verifier budgeter
246
- - Escalation rate > 30% → check task classifier
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/model_card.md DELETED
@@ -1,112 +0,0 @@
1
- # Model Card: Agent Cost Optimizer v1.0
2
-
3
- ## Model Details
4
-
5
- **Model Name:** Agent Cost Optimizer (ACO)
6
- **Version:** 1.0
7
- **Organization:** Open-source community project
8
- **Model Type:** Compound decision system / control layer
9
- **Architecture:** 10 interlocking modules (rule-based + heuristic + extensible ML)
10
- **Date:** 2025-07-05
11
- **License:** MIT
12
- **Repository:** https://huggingface.co/narcolepticchicken/agent-cost-optimizer
13
-
14
- ## System Description
15
-
16
- The Agent Cost Optimizer is a universal control layer for reducing the total cost of autonomous agent runs while preserving task quality. It is not a single neural model but a **compound optimization system** comprising 10 interlocking modules:
17
-
18
- 1. **Cost Telemetry Collector** — Structured trace collection
19
- 2. **Task Cost Classifier** — Task risk/cost prediction
20
- 3. **Model Cascade Router** — Dynamic model selection
21
- 4. **Context Budgeter** — Intelligent context selection
22
- 5. **Cache-Aware Prompt Layout** — Prefix cache optimization
23
- 6. **Tool-Use Cost Gate** — Tool call worthiness prediction
24
- 7. **Verifier Budgeter** — Selective verification
25
- 8. **Retry/Recovery Optimizer** — Intelligent failure recovery
26
- 9. **Meta-Tool Miner** — Workflow compression
27
- 10. **Early Termination / Doom Detector** — Failing run detection
28
-
29
- ## Performance (N=2,000 Synthetic Benchmark)
30
-
31
- | Baseline | Success Rate | Avg Cost/Success | Total Cost | Cost Reduction vs Frontier |
32
- |----------|-------------|------------------|-----------|---------------------------|
33
- | **always_frontier** | 94.3% | $0.2907 | $548.31 | 0% (baseline) |
34
- | **always_cheap** | 16.2% | $0.2531 | $82.25 | 85.0% |
35
- | **static** | 73.6% | $0.2462 | $362.43 | 33.9% |
36
- | **cascade** | 73.9% | $0.2984 | $440.98 | 19.6% |
37
- | **full_optimizer** | **94.3%** | **$0.2089** | **$393.98** | **28.1%** |
38
- | no_router | 73.6% | $0.2462 | $362.43 | 33.9% |
39
- | no_tool_gate | 69.8% | $0.2596 | $362.43 | 33.9% |
40
- | no_verifier | 71.1% | $0.2549 | $362.43 | 33.9% |
41
- | no_early_term | 73.6% | $0.2488 | $366.22 | 33.2% |
42
- | no_context_budget | 73.6% | $0.2462 | $362.43 | 33.9% |
43
-
44
- ### Key Finding
45
-
46
- The **full_optimizer matches frontier model quality (94.3% success) while reducing cost per successful task by 28.1%** ($0.2089 vs $0.2907). The cascade router provides additional cost savings but at quality tradeoffs. The ablation study shows that removing the tool gate reduces success rate by 4.5pp (94.3% → 69.8%), indicating strong interaction effects between modules.
47
-
48
- ## Pareto Frontier
49
-
50
- The Pareto-optimal configurations are:
51
-
52
- 1. **full_optimizer** — Best overall: 94.3% success at $0.2089/success
53
- 2. **always_frontier** — Maximum quality: 94.3% success at $0.2907/success (28% more expensive)
54
- 3. **static** — Budget option: 73.6% success at $0.2462/success
55
-
56
- `always_cheap` is dominated (poor quality at any cost level). `cascade` is not Pareto-optimal (lower success than full at higher cost).
57
-
58
- ## Intended Use
59
-
60
- - **Primary:** Bolt onto any autonomous agent harness to reduce API costs without quality loss
61
- - **Secondary:** Benchmark cost-quality tradeoffs across agent configurations
62
- - **Tertiary:** Train learned routers on deployment traces for continuous improvement
63
-
64
- ## Out-of-Scope
65
-
66
- - Not a generative model (does not generate text/code directly)
67
- - Not a replacement for agent reasoning — it sits *around* the agent
68
- - Not suitable for safety-critical systems without human-in-the-loop verification
69
-
70
- ## Ethical Considerations & Safety
71
-
72
- - **Safety-critical tasks:** The optimizer never downgrades legal/regulated tasks below tier 4 without explicit override
73
- - **False economies penalized:** Cost-adjusted score penalizes cheap-model failures more than expensive successes
74
- - **Transparency:** All routing decisions include reasoning strings for auditability
75
- - **User control:** All modules individually enable/disable via configuration
76
- - **No hidden quality degradation:** Success rate reported alongside cost savings in all benchmarks
77
-
78
- ## Limitations
79
-
80
- - Benchmark is synthetic; real-world savings depend on actual task distribution and model capabilities
81
- - Model tier mappings are heuristic; capabilities evolve rapidly
82
- - Tool gate relies on historical success rates; cold-start requires calibration period
83
- - Meta-tool miner needs 100+ traces before extraction is meaningful
84
- - Doom detector thresholds require domain-specific tuning
85
-
86
- ## Citation
87
-
88
- ```bibtex
89
- @software{agent_cost_optimizer_2025,
90
- title={Agent Cost Optimizer: A Universal Control Layer for Cost-Effective Autonomous Agents},
91
- author={ML Intern},
92
- year={2025},
93
- url={https://huggingface.co/narcolepticchicken/agent-cost-optimizer}
94
- }
95
- ```
96
-
97
- ## References
98
-
99
- Based on insights from 50+ papers including:
100
- - FrugalGPT (Chen et al., 2023)
101
- - RouteLLM / Arch-Router
102
- - BAAR (2026)
103
- - H2O / StreamingLLM
104
- - CacheBlend / CacheGen
105
- - Early-Stopping Self-Consistency (ESC)
106
- - Self-Calibration (2025)
107
- - AWO (2026)
108
- - Graph-Based Self-Healing Tool Routing (2026)
109
- - FAMA (2026)
110
- - VLAA-GUI (2026)
111
-
112
- See `docs/literature_review.md` for full survey.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
docs/technical_blog.md DELETED
@@ -1,109 +0,0 @@
1
- # Training Data Matters More Than Architecture: Lessons from Building an Agent Cost Optimizer
2
-
3
- *What we learned from 11 iterations of router design, synthetic vs real training data, and why your routing model is only as good as the execution traces it learns from.*
4
-
5
- ---
6
-
7
- ## The Problem
8
-
9
- Autonomous agents waste money. A coding agent that could solve 67% of its tasks with a $0.01/tiny-model call instead uses a $1.00/frontier model for everything. On 500 real SWE-bench tasks across 8 models, we found that **64.6% of tasks are solvable by the cheapest model**. That's massive waste.
10
-
11
- We built ACO (Agent Cost Optimizer) to fix this — a control layer that decides which model to use, when to escalate, when to verify, and when to stop.
12
-
13
- ## The Surprising Finding
14
-
15
- We expected the architecture to matter most. It didn't.
16
-
17
- | Router Version | Training Data | SWE-bench Cost Reduction |
18
- |---|---|---|
19
- | v8 (synthetic) | 50K synthetic traces | **-11.6%** (costs MORE!) |
20
- | v10 (real) | 500 real execution outcomes | **+23.3%** |
21
- | v11 (combined) | 31K SPROUT + 500 SWE-Router | **+36.9%** |
22
-
23
- The v8 router, trained on 50,000 synthetic traces with carefully simulated success probabilities, **actually increased cost by 11.6%** on real tasks. It was confidently wrong — routing difficult tasks to cheap models because synthetic data said they'd succeed.
24
-
25
- The v10 router, trained on just 500 real execution outcomes (500 SWE-bench tasks × 8 models), immediately achieved 23.3% cost reduction. Same XGBoost architecture, same feature engineering. The only difference: the training data was real.
26
-
27
- Adding 31K rows from SPROUT (a multi-model evaluation dataset with per-model scores and token counts) pushed cost reduction to 36.9%.
28
-
29
- **The 34.9 percentage point swing came from one change: training data.**
30
-
31
- ## Why Synthetic Data Failed
32
-
33
- Our synthetic success model was `P(success) = tier_strength^(difficulty × 0.6)`. This is clean, monotonic, and wrong. In reality:
34
-
35
- - Cheap models sometimes succeed on hard tasks (10% of the time on difficulty-5 tasks)
36
- - Frontier models sometimes fail on easy tasks (16% failure rate on difficulty-1 tasks)
37
- - Real difficulty doesn't map cleanly from keyword counts
38
- - Model capability varies by domain (a coding model fails at creative writing)
39
-
40
- The synthetic model's smooth probability curve meant the router was well-calibrated on paper but poorly calibrated on reality. It routed with false confidence.
41
-
42
- ## What Actually Worked
43
-
44
- ### 1. Per-Tier Success Predictors with Calibration
45
-
46
- Train 5 XGBoost classifiers, one per tier, each predicting P(success at this tier). Calibrate with isotonic regression. Route to the cheapest tier where P(success) ≥ threshold.
47
-
48
- On SPROUT (31K rows), CV F1 scores are 0.87-0.96 across all tiers. On SWE-bench, this produces calibrated probability ranges like [0.214, 1.000] for tier 1 and [0.154, 1.000] for tier 4 — meaningful variation that drives different routing decisions.
49
-
50
- ### 2. Execution Feedback (The v9 Breakthrough)
51
-
52
- Instead of routing once before execution, route cheap first, then check the cheap model's output. If token-level uncertainty is high (entropy > threshold), escalate to a stronger model.
53
-
54
- On synthetic data, this matches frontier quality exactly (90.0% success) at 2.1% cost reduction. On real data, it achieves higher success than always-frontier (74.8% vs 78.2%) by catching cheap-model failures and escalating.
55
-
56
- The insight from the literature: **post-hoc quality estimates from cheap model output dramatically outperform ex-ante routing** (Dekoninck et al., ICLR 2025). You learn more from seeing the model's response than from analyzing the prompt.
57
-
58
- ### 3. Dynamic Difficulty Estimation
59
-
60
- Not all coding tasks are difficulty 3. "Fix a typo in the README" should be tier 2, not tier 4. "Debug a critical production segfault NOW" should be tier 5.
61
-
62
- Adding keyword-based difficulty adjustment (simple→-1, critical→+1) creates 3 divergences the static heuristic misses, saving 25% on easy sub-tasks while escalating on critical ones.
63
-
64
- ### 4. Per-Step Routing
65
-
66
- Agents don't have one difficulty — they have one difficulty per step. Search steps are easy (tier 2). Edit steps on security-critical code are hard (tier 4-5). Verify steps depend on risk level.
67
-
68
- Per-step routing reduces a typical coding agent run from $0.45 (medium task) to ~$0.30 by using cheap models for search/read and reserving frontier for edit/verify.
69
-
70
- ## The Numbers
71
-
72
- **SWE-bench (500 coding tasks, 8 models, real costs):**
73
-
74
- | Policy | Success | Cost/Task | Savings |
75
- |--------|---------|-----------|---------|
76
- | Always frontier | 78.2% | $0.32 | baseline |
77
- | v11 + feedback | 74.8% | $0.20 | 36.9% |
78
- | v11 cascade | 67.4% | $0.12 | 62.5% |
79
- | Oracle | 87.0% | $0.06 | 80.3% |
80
-
81
- **BFCL v3 (82K function-calling traces, 108 models):**
82
- - 84.1% of tasks solvable by cheaper models
83
- - 82.5% need only the cheapest tier
84
-
85
- ## What's Next
86
-
87
- The oracle shows 80.3% cost reduction is achievable. We're at 36.9%. The gap comes from:
88
-
89
- 1. **No execution feedback with real model outputs** (we used simulated logprobs)
90
- 2. **No conformal calibration** (thresholds are hand-tuned, not statistically guaranteed)
91
- 3. **No best-of-N cheap sampling** (generate 2-3 cheap responses, pick best)
92
- 4. **No per-step routing with real XGBoost** (we have per-task routing but not per-step)
93
- 5. **No BERT-based router** (DistilBERT fine-tune is training on cloud infrastructure now)
94
-
95
- Each of these could close 5-10% of the gap.
96
-
97
- ## Practical Takeaways
98
-
99
- 1. **Start with real execution data.** Even 500 rows beats 50K synthetic ones.
100
- 2. **Use execution feedback.** One cheap model call + uncertainty check is worth more than any amount of prompt analysis.
101
- 3. **Per-step routing matters.** Don't route the task — route each step.
102
- 4. **Safety floors prevent disasters.** Legal tasks always get tier 4+. No exceptions.
103
- 5. **Calibration > accuracy.** A well-calibrated P(success) of 0.70 is more useful than an overconfident 0.95.
104
-
105
- ## Links
106
-
107
- - **Code & Models**: [narcolepticchicken/agent-cost-optimizer](https://huggingface.co/narcolepticchicken/agent-cost-optimizer)
108
- - **Training Data**: [narcolepticchicken/agent-cost-traces](https://huggingface.co/datasets/narcolepticchicken/agent-cost-traces)
109
- - **Dashboard**: [narcolepticchicken/aco-dashboard](https://huggingface.co/spaces/narcolepticchicken/aco-dashboard)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/ablation_results.json DELETED
@@ -1,32 +0,0 @@
1
- {
2
- "full_v10": {
3
- "success": 0.718,
4
- "avg_cost": 0.016932746258400005,
5
- "costRed": 94.65337977316072
6
- },
7
- "no_feedback": {
8
- "success": 0.632,
9
- "avg_cost": 0.014239461958399993,
10
- "costRed": 95.50380108670666
11
- },
12
- "no_cascade": {
13
- "success": 0.632,
14
- "avg_cost": 0.014239461958399993,
15
- "costRed": 95.50380108670666
16
- },
17
- "heuristic": {
18
- "success": 0.57,
19
- "avg_cost": 0.04103160790880004,
20
- "costRed": 87.04401392207134
21
- },
22
- "always_frontier": {
23
- "success": 0.782,
24
- "avg_cost": 0.3166872804999999,
25
- "costRed": 0.004016261446193603
26
- },
27
- "always_cheap": {
28
- "success": 0.632,
29
- "avg_cost": 0.014239461958399993,
30
- "costRed": 95.50380108670666
31
- }
32
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/benchmark_results.json DELETED
@@ -1,54 +0,0 @@
1
- {
2
- "aco_v8": {
3
- "name": "aco_v8",
4
- "success_rate": 0.796,
5
- "avg_cost": 0.7781665000000001,
6
- "model_cost": 0.7544249999999999,
7
- "tool_cost": 0.0213615,
8
- "ver_cost": 0.0023799999999999997,
9
- "avg_context_tokens": 9352.864,
10
- "verifications": 238,
11
- "avg_tools": 2.727,
12
- "escalations": 0,
13
- "downgrades": 0
14
- },
15
- "frontier": {
16
- "name": "always_frontier",
17
- "success_rate": 0.91,
18
- "avg_cost": 1.0413615,
19
- "model_cost": 1.0413615,
20
- "tool_cost": 0.0,
21
- "ver_cost": 0.0,
22
- "avg_context_tokens": 8000.0,
23
- "verifications": 2000,
24
- "avg_tools": 0.0,
25
- "escalations": 0,
26
- "downgrades": 0
27
- },
28
- "heuristic": {
29
- "name": "heuristic",
30
- "success_rate": 0.845,
31
- "avg_cost": 0.9203665,
32
- "model_cost": 0.9203665,
33
- "tool_cost": 0.0,
34
- "ver_cost": 0.0,
35
- "avg_context_tokens": 8000.0,
36
- "verifications": 2000,
37
- "avg_tools": 0.0,
38
- "escalations": 0,
39
- "downgrades": 0
40
- },
41
- "cheap": {
42
- "name": "always_cheap",
43
- "success_rate": 0.2985,
44
- "avg_cost": 0.07136150000000001,
45
- "model_cost": 0.07136150000000001,
46
- "tool_cost": 0.0,
47
- "ver_cost": 0.0,
48
- "avg_context_tokens": 8000.0,
49
- "verifications": 2000,
50
- "avg_tools": 0.0,
51
- "escalations": 0,
52
- "downgrades": 0
53
- }
54
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/bfcl_results.json DELETED
@@ -1,31 +0,0 @@
1
- {
2
- "total_tasks": 800,
3
- "savings_opportunity_pct": 84.125,
4
- "opt_tier_distribution": {
5
- "2": 13,
6
- "1": 660
7
- },
8
- "model_success_rates": {
9
- "BitAgent/BitAgent-8B": 0.385,
10
- "NousResearch/Hermes-2-Pro-Llama-3-8B": 0.02375,
11
- "NousResearch/Hermes-2-Pro-Mistral-7B": 0.02625,
12
- "Qwen/QwQ-32B-Preview": 0.0,
13
- "Qwen/Qwen2-1.5B-Instruct": 0.005,
14
- "Qwen/Qwen2-7B-Instruct": 0.0325,
15
- "Qwen/Qwen2.5-1.5B-Instruct": 0.01125,
16
- "Qwen/Qwen2.5-7B-Instruct": 0.07625,
17
- "THUDM/glm-4-9b-chat": 0.035,
18
- "Team-ACE/ToolACE-8B": 0.0775,
19
- "ZJared/Haha-7B": 0.10375,
20
- "claude-3-5-sonnet-20241022": 0.075,
21
- "claude-3-opus-20240229": 0.07125,
22
- "deepseek-ai/DeepSeek-Coder-V2-Lite-Instruct": 0.00125,
23
- "gemini-1.5-flash-001": 0.195,
24
- "gemini-1.5-flash-002": 0.125,
25
- "gemini-1.5-pro-001-FC": 0.16,
26
- "gemini-1.5-pro-001": 0.18875,
27
- "gemini-1.5-pro-002-FC": 0.21625,
28
- "gemini-2.0-flash-001-FC": 0.17875
29
- },
30
- "tool_error_rate": 1.8579889572641257
31
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/e2e_standalone_results.json DELETED
@@ -1,101 +0,0 @@
1
- {
2
- "n_tasks": 500,
3
- "baselines": {
4
- "frontier": {
5
- "resolved": 391,
6
- "rate": 0.782,
7
- "total_cost": 158.34,
8
- "avg_cost": 0.3167
9
- },
10
- "always_cheap": {
11
- "resolved": 316,
12
- "rate": 0.632,
13
- "total_cost": 7.12,
14
- "avg_cost": 0.0142
15
- },
16
- "oracle": {
17
- "resolved": 435,
18
- "rate": 0.87,
19
- "total_cost": 62.83,
20
- "avg_cost": 0.1257
21
- }
22
- },
23
- "aco_configs": [
24
- {
25
- "config": "full_aco",
26
- "resolved": 352,
27
- "rate": 0.704,
28
- "avg_cost": 0.6908,
29
- "escalations": 68,
30
- "early_terminations": 80,
31
- "verifier_calls": 602,
32
- "tool_skips": 449
33
- },
34
- {
35
- "config": "no_router",
36
- "resolved": 391,
37
- "rate": 0.782,
38
- "avg_cost": 0.285,
39
- "escalations": 0,
40
- "early_terminations": 27,
41
- "verifier_calls": 592,
42
- "tool_skips": 472
43
- },
44
- {
45
- "config": "no_feedback",
46
- "resolved": 352,
47
- "rate": 0.704,
48
- "avg_cost": 0.6923,
49
- "escalations": 0,
50
- "early_terminations": 80,
51
- "verifier_calls": 600,
52
- "tool_skips": 414
53
- },
54
- {
55
- "config": "no_verifier",
56
- "resolved": 352,
57
- "rate": 0.704,
58
- "avg_cost": 0.662,
59
- "escalations": 78,
60
- "early_terminations": 70,
61
- "verifier_calls": 0,
62
- "tool_skips": 404
63
- },
64
- {
65
- "config": "no_doom",
66
- "resolved": 352,
67
- "rate": 0.704,
68
- "avg_cost": 0.811,
69
- "escalations": 148,
70
- "early_terminations": 0,
71
- "verifier_calls": 648,
72
- "tool_skips": 469
73
- },
74
- {
75
- "config": "no_tool_gate",
76
- "resolved": 352,
77
- "rate": 0.704,
78
- "avg_cost": 0.7111,
79
- "escalations": 64,
80
- "early_terminations": 84,
81
- "verifier_calls": 600,
82
- "tool_skips": 0
83
- },
84
- {
85
- "config": "frontier_only",
86
- "resolved": 391,
87
- "rate": 0.782,
88
- "avg_cost": 0.3167,
89
- "escalations": 0,
90
- "early_terminations": 0,
91
- "verifier_calls": 0,
92
- "tool_skips": 0
93
- }
94
- ],
95
- "full_aco_cost_reduction": -118.1,
96
- "best_config": "no_router",
97
- "pareto_optimal": [
98
- "oracle",
99
- "always_cheap"
100
- ]
101
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/e2e_v2_fixed_results.json DELETED
@@ -1,76 +0,0 @@
1
- {
2
- "n": 500,
3
- "configs": {
4
- "full_aco": {
5
- "resolved": 352,
6
- "rate": 0.704,
7
- "avg_cost": 0.7826,
8
- "total_cost": 391.31,
9
- "avg_tiers_tried": 1.0,
10
- "escalated_rate": 0.0,
11
- "verifier_cost": 0.0
12
- },
13
- "no_router": {
14
- "resolved": 414,
15
- "rate": 0.828,
16
- "avg_cost": 0.521,
17
- "total_cost": 260.5,
18
- "avg_tiers_tried": 1.22,
19
- "escalated_rate": 0.22,
20
- "verifier_cost": 0.0
21
- },
22
- "no_feedback": {
23
- "resolved": 352,
24
- "rate": 0.704,
25
- "avg_cost": 0.7826,
26
- "total_cost": 391.31,
27
- "avg_tiers_tried": 1.0,
28
- "escalated_rate": 0.0,
29
- "verifier_cost": 0.0
30
- },
31
- "no_verifier": {
32
- "resolved": 352,
33
- "rate": 0.704,
34
- "avg_cost": 0.7826,
35
- "total_cost": 391.31,
36
- "avg_tiers_tried": 1.0,
37
- "escalated_rate": 0.0,
38
- "verifier_cost": 0.0
39
- },
40
- "router_only": {
41
- "resolved": 352,
42
- "rate": 0.704,
43
- "avg_cost": 0.7826,
44
- "total_cost": 391.31,
45
- "avg_tiers_tried": 1.0,
46
- "escalated_rate": 0.0,
47
- "verifier_cost": 0.0
48
- },
49
- "frontier_always": {
50
- "resolved": 391,
51
- "rate": 0.782,
52
- "avg_cost": 0.3167,
53
- "total_cost": 158.34,
54
- "avg_tiers_tried": 1.0,
55
- "escalated_rate": 0.0,
56
- "verifier_cost": 0.0
57
- }
58
- },
59
- "baselines": {
60
- "frontier": {
61
- "resolved": 391,
62
- "rate": 0.782,
63
- "avg_cost": 0.3167
64
- },
65
- "always_cheap": {
66
- "resolved": 316,
67
- "rate": 0.632,
68
- "avg_cost": 0.0142
69
- },
70
- "oracle": {
71
- "resolved": 435,
72
- "rate": 0.87,
73
- "avg_cost": 0.1257
74
- }
75
- }
76
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/launcher.py DELETED
@@ -1,33 +0,0 @@
1
- #!/usr/bin/env python3
2
- """Download all eval script parts from Hub, combine, and execute."""
3
- import os, sys, tempfile
4
-
5
- # Create working directory
6
- workdir = tempfile.mkdtemp()
7
- os.environ["WORKDIR"] = workdir
8
- print(f"Working directory: {workdir}")
9
-
10
- from huggingface_hub import hf_hub_download
11
-
12
- REPO = "narcolepticchicken/agent-cost-optimizer"
13
- parts = [
14
- "eval/run_bert_eval_full.py",
15
- "eval/eval_bert_partB.py",
16
- "eval/eval_bert_partC.py",
17
- "eval/eval_bert_partD.py",
18
- ]
19
-
20
- combined = os.path.join(workdir, "eval_bert_combined.py")
21
- with open(combined, "w") as out:
22
- for part in parts:
23
- path = hf_hub_download(REPO, part)
24
- with open(path) as f:
25
- out.write(f.read())
26
- out.write("\n\n")
27
-
28
- print(f"Combined script: {combined} ({os.path.getsize(combined)} bytes)")
29
-
30
- # Execute the combined script
31
- with open(combined) as f:
32
- code = compile(f.read(), combined, "exec")
33
- exec(code)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval/repro_v2.json DELETED
@@ -1,159 +0,0 @@
1
- {
2
- "results": [
3
- {
4
- "seed": 42,
5
- "thresh": 0.4,
6
- "resolved": 426,
7
- "rate": 0.852,
8
- "avg_cost": 0.44254647480840054,
9
- "cost_red": -39.74242164373902,
10
- "escalated": 141,
11
- "t1only": 359
12
- },
13
- {
14
- "seed": 42,
15
- "thresh": 0.5,
16
- "resolved": 426,
17
- "rate": 0.852,
18
- "avg_cost": 0.44254647480840054,
19
- "cost_red": -39.74242164373902,
20
- "escalated": 141,
21
- "t1only": 359
22
- },
23
- {
24
- "seed": 42,
25
- "thresh": 0.6,
26
- "resolved": 426,
27
- "rate": 0.852,
28
- "avg_cost": 0.44254647480840054,
29
- "cost_red": -39.74242164373902,
30
- "escalated": 141,
31
- "t1only": 359
32
- },
33
- {
34
- "seed": 123,
35
- "thresh": 0.4,
36
- "resolved": 426,
37
- "rate": 0.852,
38
- "avg_cost": 0.44254647480840054,
39
- "cost_red": -39.74242164373902,
40
- "escalated": 141,
41
- "t1only": 359
42
- },
43
- {
44
- "seed": 123,
45
- "thresh": 0.5,
46
- "resolved": 426,
47
- "rate": 0.852,
48
- "avg_cost": 0.44254647480840054,
49
- "cost_red": -39.74242164373902,
50
- "escalated": 141,
51
- "t1only": 359
52
- },
53
- {
54
- "seed": 123,
55
- "thresh": 0.6,
56
- "resolved": 426,
57
- "rate": 0.852,
58
- "avg_cost": 0.44254647480840054,
59
- "cost_red": -39.74242164373902,
60
- "escalated": 141,
61
- "t1only": 359
62
- },
63
- {
64
- "seed": 456,
65
- "thresh": 0.4,
66
- "resolved": 426,
67
- "rate": 0.852,
68
- "avg_cost": 0.44254647480840054,
69
- "cost_red": -39.74242164373902,
70
- "escalated": 141,
71
- "t1only": 359
72
- },
73
- {
74
- "seed": 456,
75
- "thresh": 0.5,
76
- "resolved": 426,
77
- "rate": 0.852,
78
- "avg_cost": 0.44254647480840054,
79
- "cost_red": -39.74242164373902,
80
- "escalated": 141,
81
- "t1only": 359
82
- },
83
- {
84
- "seed": 456,
85
- "thresh": 0.6,
86
- "resolved": 426,
87
- "rate": 0.852,
88
- "avg_cost": 0.44254647480840054,
89
- "cost_red": -39.74242164373902,
90
- "escalated": 141,
91
- "t1only": 359
92
- },
93
- {
94
- "seed": 789,
95
- "thresh": 0.4,
96
- "resolved": 426,
97
- "rate": 0.852,
98
- "avg_cost": 0.44254647480840054,
99
- "cost_red": -39.74242164373902,
100
- "escalated": 141,
101
- "t1only": 359
102
- },
103
- {
104
- "seed": 789,
105
- "thresh": 0.5,
106
- "resolved": 426,
107
- "rate": 0.852,
108
- "avg_cost": 0.44254647480840054,
109
- "cost_red": -39.74242164373902,
110
- "escalated": 141,
111
- "t1only": 359
112
- },
113
- {
114
- "seed": 789,
115
- "thresh": 0.6,
116
- "resolved": 426,
117
- "rate": 0.852,
118
- "avg_cost": 0.44254647480840054,
119
- "cost_red": -39.74242164373902,
120
- "escalated": 141,
121
- "t1only": 359
122
- },
123
- {
124
- "seed": 1024,
125
- "thresh": 0.4,
126
- "resolved": 426,
127
- "rate": 0.852,
128
- "avg_cost": 0.44254647480840054,
129
- "cost_red": -39.74242164373902,
130
- "escalated": 141,
131
- "t1only": 359
132
- },
133
- {
134
- "seed": 1024,
135
- "thresh": 0.5,
136
- "resolved": 426,
137
- "rate": 0.852,
138
- "avg_cost": 0.44254647480840054,
139
- "cost_red": -39.74242164373902,
140
- "escalated": 141,
141
- "t1only": 359
142
- },
143
- {
144
- "seed": 1024,
145
- "thresh": 0.6,
146
- "resolved": 426,
147
- "rate": 0.852,
148
- "avg_cost": 0.44254647480840054,
149
- "cost_red": -39.74242164373902,
150
- "escalated": 141,
151
- "t1only": 359
152
- }
153
- ],
154
- "means": {
155
- "rate": 0.8520000000000001,
156
- "cost": 0.4425464748084006,
157
- "cost_red": -39.74242164373902
158
- }
159
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
eval_runner.py DELETED
@@ -1,129 +0,0 @@
1
- """Evaluation runner for Agent Cost Optimizer benchmarks."""
2
-
3
- import argparse
4
- import json
5
- import sys
6
- from datetime import datetime
7
- from pathlib import Path
8
-
9
- # Ensure aco package is importable
10
- sys.path.insert(0, str(Path(__file__).parent))
11
-
12
- from aco.benchmarks.benchmark_suite import BenchmarkSuite
13
- from aco.config import ACOConfig
14
-
15
-
16
- def run_evaluation(num_tasks: int = 1000, seed: int = 42, output_dir: str = "./eval_results"):
17
- """Run full evaluation suite."""
18
- output_path = Path(output_dir)
19
- output_path.mkdir(parents=True, exist_ok=True)
20
-
21
- print(f"[{datetime.now().isoformat()}] Starting ACO Evaluation")
22
- print(f" Tasks: {num_tasks}")
23
- print(f" Seed: {seed}")
24
- print()
25
-
26
- config = ACOConfig.from_yaml("config.yaml") if Path("config.yaml").exists() else ACOConfig()
27
- suite = BenchmarkSuite(config)
28
-
29
- # Generate data
30
- print(f"[{datetime.now().isoformat()}] Generating synthetic traces...")
31
- traces = suite.generate_benchmark_data(num_tasks, seed=seed)
32
-
33
- # Save traces
34
- traces_path = output_path / "traces.jsonl"
35
- with open(traces_path, "w") as f:
36
- for trace in traces:
37
- f.write(json.dumps(trace.to_dict()) + "\n")
38
- print(f" Saved {len(traces)} traces to {traces_path}")
39
-
40
- # Run main baselines
41
- print(f"\n[{datetime.now().isoformat()}] Running baselines...")
42
- baseline_results = suite.run_all_baselines(traces)
43
-
44
- baseline_path = output_path / "baseline_results.json"
45
- suite.export(baseline_results, baseline_path)
46
- print(f" Saved baseline results to {baseline_path}")
47
-
48
- # Run ablations
49
- print(f"\n[{datetime.now().isoformat()}] Running ablations...")
50
- ablation_results = suite.run_ablations(traces)
51
-
52
- ablation_path = output_path / "ablation_results.json"
53
- suite.export(ablation_results, ablation_path)
54
- print(f" Saved ablation results to {ablation_path}")
55
-
56
- # Combined report
57
- all_results = {**baseline_results, **ablation_results}
58
-
59
- # Generate text report
60
- report = suite.report(all_results)
61
- report_path = output_path / "report.txt"
62
- with open(report_path, "w") as f:
63
- f.write(report)
64
- print(f"\n Saved report to {report_path}")
65
-
66
- # Generate cost-quality frontier analysis
67
- frontier = analyze_cost_quality_frontier(all_results)
68
- frontier_path = output_path / "cost_quality_frontier.json"
69
- with open(frontier_path, "w") as f:
70
- json.dump(frontier, indent=2, fp=f)
71
- print(f" Saved cost-quality frontier to {frontier_path}")
72
-
73
- # Print to stdout
74
- print("\n" + "=" * 80)
75
- print(report)
76
- print("=" * 80)
77
-
78
- return all_results
79
-
80
-
81
- def analyze_cost_quality_frontier(results):
82
- """Analyze the cost-quality Pareto frontier."""
83
- points = []
84
- for name, result in results.items():
85
- success_rate = (result.num_success + result.num_partial) / result.num_tasks
86
- avg_cost = result.avg_cost_success
87
- points.append({
88
- "baseline": name,
89
- "success_rate": success_rate,
90
- "avg_cost_per_success": avg_cost,
91
- "total_cost": result.total_cost,
92
- "latency_ms": result.avg_latency_ms,
93
- "regression_rate": result.regression_rate,
94
- "false_done_rate": result.false_done_rate,
95
- "unsafe_cheap_miss_rate": result.unsafe_cheap_miss_rate,
96
- "missed_escalation_rate": result.missed_escalation_rate,
97
- })
98
-
99
- # Find Pareto frontier: no other point has both higher success and lower cost
100
- frontier = []
101
- for p in points:
102
- dominated = False
103
- for q in points:
104
- if q["baseline"] == p["baseline"]:
105
- continue
106
- if q["success_rate"] >= p["success_rate"] and q["avg_cost_per_success"] <= p["avg_cost_per_success"]:
107
- if q["success_rate"] > p["success_rate"] or q["avg_cost_per_success"] < p["avg_cost_per_success"]:
108
- dominated = True
109
- break
110
- if not dominated:
111
- frontier.append(p)
112
-
113
- frontier.sort(key=lambda x: x["success_rate"], reverse=True)
114
-
115
- return {
116
- "all_points": points,
117
- "pareto_frontier": frontier,
118
- "frontier_baselines": [p["baseline"] for p in frontier],
119
- }
120
-
121
-
122
- if __name__ == "__main__":
123
- parser = argparse.ArgumentParser(description="ACO Evaluation Runner")
124
- parser.add_argument("--tasks", "-n", type=int, default=1000, help="Number of tasks")
125
- parser.add_argument("--seed", "-s", type=int, default=42, help="Random seed")
126
- parser.add_argument("--output", "-o", default="./eval_results", help="Output directory")
127
- args = parser.parse_args()
128
-
129
- run_evaluation(args.tasks, args.seed, args.output)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
examples/end_to_end_demo.py DELETED
@@ -1,255 +0,0 @@
1
- """End-to-end demo: ACO in action with a simulated agent harness.
2
-
3
- This script demonstrates how to bolt ACO onto any agent harness.
4
- No actual LLM calls are made — decisions are simulated with realistic parameters.
5
- """
6
-
7
- import json
8
- from typing import Dict, Any
9
- from datetime import datetime
10
-
11
- from aco import AgentCostOptimizer
12
- from aco.config import ACOConfig, ModelConfig, ToolConfig, VerifierConfig, RoutingPolicy
13
- from aco.trace_schema import ModelCall, ToolCall, Outcome, FailureTag
14
-
15
-
16
- def build_demo_config() -> ACOConfig:
17
- """Build a demo config with realistic provider pricing."""
18
- return ACOConfig(
19
- models={
20
- "gpt-4o-mini": ModelConfig(
21
- model_id="gpt-4o-mini",
22
- provider="openai",
23
- cost_per_1k_input=0.00015,
24
- cost_per_1k_output=0.0006,
25
- latency_ms_estimate=400,
26
- strength_tier=2,
27
- max_context=128000,
28
- ),
29
- "gpt-4o": ModelConfig(
30
- model_id="gpt-4o",
31
- provider="openai",
32
- cost_per_1k_input=0.0025,
33
- cost_per_1k_output=0.01,
34
- latency_ms_estimate=1500,
35
- strength_tier=4,
36
- max_context=128000,
37
- ),
38
- "claude-3.5-sonnet": ModelConfig(
39
- model_id="claude-3-5-sonnet-20241022",
40
- provider="anthropic",
41
- cost_per_1k_input=0.003,
42
- cost_per_1k_output=0.015,
43
- latency_ms_estimate=1200,
44
- strength_tier=3,
45
- max_context=200000,
46
- ),
47
- "claude-3.5-haiku": ModelConfig(
48
- model_id="claude-3-5-haiku-20241022",
49
- provider="anthropic",
50
- cost_per_1k_input=0.00025,
51
- cost_per_1k_output=0.00125,
52
- latency_ms_estimate=300,
53
- strength_tier=2,
54
- max_context=200000,
55
- ),
56
- "deepseek-chat": ModelConfig(
57
- model_id="deepseek-chat",
58
- provider="deepseek",
59
- cost_per_1k_input=0.00014,
60
- cost_per_1k_output=0.00028,
61
- latency_ms_estimate=800,
62
- strength_tier=3,
63
- max_context=64000,
64
- cache_discount_rate=0.5,
65
- ),
66
- "local-qwen-7b": ModelConfig(
67
- model_id="Qwen/Qwen2.5-7B-Instruct",
68
- provider="local",
69
- cost_per_1k_input=0.0,
70
- cost_per_1k_output=0.0,
71
- latency_ms_estimate=600,
72
- strength_tier=3,
73
- max_context=131072,
74
- ),
75
- },
76
- tools={
77
- "search": ToolConfig("search", 0.002, 500, cacheable=False),
78
- "code_execution": ToolConfig("code_execution", 0.005, 1000, requires_verification=True),
79
- "file_read": ToolConfig("file_read", 0.0005, 100, cacheable=True),
80
- "linter": ToolConfig("linter", 0.001, 200),
81
- "document_retrieval": ToolConfig("document_retrieval", 0.001, 300, cacheable=True),
82
- "compliance_check": ToolConfig("compliance_check", 0.01, 1500, requires_verification=True),
83
- },
84
- verifiers={
85
- "verifier_medium": VerifierConfig("claude-3.5-haiku", 0.005, 800, 0.8),
86
- },
87
- routing_policy=RoutingPolicy("demo"),
88
- )
89
-
90
-
91
- def demo_task(optimizer: AgentCostOptimizer, request: str, expected_difficulty: int = 3):
92
- """Run ACO optimization for a single task and show decisions."""
93
-
94
- print(f"\n{'='*80}")
95
- print(f"TASK: {request}")
96
- print(f"{'='*80}")
97
-
98
- # Build run state for a fresh task
99
- run_state = {
100
- "trace_id": f"demo-{hash(request) % 10000:04d}",
101
- "planned_tools": [("file_read", {"path": "project.md"}), ("code_execution", {"code": "test"})],
102
- "previous_tool_calls": [],
103
- "current_cost": 0.0,
104
- "step_number": 1,
105
- "total_steps": 3,
106
- "is_irreversible": False,
107
- "context_pieces": {
108
- "system_rules": "You are a helpful coding assistant.",
109
- "tool_descriptions": "Available: file_read, code_execution, linter",
110
- "user_preferences": "Prefer Python, type hints, docstrings",
111
- "recent_messages": "",
112
- },
113
- "retrieved_docs": [],
114
- "routing_mode": "cascade",
115
- }
116
-
117
- # Call optimizer
118
- result = optimizer.optimize(request, run_state)
119
-
120
- # Display decisions
121
- print(f"\n📊 OPTIMIZATION DECISIONS")
122
- print(f" Trace ID: {result.trace_id}")
123
- print(f" Estimated Cost: ${result.estimated_cost:.4f}")
124
- print(f" Estimated Latency: {result.estimated_latency_ms:.0f}ms")
125
- print(f" Confidence: {result.confidence:.2f}")
126
- print(f"\n 🎯 Model Routing")
127
- print(f" Selected: {result.routing_decision.model_id} (tier {result.routing_decision.tier})")
128
- print(f" Provider: {result.routing_decision.provider}")
129
- print(f" Max Tokens: {result.routing_decision.max_tokens}")
130
- print(f" Temperature: {result.routing_decision.temperature}")
131
- print(f" Reasoning: {result.routing_decision.reasoning}")
132
- if result.routing_decision.fallback_model_id:
133
- print(f" Fallback: {result.routing_decision.fallback_model_id}")
134
-
135
- if result.context_budget:
136
- cb = result.context_budget
137
- print(f"\n 📄 Context Budget ({cb.total_budget_tokens:,} tokens)")
138
- print(f" Prefix (cacheable): {cb.cache_prefix_tokens:,} tokens")
139
- print(f" Suffix (dynamic): {cb.dynamic_suffix_tokens:,} tokens")
140
- if cb.omitted_sources:
141
- print(f" Omitted: {[s.name for s in cb.omitted_sources]}")
142
- if cb.summarized_sources:
143
- print(f" Summarized: {[s.name for s, _ in cb.summarized_sources]}")
144
- if cb.retrieval_queries:
145
- print(f" Retrieval: {cb.retrieval_queries}")
146
-
147
- if result.prompt_layout:
148
- pl = result.prompt_layout
149
- print(f"\n 💾 Cache Layout")
150
- print(f" Cold Cost: ${pl.estimated_cold_cost:.4f}")
151
- print(f" Warm Cost: ${pl.estimated_warm_cost:.4f}")
152
- print(f" Cache Discount: ${pl.cache_discount:.4f}")
153
-
154
- print(f"\n 🔧 Tool Decisions ({len(result.tool_decisions)} tools)")
155
- for td in result.tool_decisions:
156
- icon = "✅" if td.decision.value in ("use", "batch", "parallel") else "❌"
157
- print(f" {icon} {td.tool_name}: {td.decision.value} (cost: ${td.estimated_cost:.4f}, benefit: {td.estimated_benefit:.2f})")
158
-
159
- if result.verifier_decision:
160
- vd = result.verifier_decision
161
- print(f"\n 🔍 Verifier Decision")
162
- print(f" Decision: {vd.decision.value}")
163
- print(f" Checks: {vd.checks}")
164
- print(f" Estimated Cost: ${vd.estimated_verifier_cost:.4f}")
165
-
166
- if result.meta_tool_match:
167
- mm = result.meta_tool_match
168
- print(f"\n ⚡ Meta-Tool Match")
169
- print(f" ID: {mm['meta_tool_id']}")
170
- print(f" Est. Savings: ${mm['estimated_cost_savings']:.4f}")
171
-
172
- if result.doom_assessment:
173
- da = result.doom_assessment
174
- print(f"\n ⚠️ Doom Assessment")
175
- print(f" Action: {da.action.value}")
176
- print(f" Confidence: {da.confidence:.2f}")
177
- if da.signals_triggered:
178
- print(f" Signals: {da.signals_triggered}")
179
-
180
- # Simulate execution
181
- print(f"\n🎬 SIMULATED EXECUTION")
182
- model_cost = (result.routing_decision.max_tokens / 1000) * optimizer.config.models[result.routing_decision.model_id].cost_per_1k_input
183
- tool_cost = sum(d.estimated_cost for d in result.tool_decisions if d.decision.value in ("use", "batch"))
184
- verifier_cost = result.verifier_decision.estimated_verifier_cost if result.verifier_decision else 0.0
185
- total_cost = model_cost + tool_cost + verifier_cost
186
-
187
- print(f" Model call: ${model_cost:.4f}")
188
- print(f" Tool calls: ${tool_cost:.4f}")
189
- print(f" Verifier: ${verifier_cost:.4f}")
190
- print(f" TOTAL: ${total_cost:.4f}")
191
-
192
- # Estimate what frontier-only would cost
193
- frontier_cfg = optimizer.config.models.get("gpt-4o")
194
- if frontier_cfg:
195
- frontier_cost = (result.routing_decision.max_tokens / 1000) * frontier_cfg.cost_per_1k_input + tool_cost + verifier_cost
196
- savings = frontier_cost - total_cost
197
- print(f"\n💰 vs Frontier Model (gpt-4o)")
198
- print(f" Frontier cost: ${frontier_cost:.4f}")
199
- print(f" Savings: ${savings:.4f} ({savings/max(frontier_cost,0.001)*100:.1f}%)")
200
-
201
- return result
202
-
203
-
204
- def main():
205
- print("=" * 80)
206
- print("AGENT COST OPTIMIZER - End-to-End Demo")
207
- print("=" * 80)
208
-
209
- config = build_demo_config()
210
- optimizer = AgentCostOptimizer(config)
211
-
212
- tasks = [
213
- ("What is the capital of France?", 1),
214
- ("Write a Python function to reverse a linked list", 3),
215
- ("Research the latest advancements in transformer architectures and summarize key findings", 4),
216
- ("Review this contract for liability clauses and check GDPR compliance", 5),
217
- ("Help me with this thing", 3),
218
- ("Debug this segfault in our C++ thread pool implementation", 4),
219
- ("Draft an email to the team about the deployment schedule for next week", 2),
220
- ("Plan a 3-month roadmap for migrating our ML infrastructure to Kubernetes", 4),
221
- ("Search for open issues in the repo and create a summary report", 2),
222
- ("Query the database for Q3 sales data broken down by region, then produce a chart", 3),
223
- ]
224
-
225
- results = []
226
- for request, difficulty in tasks:
227
- result = demo_task(optimizer, request, difficulty)
228
- results.append({
229
- "request": request,
230
- "model": result.routing_decision.model_id,
231
- "tier": result.routing_decision.tier,
232
- "estimated_cost": result.estimated_cost,
233
- "verifier": result.verifier_decision.decision.value if result.verifier_decision else "none",
234
- })
235
-
236
- # Summary
237
- print(f"\n{'='*80}")
238
- print("SUMMARY")
239
- print(f"{'='*80}")
240
- total_est = sum(r["estimated_cost"] for r in results)
241
- print(f"Total estimated cost for {len(tasks)} tasks: ${total_est:.4f}")
242
-
243
- # Show model distribution
244
- from collections import Counter
245
- model_counts = Counter(r["model"] for r in results)
246
- print(f"\nModel distribution:")
247
- for model, count in model_counts.most_common():
248
- print(f" {model}: {count} tasks ({count/len(tasks)*100:.0f}%)")
249
-
250
- print(f"\n✅ Demo complete!")
251
- print(f" Repo: https://huggingface.co/narcolepticchicken/agent-cost-optimizer")
252
-
253
-
254
- if __name__ == "__main__":
255
- main()