Hermes auf dem Raspberry Pi: Setup, Desktop-App und zwei Stolpersteine

10.06.2026 11:20

Seit Anfang Juni läuft bei mir ein Hermes-Agent auf einem Raspberry Pi 5 — rund um die Uhr, mit voller Shell, eigenem Telegram-Zugang und seit dieser Woche mit nativer Desktop-App als Oberfläche. Hier die Reihenfolge, in der das Setup entstanden ist, und die zwei Stellen, an denen es hakte: ein Cronjob, der Telegram vollspammte, und ein Update, das das Dashboard mitnahm.

Ausgangslage

Hermes ist ein Open-Source-Agent-Harness von Nous Research (MIT-Lizenz): ein Python-Programm, das ein Sprachmodell mit Werkzeugen verbindet — Shell, Browser, Dateisystem, Messaging — und es damit selbständig Aufgaben abarbeiten lässt, inklusive eigenem Gedächtnis und Skill-Bibliothek. Das Modell ist frei wählbar; jeder OpenAI-kompatible Endpoint funktioniert, vorausgesetzt mindestens 64K Kontext und serverseitiges Tool-Calling. Bei mir löst Hermes das vorherige Experiment mit OpenClaw ab.

Die Grundsatzentscheidung vor der Installation: eigene Hardware statt Container auf dem Homeserver. Ein Agent, der mit voller Autonomie laufen soll, bekommt eine eigene physische Box. Wenn etwas schiefgeht, ist der Schaden auf diese Box begrenzt — neben meinen anderen Diensten hätte ich ihn nicht haben wollen.

Die Box

Raspberry Pi 5 mit 8 GB RAM, 1-TB-NVMe statt SD-Karte, Tower-Kühler im Pironman-Gehäuse, headless, im Dauerbetrieb bei 3–5 Watt. Zugriff von außen ausschließlich über Tailscale, ein Mesh-VPN, das die eigenen Geräte in ein privates Netz hängt — nichts an diesem Setup ist aus dem Internet erreichbar.

Einziger Hardware-Stolperer: Die NVMe (WD SN580) fiel unter Schreiblast vom PCIe-Bus. Gelöst mit nvme_core.default_ps_max_latency_us=0 pcie_aspm=off in der cmdline.txt plus PCIe auf Gen1 — für den Agenten-Workload spielt die reduzierte Bus-Geschwindigkeit keine Rolle.

Autonomie als bewusste Entscheidung

Hermes läuft bei mir im maximal autonomen Modus: approvals.mode: off (keine Rückfragen vor Aktionen), lokales Terminal-Backend, passwortloses sudo, alle Werkzeuge inklusive Browser. Das ist kein Versehen, sondern der Punkt des Experiments — ein Coding- und Admin-Agent, der vor jedem Befehl um Erlaubnis fragt, ist keiner. Eine letzte eingebaute Grenze behält Hermes selbst in diesem Modus: eine nicht abschaltbare Blockliste für katastrophale Befehle wie rm -rf / oder Fork-Bombs. Alles darunter ist Sache des Betriebssystems — und der Leitplanken eine Ebene tiefer:

  • Eigene Box: Der Agent kann maximal seine eigene Maschine zerlegen, siehe oben.
  • Tailnet-only: Weder Gateway noch Dashboard sind je dem Internet ausgesetzt.
  • Guthaben-Limit: Der OpenRouter-Key hat ein hartes 10-Dollar-Limit. Ein Agent in einer Endlosschleife kostet damit schlimmstenfalls 10 Dollar.
  • Keine Schlüssel zu Produktivsystemen: Der Pi hat keine SSH-Keys zu Maschinen, auf denen etwas Wichtiges läuft. Das kommt erst, wenn sich der Agent über Monate bewährt hat.

Als Arbeitsmodell läuft DeepSeek v3.2 über OpenRouter (etwa 0,23/0,34 Dollar pro Million Token ein/aus), für Hilfsaufgaben Gemini 2.5 Flash Lite. Praxiswert: 10 Dollar halten bei Chat-Nutzung wochenlang — bei autonomen Goal-Loops eher ein bis drei Tage.

Stolperstein 1: der Cronjob, der nicht schweigen wollte

Hermes bringt einen eigenen Scheduler mit und legte sich — abgeleitet aus einem mitgelieferten Skill — selbständig einen stündlichen Health-Check-Cronjob an. Der Auftrag im Job-Prompt lautete sinngemäß „prüfe das System, melde dich nur bei Problemen". Das Ergebnis: jede Stunde ein voller Report per Telegram, 37 Stück, inhaltlich widersprüchlich („Hermes läuft nicht" / „Hermes läuft doch, das Script irrt sich").

