Skip to content

Repository files navigation

Costwise

Cut Claude Code costs 50-90% — automatic model routing, input filtering, and output reduction via Claude Code hooks.

License Python Tests


What It Does

Claude Code defaults to Opus for everything. Most prompts don't need it — "list files," "explain this function," even simple bug fixes run fine on Haiku or Sonnet at a fraction of the cost.

Costwise is a Claude Code plugin that optimizes costs across three layers:

Layer What How
Routing Sends each prompt to the cheapest model that can handle it UserPromptSubmit hook classifies prompt → switches model
RTK Filters CLI output before it enters context (60-90% input token savings) PreToolUse hook on Bash commands
Ponytail Reduces output verbosity without losing correctness SessionStart hook injects concise-output rules

No proxy server, no infrastructure. Just hooks.

You type a prompt
     │
     ├─ Costwise routes to haiku/sonnet/opus based on complexity
     ├─ RTK filters tool output before it hits context
     └─ Ponytail keeps responses short
     │
     ▼
Same workflow, lower bill

Quick Start

1. Install

cd the_next_big_thing
pip install -e .

2. Enable the Plugin

The plugin lives at plugins/costwise/. Claude Code discovers it automatically when the repo is your working directory. To verify:

costwise doctor
# +-- Costwise Doctor ---------------------------------+
# |  + Config (defaults)                               |
# |  + Tracking DB (N records at ~/.local/share/...)   |
# |  + Plugin (costwise plugin v2.0.0 hook-based)      |
# |  + RTK (N commands tracked)                        |
# |  + Ponytail (mode: full)                           |
# |  5/5 checks passed                                 |
# +----------------------------------------------------+

3. Use Claude Code Normally

Routing is automatic. Every prompt gets classified and routed:

  • "list files in src" → Haiku (SIMPLE)
  • "fix the auth bug in login" → Sonnet (MEDIUM)
  • "redesign the authentication architecture across all microservices" → Opus (COMPLEX)

Prefix a prompt with ~ to bypass routing and keep the current model.

4. Check Savings

costwise gain
# ╭─ Costwise Gain ──────────────────────────────────────╮
# │  Requests:  166                                      │
# │  Cost:      $4.52                                    │
# │  Saved:     $3.90 (46.3%)                            │
# │  Ponytail:  7 reqs @ full (est. ~40% output savings) │
# │  Period:    2026-07-01 – 2026-08-05                  │
# ╰──────────────────────────────────────────────────────╯

Or inside Claude Code: /costwise-gain

How Routing Works

The UserPromptSubmit hook fires on every prompt:

prompt in (stdin JSON)
    │
    ├─ bypass? (starts with ~) → exit 0, no routing
    │
    ├─ fingerprint (SHA-256 + normalize)
    │
    ├─ retry detection
    │   └─ query SQLite: same session, similar content in last 5 min?
    │   └─ if previous request was downgraded → flag as retry
    │
    ├─ classify_prompt(text, ponytail_mode, is_retry)
    │   ├─ intent detection (refactor/debug/fix/generate/explain/chat/...)
    │   ├─ error severity (critical 1.0 / runtime 0.6 / warning 0.3)
    │   ├─ complexity keywords (architecture, redesign, migration plan...)
    │   ├─ code blocks, multi-file scope, prompt length
    │   └─ ponytail bias (full: -0.03, ultra: -0.06)
    │
    ├─ score → tier
    │   < 0.10 → SIMPLE (haiku)
    │   < 0.30 → MEDIUM (sonnet)
    │   ≥ 0.30 → COMPLEX (opus)
    │
    ├─ retry bump: if was false-downgrade, restore original tier
    │
    ├─ budget check (SQLite: hourly + session spend)
    │   ├─ under limit → allow
    │   ├─ near limit → warn (stderr)
    │   ├─ over + auto_downgrade → force lower tier
    │   └─ over → block
    │
    ├─ same model already? → exit 0
    │
    ├─ write ~/.claude/settings.json (model + effortLevel)
    ├─ record decision to SQLite
    └─ exit 2 (prompt re-sent with new model)

Sub-agent routing works via the PreToolUse hook — when Claude spawns an Agent or Task, the hook classifies the sub-agent's prompt and injects the appropriate model.

