Skip to main content

leanroute

A toll gate in front of any LLM. Website: leanroute.online · Source: GitHub

Before your app pays an LLM, Leanroute checks three things, locally and for $0 per call:

  1. Is this an attack? Prompt injections are blocked by an open-source detector before any LLM call.
  2. How hard is it? Easy → your cheap model. Hard or sensitive → your strong model.
  3. Anything else you ask, e.g. "is this spam?", "which team?", "hot lead?" → answered by Laya (Apache 2.0) with a probability, no LLM at all.

Version 0.1 note: this package decides "easy or hard" with Laya's difficulty score. The Leanroute server uses a trained router that was measurably better on real graded answers (results); bringing it to this package is planned for 0.2.

your code ─► leanroute ─┬─ blocked ............ $0
                        ├─ cheap model ........ $
                        └─ strong model ....... $$$

Install

pip install "leanroute[local]"    # runs Laya inside your app (downloads the model once)
pip install leanroute             # lightweight: talks to a Leanroute server instead

1. Drop-in: one line in front of your existing client

from openai import OpenAI
from leanroute import Leanroute

lr = Leanroute()                                        # or Leanroute(api_url="http://localhost:8000")
client = lr.wrap(OpenAI(), cheap="gpt-4o-mini", strong="gpt-4o")

r = client.chat.completions.create(
    model="auto",                                      # Leanroute picks cheap vs strong
    messages=[{"role": "user", "content": "Capital of Australia?"}],
)
print(r.choices[0].message.content, r.leanroute.route)  # -> "Canberra", "cheap"

Everything else about the client is unchanged. Works with OpenAI, AsyncOpenAI, any OpenAI-compatible SDK (Groq, Together, OpenRouter, Ollama's /v1), and Anthropic (client.messages.create(model="auto", ...)).

  • model="auto" → guard + route.
  • Any real model name → guard only; your model is used ("pinned").
  • Blocked prompts raise leanroute.Blocked before any tokens are billed.

2. Any LLM, any framework: ask for a route

d = lr.route(messages, cheap="small-model", strong="big-model")
if d.blocked:
    return "Sorry, I can't help with that."
reply = call_my_llm(model=d.model, messages=messages)   # LangChain, LiteLLM, raw HTTP, anything

Or just the guardrail:

from leanroute import Blocked
try:
    lr.guard(user_input)
except Blocked as e:
    print("blocked:", e.decision.reason)

3. Skip the LLM entirely for simple decisions

from leanroute import yes_no, choice, level

lr.check("FREE crypto signals!!!", "Is this spam?")      # -> 0.94

a = lr.decide(ticket_text, {
    "team":    choice("Which team should handle this?", ["billing", "technical", "sales", "other"]),
    "urgent":  yes_no("Is there a deadline or time pressure?"),
    "anger":   level("How frustrated is the customer?", ["calm", "annoyed", "furious"]),
})
a["team"].value, a["team"].confidence, a["urgent"].yes

Savings report

lr = Leanroute(prices={"gpt-4o-mini": (0.15, 0.60), "gpt-4o": (2.50, 10.00)})  # USD per 1M tokens in/out
...
lr.stats.summary()
# {'requests': 120, 'routes': {'cheap': 81, 'strong': 37, 'blocked': 2}, 'saved_usd': 1.84, 'saved_pct': 71.3, ...}

Use your provider's current prices; savings are only as accurate as those numbers.

Tuning

from leanroute import Policy
lr = Leanroute(policy=Policy(guard_mode="precise", detector_threshold=0.66, easy_max=1.2))

Guard modes (measured in eval/results.md):

guard_mode What blocks a prompt
precise (default) ProtectAI's open-source prompt-injection detector. Fewest normal requests blocked; never blocked code or math in testing
broad The detector, or Laya when its jailbreak and injection scores are both very high. Catches more role-play jailbreaks, blocks some coding requests
laya Laya's jailbreak and injection scores only
off Nothing

In local mode the detector runs inside your app (downloaded on first use); with api_url it runs on the server.

Fail-open by default: if the decision layer errors (server down, model not loaded), requests go to your strong model so your app keeps working. Set fail_open=False to raise instead.

Honest limits

Laya decides; it doesn't write. It reads short text (about a page), works best with a handful of options per question, and should be fine-tuned and calibrated on your own data before you trust its thresholds in production. Start conservative and check the routes in lr.stats.

License

Apache 2.0. Built on Laya © Convai Innovations (Apache 2.0).

Metadata

Release files for leanroute 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for leanroute 0.1.0
File Size Uploaded
leanroute-0.1.0.tar.gz 16.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for leanroute 0.1.0
File Interpreter ABI Platform
leanroute-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 32.7 kB

Release files / leanroute-0.1.0.tar.gz

Download URL leanroute-0.1.0.tar.gz
Size 16.3 kB
Tags Source
SHA-256 checksum
How to use checksums
942e20e30dbcf5bc314807f214990078d3eb96ebdc5323512db8a858cab6be40
BLAKE2b-256 checksum
How to use checksums
f80faf03d7a8be001576c5edcdda1c7f5666fefe8577439934ee9f833114edc2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release files / leanroute-0.1.0-py3-none-any.whl

Download URL leanroute-0.1.0-py3-none-any.whl
Size 16.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c65f78acd6f6b6215150dd83d09cc501924b5a97a01e31e505bd9c40d3d323b7
BLAKE2b-256 checksum
How to use checksums
fa95778d1cd9ff67e60de1fbd6aef0d81956d93ad54ea3f1b8465765799de808
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.9.6

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page