Zwei Fehler überlagerten sich. Erstens hielt sich das Modell nicht an „melde dich nur bei Problemen" — es lieferte pflichtbewusst jede Stunde ab. Zweitens war das Health-Script, das sich der Agent selbst geschrieben hatte, kaputt: Es suchte einen systemd-Service, den es nie gab, und prüfte das Dashboard auf localhost, obwohl es an die Tailscale-IP gebunden ist.

Die Lösung steckt in Hermes selbst: Cronjobs haben einen No-Agent-Modus, in dem das Script der Job ist — ohne LLM-Beteiligung, ohne Token-Kosten. Die Zustell-Logik ist sauber definiert:

leerer stdout            → kein Versand (stiller Erfolg)
stdout vorhanden         → Inhalt geht wortwörtlich per Telegram raus
Exit-Code ≠ 0 / Timeout  → Fehler-Alarm an den Nutzer

Das neue Script prüft Gateway-Prozess, Dashboard-Port, SSH, Internet, Disk und RAM deterministisch — und gibt bei gesundem System nichts aus. Seitdem: Ruhe. Die Lehre ist verallgemeinerbar: Monitoring gehört nicht in LLM-Ermessen. Ein Sprachmodell zu bitten, nur bei Fehlern zu schreiben, ist eine Stilempfehlung; ein leerer stdout ist ein Kontrakt.

Die Desktop-App

Telegram als einziger Zugang wurde mir auf Dauer zu unbequem. Passend dazu erschien am 5. Juni das „Surface Release" 0.16.0, das Hermes neben CLI, TUI und Web-Dashboard eine vierte Oberfläche gibt: eine native Desktop-App (Electron) für macOS, Windows und Linux.

Die Überraschung nach der Windows-Installation: Die App ist per Default kein Client, sondern eine komplette zweite Hermes-Installation. Beim Setup landet unter %LOCALAPPDATA%\hermes ein vollständiger Checkout samt eigener Python-Umgebung, Config und Skills, und beim App-Start läuft ein lokales Backend. Wer seinen Agenten auf einem Server oder Pi betreibt, will stattdessen den Remote-Modus: Settings → Gateway → „Remote", als URL das Dashboard des Servers.

Dabei zwei Hürden, beide lösbar:

  1. Versionsgrenze. Der Remote-Anschluss für Desktop-Clients kam client- und serverseitig erst mit 0.16.0. Mein Pi lief noch auf 0.15.1 — ohne Update endet der Verbindungsversuch in einer Reconnect-Schleife. Also erst auf dem Pi hermes update, dann verbinden.
  2. Authentifizierung. Bis dahin lief mein Dashboard im --insecure-Modus: Zugriffsschutz war allein die Tailnet-Mitgliedschaft, intern arbeitete ein Session-Token, das bei jedem Neustart rotiert. 0.16.0 bringt einen Passwort-Provider mit — Benutzername plus scrypt-Hash in der .env, dazu ein Signing-Secret, damit Sessions Neustarts überleben. Das --insecure-Flag konnte weg; Desktop-App und Browser melden sich seitdem mit Benutzername und Passwort an.

Stolperstein 2: das Update, das das Dashboard mitnahm

Kaum verbunden, war die App wieder offline: „Your remote gateway session has expired." Tatsächlich abgelaufen war nichts — ein weiteres hermes update auf dem Pi hatte den Dashboard-Prozess per SIGTERM beendet und nicht neu gestartet. Der eigentliche Stolperdraht steckt in systemd: SIGTERM zählt dort standardmäßig als sauberer Exit, und die Service-Unit stand auf Restart=on-failure — der Neustart blieb aus, das Dashboard blieb tot.

Der Fix ist eine Zeile:

[Service]
Restart=always
RestartSec=5

Seitdem darf ein Update den Dashboard-Prozess beenden, so oft es will — systemd zieht ihn wieder hoch. Wer einen Dienst betreibt, den fremde Werkzeuge (Updater, Deploy-Skripte) per Signal beenden, fährt mit Restart=always robuster.

Fazit

Beide Pannen hatten dieselbe Wurzel: Der Agent verwaltet Teile seiner eigenen Infrastruktur — eigene Cronjobs, eigene Updates — und genau dort gehören die Leitplanken nicht ins Ermessen des Modells, sondern in deterministische Mechanik. Einsetzen würde ich das Setup für das, wofür es hier läuft: Experiment, Lernobjekt und persönlicher Assistent im eigenen Netz — für alles mit Zugriff auf Produktivsysteme noch nicht.

Stichworte

KI-Agenten Self-Hosting Raspberry Pi Hermes

Kommentare

Noch keine Kommentare. Schreib den ersten.

Melde dich an, um zu kommentieren.