CoolFace
Apppublic

dakshtaneja/AuctionRouter

sourceHugging Facemitupdated 1mo agoView on Hugging Face
0likes
App README

<div align="center">

πŸ”¨ GAVL

Ask more Β· Know faster Β· Pay less

A cost-aware, multi-agent LLM router. Cheap models bid on every question, an auction picks a winner, a verifier checks the answer, and only the genuinely hard queries ever reach an expensive frontier model.

Frontier-quality answers β€” without paying frontier prices on the easy 90%.

Docker FastAPI Next.js OpenRouter License

</div>


The idea

Most chat apps send every question to one big, expensive model β€” even "what's the capital of France." That's slow and wasteful: the easy majority of queries don't need a frontier model at all.

GAVL treats routing as an auction. Three cheap, fast specialist models bid to answer each query based on how well they think they'd do. The best bid wins and drafts the answer, an independent verifier grades it, and only when a genuinely hard query fails does GAVL summon the expensive frontier model β€” the "boss fight." Easy questions never escalate.

The payoff (see evals): ~0.95 answer quality at ~68% lower cost and ~15Γ— faster median latency than sending everything to the frontier.

🧠 How it works

mermaid
flowchart LR
    Q([Your query]) --> B{{Bid in parallel}}
    B --> G[Generalist] & C[Coder] & M[Logic / math]
    G & C & M --> A[Auction<br/>score the bids]
    A -->|winner drafts| V{Verifier}
    A -.->|needs fresh info| W[Web search]
    W --> V

    V -->|passes| ANS([Answer])
    V -->|hard query fails| BOSS[πŸ”¨ Frontier model<br/>the boss fight]
    BOSS --> ANS

    classDef cheap fill:#0d2018,stroke:#16a34a,color:#bbf7d0
    classDef boss fill:#2a0d12,stroke:#f43f5e,color:#ffe4e6
    classDef out fill:#1c1005,stroke:#f97316,color:#fed7aa
    class G,C,M cheap
    class BOSS boss
    class ANS out
  1. 1.Bidding β€” all three tier-1 models bid in parallel. Each returns a confidence, a difficulty estimate, and a flag for whether the query needs live web data. A confident bidder also drafts its answer on the spot, so if it wins there's no extra round-trip.
  2. 2.Auction β€” bids are scored on 0.7Β·confidence + 0.2Β·historical-accuracy βˆ’ 0.1Β·cost. A topic toggle (general / coding / logic-math) lets you steer routing. The accuracy term is learned β€” a model that overbids and fails is trusted less next time.
  3. 3.Verification β€” an independent verifier grades the winning draft on correctness, completeness, and commitment. Creative writing skips this (no single right answer to check).
  4. 4.Escalation β€” only a hard query that fails verification escalates to the frontier model, with reasoning effort and token budget scaled to the difficulty. Easy queries never escalate; a weak answer just ships, clearly marked unverified.
  5. 5.Web search β€” if a bidder flags the query as needing current information (news, latest releases, "who won X", a specific recent item), the winner runs a live web search and cites its sources.

✨ Features

  • β€”Auction-based routing with a learned per-model accuracy prior.
  • β€”Speculative drafting β€” confident bidders answer inside their bid, so the winning answer often needs zero extra calls.
  • β€”Streaming-first UI β€” you see text in ~3s; the verifier judges in parallel.
  • β€”Difficulty-gated escalation β€” the frontier model is reserved for the small fraction of queries that truly need it.
  • β€”Live web search with citations, gated on a per-query freshness flag.
  • β€”Topic toggles to hint the router (general / coding / logic-math).
  • β€”Retro arcade UI β€” a live "bidding bots" animation, a boss-fight ticker for escalations, per-code-block copy, and a /explain command that walks through the whole pipeline in-app.
  • β€”Cost & routing telemetry β€” every answer shows who won, what it cost, and the verifier's score; a metrics dashboard tracks savings over time.

πŸ“Š Eval results

38 bucketed queries (easy factual, subjective, typos, ambiguous, coding, medium reasoning, PhD-level STEM) run through the full pipeline vs. sending every query straight to the frontier model. Answers scored 0–1 by an independent LLM judge against reference notes. Frontier stand-in for the eval: DeepSeek R1; identical queries, models, and judge across both modes.

modejudge scoretier-1 ratep50 latencytotal cost
GAVL0.9589%3.6 s$0.067
frontier-only1.000%52.8 s$0.212

68% cheaper and ~15Γ— faster at the median, giving up 0.05 judge points β€” half of which is a single eval-artifact failure (the frontier stand-in exhausted its token budget on one physics derivation), not a routing miss. At production frontier pricing the gap widens sharply, projecting to ~85–90% savings.

