Webseite: https://cailama.org/
Ecosystem-Doku:
- Human-Referenz: https://cailama.org/reference.html
- LLM-Einstieg: https://cailama.org/llms.txt
- LLM-Markdown: https://cailama.org/ecosystem-reference.md
- Maschinenlesbar: https://cailama.org/data/ecosystem.json
Generic local LLM routing gateway with OpenAI-compatible API, model aliases, backend fallback and JSONL logging.
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)
- 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 Verteilung –
round_robinverteilt 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
git clone git@github.com:TotoBa/LLM-Router.git
cd LLM-Router
python3 -m venv .venv
source .venv/bin/activate
pip install -e ".[dev]"cp configs/router.example.yaml configs/router.local.yaml
cp .env.example .envBearbeite configs/router.local.yaml und passe backends an deine IPs an.
llm-router serve --config configs/router.local.yamlcurl http://127.0.0.1:18080/health
curl http://127.0.0.1:18080/v1/modelsllm-router smoke-test --model default --prompt "Antworte nur OK."Für einen dauerhaften Router-VM + Pi-Ollama Rollout siehe:
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-TestKimi 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
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-researcherDas 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
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: falseFü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.
- 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
| 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? |
- Architektur – Systemdesign
- Konfiguration – Alle Config-Optionen
- Backends – Ollama, RasPi, Netzwerk
- Kimi CLI – Anbindung Kimi
- Schachsystem – Anbindung Schachsystem
- Fallback – Fehlerbehandlung
- Logging – Logs und Datenschutz
- systemd-Deployment – Autostart
- VM + Pi Rollout – Beispielhafter Betrieb auf zwei Hosts
- Security – Best Practices
MIT
