Hermes Agent Cron-Upgrade: monitor-mode, notepad und Preflight-Validierung

Geplante Aufgaben gehören zu den praktischsten Automatisierungsfunktionen von Hermes Agent: morgens um 9 Uhr die Hacker-News-Startseite abgreifen, alle 30 Minuten den Build prüfen, stündlich den Feed zusammenfassen. Doch je mehr Jobs laufen, desto deutlicher zeigen sich die Probleme — die meisten Ticks verbrennen Tokens für reine Wiederholung, ein falsch konfigurierter Job verschwendet einen ganzen LLM-Aufruf, bevor er scheitert, und Zustand zwischen Läufen weiterzureichen („Wo bin ich beim letzten Mal stehen geblieben?“) bedeutet, sich externe Dateien anzubauen.
Das Batch, das Anfang August 2026 auf main landete, stattet cron mit drei entscheidenden Bausteinen aus:
- monitor-mode — ein günstiges Skript oder eine URL läuft zuerst bei jedem Tick; bleibt der Hash der Ausgabe unverändert, wird der gesamte Agent-Lauf zu null LLM-Kosten unterdrückt;
- notepad — ein dauerhafter Key/Value-Scratchpad pro Job, der über geplante Läufe hinweg überlebt (Cursor, Watermarks, Watchlists);
- preflight — validiert die Job-Konfiguration, bevor irgendeine Agent-Mechanik aufgebaut wird; ein defekter Job wird als
blocked_configmarkiert, warnt einmal und gibt nie einen Token aus.
Dazu kommt ein usage_audit.jsonl-Logger, der den Token-Verbrauch jedes Cron-Laufs ehrlich protokolliert. Dieser Beitrag behandelt alle vier, mit echten CLI-Beispielen und Config-Keys.
1. monitor-mode: erst schnüffeln, nur bei Änderung laufen
Warum es das gibt
Der klassische Monitoring-Job sieht so aus: „Prüfe alle 5 Minuten, ob der Feed neue Einträge hat, und fasse sie zusammen, wenn ja.“ Ohne monitor-mode baut Hermes bei jedem Tick den vollen Agenten auf und ruft das LLM — man zahlt also für ein „es ist nichts passiert“-Ergebnis, so oft der Feed ruhig bleibt.
monitor-mode zieht die Erkennung von Änderungen aus dem Agenten heraus: Bei jedem Tick holt ein günstiges Skript (oder ein begrenzter GET-Request) die Ausgabe der Monitor-Quelle, die als exakte Bytes gehasht wird:
- Hash unverändert → der gesamte Agent-Lauf wird unterdrückt und als stiller
no_change-Tick protokolliert (kein LLM-Verbrauch, keine Zustellung); - Hash verändert → ein
MONITOR CHANGE DETECTED-Block (ein gekappter Unified-Diff plus die neue Ausgabe) wird in den Prompt injiziert und der Agent läuft normal; - Der erste Tick läuft immer (er legt die Baseline fest);
- Eine fehlschlagende Monitor-Quelle gilt als Konfigurationsfehler — der Job überspringt nie stillschweigend.
Verwendung
Aus der CLI erstellen:
# Monitor-Quelle = ein Skript (relativ zu ~/.hermes/scripts/ aufgelöst, oder absoluter Pfad)
hermes cron create "every 5m" \
"Summarize any new items on the page" \
--monitor-script feed_watch.sh
# Monitor-Quelle = eine URL (ein begrenzter GET pro Tick)
hermes cron create "every 5m" \
"Summarize changes on the status page" \
--monitor-url https://status.example.com/api/health
# Bestehenden Job aktualisieren
hermes cron edit <job_id> --monitor-script feeds.sh
Aus dem Chat heraus, über das cronjob-Tool:
cronjob(
action="create",
schedule="every 5m",
prompt="Summarize any new items on the page",
monitor_script="feed_watch.sh",
)
Drei Einschränkungen (beim Anlegen erzwungen, im Quellcode)
monitor_scriptundmonitor_urlschließen sich gegenseitig aus — eine Monitor-Quelle pro Job;- monitor-mode ist nicht kompatibel mit
no_agent=True— der Sinn ist schließlich, den Agenten zu unterdrücken oder zu wecken; reine Skript-Jobs sollten den regulärenscript-Modus verwenden; - das Monitor-Skript sollte stabile Ausgabe liefern (keine Timestamps), sonst unterscheidet sich jeder Hash und der Job feuert bei jedem Tick.
--monitor-script folgt denselben Auflösungsregeln wie script: relative Pfade werden unter ~/.hermes/scripts/ aufgelöst, .sh/.bash laufen über bash, alles andere als Python. Die Implementierung steckt in create_job, die Hash-Unterdrückung des Schedulers in cron/jobs.py.
2. notepad: dauerhafter Zustand über Läufe hinweg, ohne externe Dateien
Warum es das gibt
Zustandsbehaftete Jobs haben einen klassischen Schmerzpunkt: Job A nimmt um 2 Uhr nachts Daten auf, Job B verarbeitet um 8 Uhr „nur das Neue“ — wo lebt der „zuletzt gesehen“-Cursor? Bisher schrieb man ihn in eine lokale Datei und kümmerte sich selbst um Nebenläufigkeit und Aufräumen. notepad macht das zur erstklassigen Funktion: ein dauerhafter Key/Value-Scratchpad pro Job, gespeichert in einer eigenen SQLite-Datenbank (~/.hermes/cron/notepad.db). Bei jedem Lauf rendert der Scheduler einen nicht-leeren notepad in den Job-Prompt — der Agent sieht den Zustand früherer Läufe und aktualisiert ihn während des Laufs über die CLI.
Verwendung
# Den notepad des Jobs auflisten (Standardaktion)
hermes cron notepad <job_id>
# Einen Key lesen
hermes cron notepad <job_id> get cursor
# Einen Key schreiben
hermes cron notepad <job_id> set cursor 128
# Einen Key löschen
hermes cron notepad <job_id> delete cursor
Passt natürlich neben monitor-mode: Nach einer erkannten Änderung schreibt der Job „verarbeitet bis Eintrag N“ in seinen notepad, sodass der nächste Tick genau weiß, wo es weitergeht. Größenlimits — ein übermäßig großer Write scheitert lautstark, statt stillschweigend zu kürzen:
- 16 KB pro Wert;
- Keys bis zu 128 Zeichen;
- 64 KB insgesamt pro Job.
Der Lesepfad injiziert den notepad-Inhalt an derselben Nahtstelle in den Job-Prompt wie die context_from-Ausgabe; der Schreibpfad ist der laufende Agent, der hermes cron notepad ... set aufruft. Implementierungsdetails stehen in cron/notepad.py, das demselben Verbindungs-/Pragma-Muster folgt wie cron/executions.py.
3. preflight: ein defekter Job warnt einmal und gibt nie einen Token aus
Warum es das gibt
Cron-Jobs brechen am häufigsten nicht wegen schlechtem Code — sondern wegen driftender Umgebung: ein Provider-API-Key ist abgelaufen, einem angehängten Skill fehlt eine Env-Var, die Zustellungs-Credentials sind veraltet. Das alte Verhalten: Der Tick läuft, der Agent wird gebaut, das LLM wird aufgerufen, und erst dann scheitert es — Geld ausgegeben, und der Fehler ist oft undurchsichtig.
preflight validiert die Job-Konfiguration bevor irgendeine Agent-Mechanik aufgebaut wird (laut Quellcode und offizieller cron.md-Doku):
- der Provider-API-Key ist auflösbar (übersprungen, wenn eine
fallback_providers-Kette konfiguriert ist, da der Fallback-Pfad einen fehlenden Primär-Key retten kann); - angehängte Skills sind bereit (keine fehlenden erforderlichen Umgebungsvariablen, Befehle oder Credential-Dateien);
- die Ziele des Zustellungs-Kanals sind bekannt und haben Gateway-Credentials (
local/origin-Ziele werden nie geprüft).
Im Fehlerfall:
- der
last_statusdes Jobs wirdblocked_config; - genau eine Benachrichtigung wird zugestellt (ein
preflight_alerted-Dedup-Marker — kein Tick-Bombardement), bei Erholung zurückgesetzt, sodass ein künftiger Bruch erneut alarmiert; - null LLM-Aufrufe — ein falsch konfigurierter Job gibt nie Tokens aus.
Standardmäßig aktiv über cron.preflight: true. So stellst du das alte Verhalten wieder her:
# config.yaml
cron:
preflight: false
# oder auf der Kommandozeile
hermes config set cron.preflight false
Alle Prüfungen scheitern offen — ein preflight-Problem selbst blockiert nie einen Lauf, ein gesunder Job wird also nicht versehentlich gestoppt.
4. usage_audit: ein Token-Kassenbuch für cron
Dasselbe Batch brachte auch einen Teil der Cron-Token-Leak-Minderung mit: Cron-Sitzungen starten keine Hintergrund-Review mehr (skip_background_review), und ein Audit-Log des Token-Verbrauchs pro Ausführung liegt jetzt unter ~/.hermes/cron/usage_audit.jsonl — eine JSONL-Zeile pro Lauf. Wenn du quantifizieren willst, wie viel monitor-mode dir tatsächlich gespart hat, ist diese Datei die Antwort.
5. Alles zusammen: ein günstiger, änderungsbewusster Monitoring-Job
Die drei Bausteine zu einem typischen „Site-Change-Monitor + inkrementelle Zusammenfassung“-Job verdrahten:
# 1) Monitor-Skript: stabile Ausgabe (z. B. die Titel der Feed-Einträge)
cat > ~/.hermes/scripts/feed_watch.sh <<'EOF'
#!/bin/bash
curl -s https://example.com/feed.xml | grep -o '<title>[^<]*</title>'
EOF
chmod +x ~/.hermes/scripts/feed_watch.sh
# 2) Monitor-Job anlegen: unveränderter Hash → stiller Skip
hermes cron create "every 5m" \
"Summarize new feed items and remember the last seen count in the notepad" \
--monitor-script feed_watch.sh \
--deliver telegram
Ab dann gilt: Feed unverändert → stiller no_change-Tick, null Tokens; Feed verändert → der Agent wacht auf, liest den Cursor aus seinem notepad, fasst die neuen Einträge zusammen, aktualisiert den Cursor und liefert an Telegram. Budgetbewusste Nutzer können am Monatsende usage_audit.jsonl gegenprüfen.
6. Wann man diese NICHT nutzen sollte
- Muss-bei-jedem-Tick-laufen-Jobs (stündliche Chimes, Heartbeat-Keep-alives) brauchen keinen monitor-mode — er fügt nur eine sinnlose Änderungsprüfung hinzu;
- notepad ist pro Job, kein jobübergreifender Speicher — verdrahte Jobs mit
context_fromoder externem Storage, wenn Daten zwischen Aufgaben fließen müssen; - reine Skript-Jobs, die den Agenten komplett überspringen sollen: nutze das bestehende
no_agent=True+script, zwinge ihnen keinen monitor-mode auf.
Zusammenfassung
Diese drei Bausteine verwandeln cron von einem „geplanten Geldverbrenner“ in einen „On-Demand-Wecker“: monitor-mode spart (null Kosten, wenn nichts passiert ist), notepad erinnert sich (Zustand überlebt Läufe), preflight stabilisiert (kein Token-Verbrauch bei defekter Konfiguration, eine Warnung). Für alle, die eine Flotte geplanter Jobs betreiben, ist das eine echte Kostenreduktion und ein Operations-Gewinn.
Neu bei cron? Starte mit unserem kompletten Leitfaden zur Hermes-Agent-Cron-Automatisierung; halte langlaufende Hintergrundaufgaben mit dem Config-Leitfaden für lange Tasks am Laufen; weitere tägliche Effizienztipps gibt es in unserer Sammlung zu Hermes-Agent-Produktivitätstipps. Noch nicht installiert? Der Installations-Leitfaden bringt dich in fünf Minuten zum Laufen.