<details> <summary>Per-bucket breakdown</summary>

bucketnjudgetier-1p50cost
easy_factual81.00100%1.7 s$0.002
subjective51.00100%2.6 s$0.002
typo41.00100%3.3 s$0.002
ambiguous50.82100%2.8 s$0.003
coding51.00100%6.8 s$0.005
reasoning51.00100%9.9 s$0.005
stem_hard60.8333%112.6 s$0.048

Notably, 2 of 6 hard-STEM items were answered correctly at tier 1 (judge 1.0, verifier-passed) β€” the cheap models legitimately solved them, so the "low" routing accuracy there is savings, not error. </details>

Reproduce:

bash
cd backend
FRONTIER_MODEL_ID=deepseek/deepseek-r1 uv run python -m evals.run_evals
FRONTIER_MODEL_ID=deepseek/deepseek-r1 uv run python -m evals.run_evals --mode frontier

🧩 Tech stack

LayerTech
BackendFastAPI Β· LangGraph pipeline Β· async httpx
ModelsRouted through OpenRouter (swappable per slot via config)
FrontendNext.js (static export) Β· Tailwind Β· streaming NDJSON
StoreMongoDB (optional) or in-memory
DeploySingle Docker image (Hugging Face Space) or split Vercel + HF

All model choices, auction weights, and thresholds live in backend/app/config.py β€” swap any bidder, the verifier, or the frontier model without touching pipeline code.

πŸš€ Deployment

The frontend is a pure client-side SPA and the backend is a pure API, so they can deploy independently: Vercel serves the UI, a Hugging Face Docker Space runs FastAPI. (The Dockerfile also bundles the UI, so the Space works standalone.)

πŸ” Security model

The API key is a server-side secret never sent to the browser β€” the real threat is abuse of the endpoints that spend it. Defense in depth, worst case bounded by a number:

  1. 1.Credit-capped OpenRouter key β€” a dedicated key with a hard credit limit. Provider-enforced; survives any app bug.
  2. 2.Daily spend guard β€” DAILY_SPEND_LIMIT_USD; query endpoints 503 once the day's total is exceeded.
  3. 3.Access code β€” every /api/* route requires the X-Access-Code header (ACCESS_CODE); /health stays open. Locking it also closes the run-history and metrics endpoints.
  4. 4.Per-IP rate limiting β€” RATE_LIMIT_PER_MIN / _PER_DAY.
  5. 5.CORS β€” ALLOWED_ORIGINS allowlist (browsers only; layers 1–4 are the real boundary).

Backend β†’ Hugging Face Docker Space

  1. 1.Create the credit-capped OpenRouter key.
  2. 2.Push this repo to a Docker Space:
bash
   git remote add hf https://huggingface.co/spaces/<user>/GAVL
   git push hf main:main
  1. 1.Settings β†’ Variables and secrets:
  2. 2.OPENROUTER_API_KEY (secret) β€” the credit-capped key
  3. 3.ACCESS_CODE (secret) β€” the shared demo code
  4. 4.TAVILY_API_KEY (secret, optional) β€” enables the image strip under web-search answers. Omit it and the feature stays off; nothing else changes.
  5. 5.ALLOWED_ORIGINS (variable) β€” your Vercel URL (comma-separated)
  6. 6.DAILY_SPEND_LIMIT_USD (variable) β€” e.g. 20
  7. 7.MONGODB_URI / MONGODB_DB (optional) β€” Atlas M0; else in-memory
  8. 8.FRONTIER_MODEL_ID (optional)
  9. 9.If using Atlas, allow 0.0.0.0/0 in its Network Access list.
  10. 10.Confirm <space-url>/health returns openrouter_key_set: true.

Frontend β†’ Vercel

  1. 1.Import frontend/ as a Vercel project (auto-detected Next.js).
  2. 2.Set NEXT_PUBLIC_API_BASE = the HF Space URL. (The access code is entered at runtime, never baked into the bundle.)
  3. 3.Deploy, add the Vercel domain to the Space's ALLOWED_ORIGINS, redeploy.
HF free tier sleeps after ~48h idle β†’ first query cold-starts ~30s. HF Pro or an always-on backend (Fly.io / Render, same Dockerfile) removes this. CPU Basic is sufficient β€” all inference happens on OpenRouter.

πŸ’» Local development

bash
# backend
cd backend && uv sync && uv run uvicorn app.main:app --reload --port 8000

# frontend
cd frontend && npm install && npm run dev

Then open <http://localhost:3000>. With no ACCESS_CODE set the gate is skipped automatically; set one in backend/.env to preview the splash screen.


<div align="center"> <sub>Built with FastAPI, LangGraph, Next.js, and OpenRouter Β· MIT licensed</sub> </div>