Zum Inhalt springen

Konfiguration

Vollständiges Beispiel: configs/config.example.json. ${VAR}-Platzhalter werden beim Laden aus der Umgebung ersetzt (z.B. für Tokens).

"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 }
]
FeldBedeutung
nameeindeutiger Name (erscheint in Logs, CLI, API)
urlBasis-URL des Ollama-Servers
max_inflightmax. gleichzeitige Anfragen an diesen Server (Default 2 — kleine Server verkraften wenig Parallelität)
prioritybei 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.

FeldDefaultBedeutung
health_interval_sec15Ping-Intervall
ping_timeout_sec3Timeout pro Ping
fail_threshold3so viele Fehlschläge in Folge → Server gilt als down
recover_threshold2so viele Erfolge in Folge → Server wieder aktiv
tags_refresh_every_n_pings4wie oft die Modell-Liste aktualisiert wird
request_timeout_sec900Timeout pro Chat-Anfrage — bewusst großzügig: lokale Modelle auf schwacher Hardware brauchen legitim mehrere Minuten
"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!) und summarize (wird auch für die History-Kompaktierung genutzt).
  • options sind Ollama-Optionen (temperature, num_ctx, …), die bei jedem Call dieser Kategorie mitgeschickt werden.
  • Modellnamen ohne Tag matchen jeden Tag: qwen3.5 findet qwen3.5:9b.

Wie wird die Kategorie bestimmt? In dieser Reihenfolge:

  1. explizit vom Aufrufer (--category, API-Feld, Job-Definition)
  2. kostenlose Heuristiken (Code-Blöcke → code, “fasse zusammen”/“tl;dr” → summarize)
  3. das router-Modell klassifiziert den Input (JSON-Schema-erzwungene Antwort, Temperatur 0)
  4. Fallback: default_category
FeldDefaultBedeutung
max_iterations10max. Tool-Runden pro Anfrage
max_tools_per_call8max. Tools, die das Modell pro Call angeboten bekommt
max_tool_result_chars4000Tool-Ergebnisse werden hierauf gekürzt
history_budget_ratio0.8ab dieser Füllung des Kontextfensters wird die History zusammengefasst
system_promptBasis-System-Prompt (kurz halten!)
"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_url kann 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 bei max_page_chars paginiert; das Tool sagt dem Modell, wie es mit page=2 weiterliest. 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": { "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": {
"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.addr: Adresse des Daemons (Default 127.0.0.1:2330); api.auth_token: wenn gesetzt, braucht jede API-Anfrage Authorization: Bearer <token> (siehe HTTP-API-Referenz).
  • log.level: debug | info | warn | error; log.format: text | json.