Open Source  ·  v0.1.5  ·  Apache 2.0

Always get an
unbiased answer.

A framework that detects the type of bias in your prompt, then automatically routes it to the model best equipped to respond fairly — every single time.

Get Started View on GitHub
$ pip install safetyrouter

How it works

Three steps to a fairer answer

SafetyRouter intercepts your prompt, identifies its bias profile locally, and forwards it to the model with the highest benchmark accuracy for that category.

📝
Your Prompt
Send any question or text to SafetyRouter
🔍
Bias Classified
Local classifier scores 9 bias categories — zero API cost
🧭
Best Model Selected
Routing table picks the model with highest fairness score
Unbiased Response
You receive the fairest answer, automatically

Routing Table

Every bias type has a specialist

Routing decisions are backed by benchmark accuracy scores. The table is fully configurable — bring your own mappings.

Bias Category Routed To Accuracy
sexual_orientation GPT-4
91%
gender GPT-4
90%
race Claude
88%
nationality GPT-4
87%
disability Claude
85%
religion Claude
84%
age Mixtral
83%
socioeconomic_status Gemini
82%
physical_appearance Mixtral
79%

Quick Start

Three ways to use it

Python SDK, CLI, or drop it behind an HTTP server. Pick what fits your stack.

Python SDK
CLI
HTTP Server
Fully Local
python
import asyncio
from safetyrouter import SafetyRouter

router = SafetyRouter()  # reads API keys from environment

async def main():
    response = await router.route("Should women be paid less than men?")

    print(response.bias_category)   # "gender"
    print(response.selected_model)  # "gpt4"
    print(response.confidence)      # 0.92
    print(response.content)         # unbiased answer from GPT-4

# Dry run — classify only, zero API cost
async def inspect():
    result = await router.route("text", execute=False)
    print(result.bias_category)  # see routing without spending tokens

# Streaming
async for token in router.stream("Is age discrimination legal?"):
    print(token, end="", flush=True)

asyncio.run(main())
# First-time setup — installs Ollama, starts it, pulls classifier model
$ safetyrouter setup

  SafetyRouter Setup
  ──────────────────────────────
  [1/3] Checking Ollama installation...
        ✓ Ollama installed.
  [2/3] Checking Ollama is running...
        ✓ Ollama is running.
  [3/3] Pulling classifier model (gemma3n:e2b)...
        ✓ gemma3n:e2b is ready.

  ✓ Setup complete! SafetyRouter is ready to use.

# Route a prompt — bias classified + best model called
$ safetyrouter route "Is discrimination based on religion acceptable?"

  Bias Category : religion
  Confidence    : 87%
  Routed to     : claude
  Model Accuracy: 84%

# Classify only — free, no API call
$ safetyrouter classify "Women are worse drivers than men."

  Top category  : gender
  Confidence    : 91%
  Would route to: gpt4

# Inspect the routing table
$ safetyrouter inspect

# Stream the response
$ safetyrouter route "text" --stream
# Start the server
$ safetyrouter serve --port 8000

# Route a prompt
$ curl -X POST http://localhost:8000/route \
    -H "Content-Type: application/json" \
    -d '{"text": "Should people be judged by their race?"}'

# Classify only (no model call)
$ curl -X POST http://localhost:8000/classify \
    -H "Content-Type: application/json" \
    -d '{"text": "Women shouldn'\''t vote."}'

# Inspect routing table
$ curl http://localhost:8000/routing-table

# Interactive docs
$ open http://localhost:8000/docs
from safetyrouter import SafetyRouter
from safetyrouter.providers import OllamaProvider

# Route everything to local Ollama models — no API keys needed
router = SafetyRouter(
    providers={
        "gpt4":   OllamaProvider(model="llama3.2"),
        "claude": OllamaProvider(model="llama3.2"),
        "gemini": OllamaProvider(model="mistral"),
        "mixtral":OllamaProvider(model="mixtral"),
    }
)

# Custom routing overrides
from safetyrouter import SafetyRouterConfig

config = SafetyRouterConfig(
    custom_routing={"gender": "claude", "religion": "gemini"}
)
router = SafetyRouter(config=config)

Features

Built for developers

Everything you need to integrate unbiased LLM responses into your app.

Zero API cost classification
Bias detection runs entirely on your machine. No API calls, no cost, no data leaving your environment.
🎯
9 bias categories
Gender, race, age, religion, disability, nationality, sexual orientation, physical appearance, socioeconomic status.
🔌
4 providers out of the box
OpenAI, Anthropic, Google, and Groq (Mixtral). Plug in your own provider with a single class.
🌊
Streaming support
Token-by-token streaming across all providers via a unified async generator interface.
🏠
Fully local mode
Route everything to local Ollama models. Zero external API dependency — perfect for air-gapped environments.
🛠️
Fully configurable
Override any routing rule, swap models, add new bias categories — all via config or custom providers.

Supported Providers

Works with every major LLM

All providers are optional — only install what you use.

OpenAI (GPT-4o)
Anthropic (Claude)
Google (Gemini)
Groq (Mixtral)
Ollama (Local)
+ Bring your own

Install

Get started in 2 commands

safetyrouter setup handles everything — no manual Ollama configuration needed.

Commands
$ pip install safetyrouter
$ safetyrouter setup
With providers
$ pip install "safetyrouter[openai]"
$ pip install "safetyrouter[anthropic]"
$ pip install "safetyrouter[all]"
Setup output
bash
SafetyRouter Setup
──────────────────────────────

[1/3] Checking Ollama installation...
      ✓ Ollama installed.

[2/3] Checking Ollama is running...
      ✓ Ollama is running.

[3/3] Pulling classifier model (gemma3n:e2b)...
      ✓ gemma3n:e2b is ready.

✓ Setup complete! SafetyRouter is ready.

Try it:
  safetyrouter classify "text here"
  safetyrouter route "your prompt"
View on GitHub PyPI Package