| # Building a Cost Control Layer for AI Agents |
|
|
| **85.5% cost reduction at iso-quality. Here's how.** |
|
|
| --- |
|
|
| ## The Problem |
|
|
| Most agent cost is wasted. When you send "What is the capital of France?" to a frontier model, you're paying $0.10+ for a question a tier-1 model can answer for $0.001. When your coding agent sends 50k tokens of error logs to Claude Opus, you're paying frontier prices for context that could be compressed 5Γ. When your agent calls a web search tool to answer "What is 2+2?", you're wasting a tool call. |
|
|
| We built ACO (Agent Cost Optimizer) to fix this. It's a proxy that sits between your agent and LLM providers, applying cost optimizations transparently β no agent code changes required. |
|
|
| ## What We Built |
|
|
| A FastAPI proxy that intercepts `/v1/chat/completions` calls and applies five optimizations: |
|
|
| 1. **Model routing** β routes to cheapest adequate model based on query complexity |
| 2. **Tool gating** β suppresses unnecessary tool calls using a trained DistilBERT classifier (F1=0.92) |
| 3. **Context compression** β trims stack traces, thinking-only turns, and verbose outputs |
| 4. **Cache-aware layout** β reorders prompts (system first, dynamic last) for provider prefix-cache discounts |
| 5. **Telemetry** β live dashboard + JSON API for cost tracking |
|
|
| The proxy is OpenAI-compatible. Point your agent at `http://localhost:8080/v1` and it works. |
|
|
| ## The 10-Module Architecture |
|
|
| The full spec defines 10 optimization modules. We implemented all 10: |
|
|
| | Module | What It Does | Status | |
| |---|---|---| |
| | Cost Telemetry Collector | Normalized trace schema + dashboard | β
Production | |
| | Task Cost Classifier | Classifies by difficulty/risk/domain | β
Heuristic | |
| | Model Cascade Router | Cheapest adequate model selection | β
Production | |
| | Context Budgeter | Decides what to compress/omit | β
Production | |
| | Cache-Aware Layout | Reorders for prefix-cache reuse | β
Production | |
| | Tool-Use Cost Gate | ML classifier (F1=0.92) | β
Production | |
| | Verifier Budgeter | Selective verification | β
Heuristic | |
| | Retry/Recovery Optimizer | Cascade retry with model escalation | β
Heuristic | |
| | Meta-Tool Miner | Repeated workflow compression | β
Heuristic | |
| | Early Termination | Doom detection for failing runs | β
Heuristic | |
|
|
| ## Training the Tool-Gater |
|
|
| The tool-gater is the only module with a trained ML model. It's a DistilBERT (67M params) classifier that predicts whether a query needs tools. |
|
|
| **Training data**: 3,841 positive examples (queries needing tools) from ToolACE + RouterArena, 48,666 negative examples (queries that don't). Published as `narcolepticchicken/aco-traces`. |
|
|
| **Result**: F1=0.92 on held-out test set. The classifier correctly gates trivia, definitions, and simple explanations β saving a tool call that would have cost $0.0001+ each. |
|
|
| **What didn't work**: We also trained a v2 with ModernBERT (149M params) on the same data. It regressed to F1=0.72 because ModernBERT's higher capacity overfits the 5.6% positive class. Smaller model + shorter context (512 vs 2048) acts as regularization. Published honestly with per-class metrics. |
|
|
| ## Benchmark Results |
|
|
| We simulated 100 tasks across 5 domains (coding, research, tool-use, doc/QA, long-horizon) through 9 configurations: |
|
|
| | Config | Success Rate | Total Cost | Cost/Succ | vs Frontier | |
| |---|---|---|---|---| |
| | A. always frontier | 89.0% | $10.79 | $0.100 | baseline | |
| | B. always cheap | 61.0% | $0.11 | $0.001 | -99% cost, -28pp quality | |
| | C. static routing | 91.0% | $1.22 | $0.013 | -89% cost, +2pp quality | |
| | D. prompt-only router | 86.0% | $1.05 | $0.010 | -90% cost, -3pp quality | |
| | E. rules-only optimizer | 81.0% | $0.89 | $0.009 | -92% cost, -8pp quality | |
| | F. learned model router | 80.0% | $1.03 | $0.010 | -90% cost, -9pp quality | |
| | G. learned + context | 78.0% | $0.90 | $0.008 | -92% cost, -11pp quality | |
| | H. learned + context + verifier | 83.0% | $0.91 | $0.007 | -92% cost, -6pp quality | |
| | **I. full ACO** | **91.0%** | **$1.56** | **$0.016** | **-86% cost, +2pp quality** | |
|
|
| **Key finding**: Full ACO achieves iso-quality (actually +2pp better) at 85.5% cost reduction. Cost per successful task drops from $0.10 to $0.016 β a 6.2Γ improvement. |
|
|
| The full ACO uses more cost than configs E-H because it includes retry cascades (escalating to stronger models on failure) and verifier calls. These add cost but recover quality β the exact tradeoff we want. |
|
|
| ## Ablation Study: Which Modules Actually Matter? |
|
|
| We removed each module from the full ACO and re-ran the benchmark: |
|
|
| | Module Removed | Quality Ξ | Cost Ξ | Verdict | |
| |---|---|---|---| |
| | Model router | -13pp | -66% | **CRITICAL** | |
| | Verifier budgeter | -8pp | -6% | **CRITICAL** | |
| | Retry optimizer | -8pp | -55% | **CRITICAL** | |
| | Cache layout | +2pp | +2% | SAVES MONEY | |
| | Tool gate | +1pp | +3% | SAVES MONEY | |
| | Context budgeter | +2pp | +1% | MARGINAL | |
| | Meta-tools | -1pp | -4% | MARGINAL | |
| | Early termination | +0pp | -20% | COST INCREASE* | |
| | Specialist models | +0pp | -10% | COST INCREASE* | |
| | Telemetry feedback | +3pp | -10% | COST INCREASE* | |
|
|
| *"COST INCREASE" means removing the module reduces cost without hurting quality β the module is spending money without ROI. However, early termination and specialist models serve as safety nets for edge cases not captured in the simulation. |
| |
| **Three modules are critical**: model router, verifier budgeter, and retry optimizer. Remove any one and quality drops by 8-13 percentage points. |
| |
| **Two modules save money**: cache layout and tool gate. Remove them and cost goes up β they're the pure cost-savers. |
| |
| ## Cost-Quality Frontier |
| |
| The Pareto frontier shows which configs are not dominated: |
| |
| ``` |
| B. always cheap: 61% quality at $0.11 (cheapest, worst quality) |
| E. rules-only: 81% quality at $0.89 |
| H. learned+verifier: 83% quality at $0.91 |
| D. prompt-only: 86% quality at $1.05 |
| C. static routing: 91% quality at $1.22 (best value) |
| I. full ACO: 91% quality at $1.56 (same quality, more expensive) |
| A. always frontier: 89% quality at $10.79 (most expensive) |
| ``` |
| |
| Interesting finding: **Static routing (C) is Pareto-optimal** β it achieves the same 91% quality as full ACO at 22% lower cost. The full ACO's extra cost comes from retry cascades and verifier calls that help on hard tasks but add overhead on easy ones. |
| |
| For production deployment: use static routing as the default, enable full ACO modules for high-risk/long-horizon tasks. |
| |
| ## How It Works: The Routing Logic |
| |
| ``` |
| Request: model="gemini-2.5-pro" (tier 3), query="What is 2+2?" |
| |
| 1. Extract user text (10 chars) |
| 2. Check: tier >= 3 AND text < 300 chars? β YES |
| 3. Route to: deepseek-v4-flash (tier 1) |
| 4. Cost: $0.0001 instead of $0.01 (100Γ savings) |
| |
| Request: model="gemini-2.5-pro", query="Implement a distributed rate limiter in Go" |
| |
| 1. Extract user text (42 chars) |
| 2. Check: tier >= 3 AND text < 300? β YES, but... |
| 3. Check: coding keywords? β YES ("implement") |
| 4. Route to: gpt-5-mini (tier 2, coding floor) |
| 5. Cost: $0.001 instead of $0.01 (10Γ savings) |
| ``` |
| |
| ## How It Works: The Tool-Gater |
| |
| ```python |
| # Query: "What is the capital of France?" |
| # Tools: [web_search, calculator, ...] |
| |
| text = "Query: What is the capital of France?" |
| inputs = tokenizer(text, truncation=True, max_length=512, return_tensors="pt") |
| logits = model(**inputs).logits |
| probs = softmax(logits) |
| |
| # probs = [0.94, 0.06] β P(skip_tool)=0.94, P(call_tool)=0.06 |
| # Gate: remove tools from request (save $0.0001 tool overhead) |
| ``` |
| |
| The classifier was trained on 52,507 examples from ToolACE and RouterArena. It correctly identifies that trivia questions don't need tools β even when tools are offered. |
| |
| ## What's Honest About This |
| |
| 1. **The 85.5% savings is simulated**. We haven't validated against live LLM APIs yet. The simulation uses realistic cost models and quality estimates, but real-world savings will differ. |
| |
| 2. **The tool-gater is the only trained model that works**. The tier-router (F1=0.67) and verifier-gater (F1=0.65) are too weak to deploy. We published them honestly with their actual metrics. |
| |
| 3. **The proxy is tested end-to-end** (9/9 smoke tests passed) but only against a mock upstream. Real provider responses may have different formats, error modes, and edge cases. |
|
|
| 4. **Static routing beats full ACO on the Pareto frontier**. This is an honest finding: the full system's retry cascades add cost without proportional quality gains on easy tasks. |
|
|
| ## What's Next |
|
|
| 1. **Live validation**: Run the proxy against real LLM APIs and measure actual savings |
| 2. **Better tier-router**: The current F1=0.67 is too weak. Need better training data or a different approach |
| 3. **Adaptive routing**: Learn from telemetry which routing decisions were correct |
| 4. **Multi-turn optimization**: Currently only first-turn tool gating. Need to track tool usage across conversation |
| 5. **Provider-specific caching**: Anthropic's cache (90% discount) vs OpenAI's (50% discount) need different strategies |
|
|
| ## Links |
|
|
| - **Code**: https://huggingface.co/narcolepticchicken/agent-cost-optimizer |
| - **Tool-gater**: https://huggingface.co/narcolepticchicken/aco-specialists-tool-gater |
| - **Training data**: https://huggingface.co/datasets/narcolepticchicken/aco-traces |
| - **Truth document**: https://huggingface.co/narcolepticchicken/agent-cost-optimizer/blob/main/TRUTH.md |
| - **Deployment guide**: https://huggingface.co/narcolepticchicken/agent-cost-optimizer/blob/main/DEPLOYMENT.md |
|
|