Skip to content

TotoBa/CaiLama-LLM-Router

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

LLM-Router

CaiLama Logo

Webseite: https://cailama.org/

Ecosystem-Doku:

Generic local LLM routing gateway with OpenAI-compatible API, model aliases, backend fallback and JSONL logging.

Was macht der Router?

Du hast mehrere LLM-Backends (z.B. Ollama lokal, Ollama auf einem RasPi, später OpenRouter). Deine Tools (Kimi CLI, Schachsystem, Skripte) sollen nicht wissen, welches Backend gerade verfügbar ist und welches Modell dort läuft.

Der Router schafft eine Abstraktionsschicht:

Dein Tool -> "chess-small" -> LLM-Router -> Backend "vm" (deepseek-v4-flash:cloud)
                                falls down -> Backend "pi" (deepseek-v4-flash:cloud)

Features

  • OpenAI-compatible API/v1/chat/completions, /v1/models, /health
  • Modell-Aliase – dein Tool fragt chess-small, der Router weiß, welches Provider-Modell gemeint ist
  • Backend-Fallback – bei Rate-Limits, Verbindungsfehlern oder Crashs automatisch nächstes Backend
  • Optionale Verteilunground_robin verteilt Requests ueber alle verfuegbaren Backends
  • Streaming – SSE-Stream wird transparent durchgereicht (wichtig für Kimi CLI)
  • JSONL-Logging – jede Anfrage wird protokolliert, ohne Prompt-Inhalte (standardmäßig)
  • Keine Secrets im Repo – echte Configs und API-Keys werden nie eingecheckt

Schnellinstallation

git clone git@github.com:TotoBa/LLM-Router.git
cd LLM-Router
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"

Erste Schritte

1. Konfiguration anlegen

cp configs/router.example.yaml configs/router.local.yaml
cp .env.example .env

Bearbeite configs/router.local.yaml und passe backends an deine IPs an.

2. Router starten

llm-router serve --config configs/router.local.yaml

3. Testen

curl http://127.0.0.1:18080/health
curl http://127.0.0.1:18080/v1/models

4. Smoke-Test

llm-router smoke-test --model default --prompt "Antworte nur OK."

Für einen dauerhaften Router-VM + Pi-Ollama Rollout siehe:


CLI-Befehle

llm-router --help                       # Alle Befehle anzeigen
llm-router serve --config ...           # Router starten
llm-router check-config --config ...    # Config validieren
llm-router list-models --config ...     # Modell-Aliase auflisten
llm-router test-backends --config ...  # Backends testen
llm-router smoke-test --model ...       # End-to-End-Test

Für Kimi CLI

Kimi spricht nicht mehr direkt mit Ollama, sondern mit dem Router.

Füge in ~/.kimi/config.toml ein:

default_model = "kimi-cli-default"

[providers.local-llm-router]
type = "openai_legacy"
base_url = "http://127.0.0.1:18080/v1"
api_key = "ollama"

[models.kimi-cli-default]
provider = "local-llm-router"
model = "kimi-cli-default"
max_context_size = 131072
capabilities = ["thinking"]

Dann: kimi --model kimi-cli-default

Mehr Details in docs/kimi-cli.md


Für das Schachsystem

Im Schachsystem:

LLM_BASE_URL=http://127.0.0.1:18080/v1
LLM_API_KEY=ollama
LLM_MODEL_ROUTER=chess-router
LLM_MODEL_SMALL=chess-small
LLM_MODEL_LARGE=chess-large
LLM_MODEL_TASK=chess-task
LLM_MODEL_COACH=chess-coach
LLM_MODEL_ANALYST=chess-analyst
LLM_MODEL_CRITIC=chess-critic
LLM_MODEL_VISION=chess-vision
LLM_MODEL_SCRIBE=chess-scribe
LLM_MODEL_RESEARCHER=chess-researcher

Das Schachsystem kennt nur logische Rollen (small, large, task, coach, analyst, critic, vision, scribe, researcher). Der Router kümmert sich um das echte Modell und das Backend. Rollenverhalten wird vom Schachsystem gepromptet; der Router erzwingt keine Schachlogik.

Mehr Details in docs/chess-system.md


Beispiel-Konfiguration

server:
  host: "127.0.0.1"
  port: 18080

backends:
  local:
    type: "openai_compatible"
    base_url: "http://127.0.0.1:11434/v1"
    api_key_env: "OLLAMA_LOCAL_API_KEY"
    priority: 10
    enabled: true

  pi:
    type: "openai_compatible"
    base_url: "http://192.168.178.50:11434/v1"
    api_key_env: "OLLAMA_PI_API_KEY"
    priority: 20
    enabled: true

models:
  default:
    provider_model: "deepseek-v4-flash:cloud"
    backends: ["local", "pi"]
    policy: "standard"

  chess-small:
    provider_model: "deepseek-v4-flash:cloud"
    backends: ["local", "pi"]
    policy: "standard"
    routing_strategy: "round_robin"

policies:
  standard:
    max_attempts_per_backend: 2
    max_backend_failures_before_cooldown: 2
    backend_cooldown_seconds: 300
    retry_on_connection_error: true
    retry_on_timeout: false
    fallback_on_limit: true
    fallback_on_5xx: true
    fallback_on_4xx: false
    return_last_error_on_exhausted_backends: true
    timeout_seconds: 300

limit_detection:
  status_codes: [402, 403, 429]
  body_markers: ["rate limit", "quota", "limit"]

logging:
  level: "INFO"
  jsonl_path: "logs/llm-router.jsonl"
  log_request_body: false
  log_response_body: false
  log_prompt_chars: false
  log_headers: false

Für langsame lokale LLMs kann runtime.request_timeout_seconds: null gesetzt bleiben. Dann begrenzt der Router nur den Verbindungsaufbau, bricht eine laufende Antwort aber nicht wegen eines Read-Timeouts ab.

Wenn alle sofort nutzbaren Backends mit Fehlern antworten, gibt der Router standardmaessig den letzten Backend-Fehler unveraendert an den Client zurueck. Das verhindert, dass Clients wie Kimi auf einen generischen Router-Fehler warten oder unklar weiterlaufen. Pro Policy kann das mit return_last_error_on_exhausted_backends: false deaktiviert werden.

Ein Modell kann gezielt nur auf einem Backend angeboten werden, z.B. backends: ["vm"]. Fuer knappe Ollama-Hosts setzen die systemd-Beispiele OLLAMA_MAX_LOADED_MODELS=1, OLLAMA_NUM_PARALLEL=1 und OLLAMA_MAX_QUEUE=2.


Sicherheit

  • Router bindet standardmäßig an 127.0.0.1
  • API-Keys werden nur via Env-Variablen referenziert (api_key_env)
  • Keine Secrets im Code, keine Secrets in Logs
  • Prompts und Responses werden standardmäßig nicht geloggt

Mehr in docs/security.md


Troubleshooting

Problem Lösung
Config-Fehler llm-router check-config --config configs/router.local.yaml
Backend nicht erreichbar llm-router test-backends --config configs/router.local.yaml
Modell unbekannt Alias in Config prüfen oder unknown_model_strategy: passthrough
Logs lesen tail -f logs/llm-router.jsonl | jq .
Kimi CLI antwortet nicht Router läuft? Modellname in Kimi Config = Alias im Router?

Dokumentation


Lizenz

MIT

About

No description, website, or topics provided.

Resources

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors