Konfiguration
Vollständiges Beispiel: configs/config.example.json. ${VAR}-Platzhalter werden beim Laden aus der Umgebung ersetzt (z.B. für Tokens).
endpoints — die Ollama-Server
Abschnitt betitelt „endpoints — die Ollama-Server“"endpoints": [ { "name": "gpu-server", "url": "http://192.168.6.80:11436", "max_inflight": 2, "priority": 0 }, { "name": "cpu-server", "url": "http://192.168.6.80:11434", "max_inflight": 2, "priority": 1 }]| Feld | Bedeutung |
|---|---|
name | eindeutiger Name (erscheint in Logs, CLI, API) |
url | Basis-URL des Ollama-Servers |
max_inflight | max. gleichzeitige Anfragen an diesen Server (Default 2 — kleine Server verkraften wenig Parallelität) |
priority | bei gleicher Auslastung gewinnt die kleinere Zahl (z.B. GPU vor CPU) |
Der Pool pingt jeden Server regelmäßig (/api/version), holt die Modell-Liste (/api/tags) und schickt Anfragen nur an gesunde Server, die das benötigte Modell haben. Fällt ein Server aus, übernehmen die anderen automatisch; kommt er zurück, wird er wieder eingebunden. Laufende Anfragen mit Transportfehler werden automatisch auf dem nächsten Server wiederholt.
pool — Health-Check-Verhalten
Abschnitt betitelt „pool — Health-Check-Verhalten“| Feld | Default | Bedeutung |
|---|---|---|
health_interval_sec | 15 | Ping-Intervall |
ping_timeout_sec | 3 | Timeout pro Ping |
fail_threshold | 3 | so viele Fehlschläge in Folge → Server gilt als down |
recover_threshold | 2 | so viele Erfolge in Folge → Server wieder aktiv |
tags_refresh_every_n_pings | 4 | wie oft die Modell-Liste aktualisiert wird |
request_timeout_sec | 900 | Timeout pro Chat-Anfrage — bewusst großzügig: lokale Modelle auf schwacher Hardware brauchen legitim mehrere Minuten |
models — welches Modell für welche Aufgabe
Abschnitt betitelt „models — welches Modell für welche Aufgabe“"models": { "default": "qwen3.5:9b", "default_category": "chat", "tasks": { "router": { "models": ["mistral:latest"], "options": { "temperature": 0 } }, "chat": { "models": ["qwen3.5:9b", "llama3.1:8b"] }, "code": { "models": ["qwen3-coder:latest", "qwen3.5:9b"] }, "summarize": { "models": ["mistral:latest"] } }}- Jede Task-Kategorie hat eine Präferenzliste; das erste Modell, das auf einem gesunden Server liegt, gewinnt. Ist keines verfügbar, greift
default. - Die Kategorie-Namen sind frei wählbar — mit zwei Sonderrollen:
router(das Klassifikations-Modell, klein und schnell wählen!) undsummarize(wird auch für die History-Kompaktierung genutzt). optionssind Ollama-Optionen (temperature,num_ctx, …), die bei jedem Call dieser Kategorie mitgeschickt werden.- Modellnamen ohne Tag matchen jeden Tag:
qwen3.5findetqwen3.5:9b.
Wie wird die Kategorie bestimmt? In dieser Reihenfolge:
- explizit vom Aufrufer (
--category, API-Feld, Job-Definition) - kostenlose Heuristiken (Code-Blöcke →
code, “fasse zusammen”/“tl;dr” →summarize) - das
router-Modell klassifiziert den Input (JSON-Schema-erzwungene Antwort, Temperatur 0) - Fallback:
default_category
agent — der Tool-Loop
Abschnitt betitelt „agent — der Tool-Loop“| Feld | Default | Bedeutung |
|---|---|---|
max_iterations | 10 | max. Tool-Runden pro Anfrage |
max_tools_per_call | 8 | max. Tools, die das Modell pro Call angeboten bekommt |
max_tool_result_chars | 4000 | Tool-Ergebnisse werden hierauf gekürzt |
history_budget_ratio | 0.8 | ab dieser Füllung des Kontextfensters wird die History zusammengefasst |
system_prompt | … | Basis-System-Prompt (kurz halten!) |
web — eingebaute Internet-Tools
Abschnitt betitelt „web — eingebaute Internet-Tools“"web": { "enabled": true, "search_url": "", "max_page_chars": 6000, "max_results": 5, "timeout_sec": 30 }Der Agent bekommt zwei Tools, beide mit einer Kompressionsschicht für kleine Modelle:
web_search: Websuche (Standard: DuckDuckGo-HTML, kein API-Key nötig;search_urlkann auf eine eigene SearXNG-Instanz zeigen). Liefert nummerierte Treffer mit Titel, URL, Snippet.web_fetch: Seite abrufen und gefiltert zurückgeben — Skripte, Styles, Navigation, Footer und Boilerplate werden entfernt, übrig bleibt der lesbare Hauptinhalt in kompakter Markdown-Form (Überschriften, Absätze, Listen, Tabellen, Code). Modi:text(Default),links(nummerierte Link-Liste),meta(Titel/Beschreibung/Größe). Lange Seiten werden beimax_page_charspaginiert; das Tool sagt dem Modell, wie es mitpage=2weiterliest. Nicht-HTML-Inhalte (JSON-APIs, Textdateien) werden direkt durchgereicht.
Kein JavaScript-Rendering — für Seiten, die zwingend einen echten Browser brauchen, lässt sich später ein Browser-MCP-Server (z. B. Playwright) unter mcp_servers anbinden; für Analyse und Recherche reicht die eingebaute Schicht und bleibt dabei klein genug für 4B–26B-Modelle.
skills — Verzeichnisse mit Skill-Ordnern
Abschnitt betitelt „skills — Verzeichnisse mit Skill-Ordnern“"skills": { "dirs": ["./skills"], "auto_load_on_trigger": true, "allow_scripts": false }auto_load_on_trigger lädt einen Skill automatisch, wenn eine seiner triggers im Prompt vorkommt. allow_scripts erlaubt Skill-Scripts auszuführen (Vorsicht: führt Code aus). Details und ein Beispiel-Skill: Plattform erweitern.
mcp_servers — externe Werkzeuge per MCP anbinden
Abschnitt betitelt „mcp_servers — externe Werkzeuge per MCP anbinden“"mcp_servers": [ { "name": "files", "transport": "stdio", "command": "mcp-filesystem-server", "args": ["/pfad/zum/projekt"], "tool_tags": ["tool_calling", "code"] }, { "name": "web", "transport": "http", "url": "http://127.0.0.1:9090/mcp", "headers": { "Authorization": "Bearer ${WEB_MCP_TOKEN}" } }]stdio startet den Server als Subprozess, http verbindet sich mit einem laufenden Streamable-HTTP-MCP-Server. tool_tags filtert, in welchen Task-Kategorien die Tools des Servers überhaupt angeboten werden — ohne Angabe stehen sie überall zur Verfügung. ${WEB_MCP_TOKEN} wird beim Laden aus der Umgebung expandiert, das Token landet nie im Klartext in der Datei. Mehr dazu: Plattform erweitern.
scheduler — wiederkehrende Agent-Aufgaben
Abschnitt betitelt „scheduler — wiederkehrende Agent-Aufgaben“"scheduler": { "enabled": true, "state_dir": "~/.ollama-agent/state", "jobs": [ { "id": "daily-digest", "schedule": "0 7 * * *", "prompt": "Fasse die wichtigsten Ereignisse der letzten 24 Stunden zusammen.", "category": "summarize", "overlap": "skip", "enabled": true } ]}schedule versteht Standard-Cron (5 Felder) sowie @hourly, @daily, @every 10m usw. overlap: "skip" verhindert, dass ein noch laufender Job durch den nächsten Zeitpunkt erneut gestartet wird. Zur Laufzeit per API angelegte Jobs (POST /v1/jobs) laufen nur, solange der Daemon läuft — sie landen nicht in dieser Datei. Details: Zeitgesteuerte Jobs.
api, log
Abschnitt betitelt „api, log“api.addr: Adresse des Daemons (Default127.0.0.1:2330);api.auth_token: wenn gesetzt, braucht jede API-AnfrageAuthorization: Bearer <token>(siehe HTTP-API-Referenz).log.level:debug|info|warn|error;log.format:text|json.