Skip to main content

Production-ready LLM routing library — multi-model routing across N cost tiers

Project description

CostRouter

Stop paying GPT-4o prices for "What's 2+2?"

CostRouter automatically sends simple questions to cheap models and hard questions to expensive ones. Drop-in replacement for your LLM calls — saves up to 85% on costs.

Install

pip install costrouter

Quick Start

import os
from costrouter import CostRouter

os.environ["OPENAI_API_KEY"] = "sk-..."

# List your models from cheapest to most expensive
router = CostRouter(["gpt-4o-mini", "gpt-4o"])

# Use it like normal
result = router.completion(messages=[{"role": "user", "content": "Hi!"}])
print(result.content)  # "Hello! How can I help you?"
print(result.model)    # "gpt-4o-mini" (cheap model — it was just a greeting)
print(result.tier)     # "simple"

That's it. Simple questions go to gpt-4o-mini, hard ones go to gpt-4o.

How It Works

Every request gets classified into a complexity tier before being routed:

Prompt Tier Goes to
"Hi there!" simple gpt-4o-mini
"Summarize this article" moderate gpt-4o-mini
"Write a Python web scraper" complex gpt-4o
"Prove the Riemann hypothesis" expert gpt-4o

The classifier is a cheap LLM call (~$0.0001) that runs before your actual request. Obvious cases (greetings, short questions, code keywords) are caught by free pattern matching and skip the classifier entirely.

More Models

You can use 1, 2, 3, or 4 models. They auto-map to tiers by position:

# 2 models: simple + complex
router = CostRouter(["gpt-4o-mini", "gpt-4o"])

# 3 models: simple + moderate + complex
router = CostRouter(["gpt-4o-mini", "gpt-4o", "claude-opus-4-6"])

# 4 models: simple + moderate + complex + expert
router = CostRouter(["gpt-4o-mini", "gpt-4o", "claude-sonnet-4-5-20250929", "claude-opus-4-6"])

Mix Providers

Use OpenAI for cheap calls and Anthropic for hard ones (or any of the 100+ providers litellm supports):

from costrouter import CostRouter, CostTier, ModelConfig

router = CostRouter([
    ModelConfig(name="gpt-4o-mini", tier=CostTier.SIMPLE, api_key="sk-..."),
    ModelConfig(name="claude-opus-4-6", tier=CostTier.COMPLEX, api_key="sk-ant-..."),
])

Track Your Savings

# After some requests...
print(router.analytics.summary())
CostRouter Analytics
====================
Total requests: 150
Total cost: $0.45
Cost if always using most expensive: $3.20
Total saved: $2.75 (86%)

Routing breakdown:
  simple      45.0% (68 requests)  -> gpt-4o-mini
  moderate    30.0% (45 requests)  -> gpt-4o-mini
  complex     20.0% (30 requests)  -> gpt-4o
  expert       5.0% (7 requests)   -> gpt-4o
# Export for analysis
router.analytics.export_csv("routing_log.csv")

# Programmatic access
data = router.analytics.to_dict()

Async

result = await router.acompletion(messages=[{"role": "user", "content": "Hi"}])
print(result.content)

Pass-Through Parameters

Anything you'd pass to OpenAI/litellm works:

result = router.completion(
    messages=[{"role": "user", "content": "Write a haiku"}],
    temperature=0.9,
    max_tokens=200,
)

Custom Routing Logic

Subclass BaseRouter to define your own rules:

from costrouter import BaseRouter, CostRouter, CostTier

class MyRouter(BaseRouter):
    def classify(self, messages):
        text = messages[-1]["content"]
        if "urgent" in text.lower():
            return CostTier.EXPERT, 1.0, 0.0
        return CostTier.SIMPLE, 0.8, 0.0

    async def aclassify(self, messages):
        return self.classify(messages)

router = CostRouter(
    models=["gpt-4o-mini", "gpt-4o"],
    strategy=MyRouter(),
)

classify returns (tier, confidence, screener_cost).

Response Object

result = router.completion(messages=[...])

result.content     # Response text (shortcut)
result.model       # Which model handled it
result.tier        # Classified complexity
result.cost        # Cost of the LLM call
result.total_cost  # Screening + LLM call
result.saved       # $ saved vs most expensive model
result.response    # Full litellm response object

Advanced Options

router = CostRouter(
    models=["gpt-4o-mini", "gpt-4o"],
    screener="gpt-4o-mini",       # Model used to classify (default: cheapest)
    strategy="cascade",            # "cascade" (default), "heuristic" (free), or "llm"
    confidence_threshold=0.7,      # How confident heuristic must be to skip LLM classifier
    fallback=True,                 # If a model fails, try the next tier up
)

Strategies:

  • cascade (default) — Free pattern matching first. If unsure, asks a cheap LLM. Best balance of cost and accuracy.
  • heuristic — Pattern matching only. Free and instant, but less accurate on ambiguous prompts.
  • llm — Always uses a cheap LLM to classify. Most accurate, costs ~$0.0001 per request.

Requirements

  • Python >= 3.10
  • litellm + pydantic (no PyTorch, no Transformers)

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

costrouter-0.1.0.tar.gz (16.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

costrouter-0.1.0-py3-none-any.whl (14.8 kB view details)

Uploaded Python 3

File details

Details for the file costrouter-0.1.0.tar.gz.

File metadata

  • Download URL: costrouter-0.1.0.tar.gz
  • Upload date:
  • Size: 16.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for costrouter-0.1.0.tar.gz
Algorithm Hash digest
SHA256 86ba6ffc030d9b856aa83cbcb1e3a4e88ee6dbeabf5f639733c95340de3a7e4c
MD5 848beae8b0b8eafcba6532d3556910bf
BLAKE2b-256 ff3cdc2ff4d0a4b29e80034ffde3c7084fc727da30f016d3fba9a6ff76632800

See more details on using hashes here.

File details

Details for the file costrouter-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: costrouter-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 14.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.3

File hashes

Hashes for costrouter-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c8776cdaa8b4c2046ec4a2b2c17a2f30e8f1c7df28ad7e394d4131ece4a5778c
MD5 8d1608796b8709b8aaa54a455f764841
BLAKE2b-256 0b662a9bef42d7d0a7d99e0f7d38f94902ab2f4426ee379276f46d6e565efbf0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page