Classification Signals

Signal Weight What it detects
intent 0.30 Task type: chat=0, explain=0.15, fix=0.6, debug=0.7, refactor=0.8
retry 0.15 Retry keywords or flagged by detector
error_severity 0.14 Graduated: warning=0.3, runtime=0.6, critical=1.0
code 0.11 Code blocks in prompt
complexity_kw 0.10 Architecture, redesign, migration plan, tradeoff...
multi_file 0.09 References multiple file paths
length 0.06 Prompt length (short=simple, long=complex)
error_kw 0.05 Error-related keywords

Ponytail bias reduces the score when output reduction is active (cheaper models are more viable when output costs are already cut).

Feedback Loop

Costwise learns from its mistakes:

  1. Retry detection — if you retry a prompt that was downgraded, that's a false downgrade
  2. Tier bump — retried prompts get routed to at least the original tier
  3. Threshold tuning — the classifier auto-adjusts thresholds to keep false-downgrade rate under 3%
  4. Bounded — max 5 nudges/hour, min 20 requests before any tuning, weights bounded to prevent collapse

Budget Enforcement

Set spend limits in costwise.toml:

[costwise.budget]
max_hourly_usd = 5.0
max_session_usd = 20.0
auto_downgrade = true        # downgrade tier when over budget (vs. block)
warning_threshold_pct = 80   # warn at 80% of limit

Budget is tracked per-request in SQLite using estimated costs ($0.007/simple, $0.06/medium, $0.175/complex).

Configuration

Costwise looks for config in order:

  1. ./costwise.toml
  2. ~/.config/costwise/costwise.toml
  3. Built-in defaults (works out of the box)
[costwise.routing]
mode = "auto"                  # "auto" (switch model) or "advisory" (log only)

[costwise.routing.models]
simple = "claude-haiku-4-5"
medium = "claude-sonnet-4-6"
complex = "claude-opus-4-6"

[costwise.budget]
max_hourly_usd = 5.0
max_session_usd = 20.0

[costwise.tracking]
db_path = "~/.local/share/costwise/costwise.db"
retention_days = 90

[costwise.feedback]
auto_tune = true
similarity_threshold = 0.7    # Jaccard threshold for retry detection

CLI

Command Description
costwise gain Savings summary (routing + RTK + Ponytail)
costwise gain --json-output Machine-readable savings data
costwise doctor Health checks (config, DB, plugin, RTK, Ponytail)

Project Structure

the_next_big_thing/
├── src/costwise/                    # Python package
│   ├── core/                        # Classifier, signals, models, pricing, budget
│   ├── feedback/                    # Retry detector, fingerprinting, auto-tuner
│   ├── tracking/                    # SQLite store (routing decisions, retries, budget)
│   ├── integrations/                # RTK + Ponytail readers
│   ├── config/                      # TOML loader + Pydantic schema
│   └── cli/                         # gain, doctor commands
│
├── plugins/costwise/                # Claude Code plugin
│   ├── .claude-plugin/plugin.json   # Plugin manifest
│   ├── hooks/
│   │   ├── hooks.json               # Hook registration
│   │   ├── session_start.py         # Emit routing rules + init
│   │   ├── user_prompt.py           # Classify → route → track
│   │   ├── pre_tool_use.py          # Route sub-agent spawns
│   │   └── hookio.py                # Hook I/O utilities
│   └── skills/costwise/gain.md      # /costwise-gain skill
│
└── tests/                           # Test suite

Model Pricing

Model Tier Input $/MTok Output $/MTok
claude-opus-4-7 COMPLEX $5.00 $25.00
claude-opus-4-6 COMPLEX $5.00 $25.00
claude-sonnet-4-6 MEDIUM $3.00 $15.00
claude-haiku-4-5 SIMPLE $1.00 $5.00

Haiku output tokens are 5x cheaper than Opus. Routing simple prompts to Haiku saves $20/MTok on output alone.

Acknowledgments

Model routing approach inspired by claude-model-router-hook by @tzachbon.

License

Apache 2.0

About

Cut Claude Code costs 50-90% — automatic model routing, input filtering, and output reduction via Claude Code hooks.

Resources

Contributing

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages