Was hat dein Agent letzte Nacht gemacht? Hermes an OpenTelemetry anbinden

Du wachst auf, klappst den Laptop auf, und der Job, den du über Nacht mit „ich stell nur kurz die Config um“ laufen lassen hast, hat ein paar Dollar mehr gekostet als sonst. /status sagt dir die Gesamtzahl der Tokens und sonst nichts. Was du eigentlich wissen willst: Welcher Modellaufruf war langsam, welches Tool hat dreimal neu versucht, und welche Freigabe lag zwei Minuten herum und wartete auf einen Klick. Diese Timeline pro Aufruf liefert Hermes nicht mit — das Community-Plugin hermes-otel schließt genau diese Lücke: Es hängt Hermes an OpenTelemetry und macht aus einem Turn ein einziges Trace, das du Schicht für Schicht aufklappen kannst.
Die zwei eingebauten Observability-Oberflächen decken „genau diesen Aufruf“ nicht ab
Hermes bringt bereits zwei mit. Die erste ist das Gateway-Monitoring (monitoring.export.otlp), das die Gesundheit von Gateway und Cron überwacht und bewusst inhaltsfrei ist — keine Prompts, keine Tool-Aufrufe, keine Tokens. Die zweite ist das mitgelieferte Langfuse-Plugin, das Traces pro Lauf aufzeichnet, sie aber ausschließlich an Langfuse schickt.
hermes-otel ist die dritte, die Ebene pro Lauf, und sie läuft parallel zu beiden. Das Plugin hängt sich an die Lifecycle-Hooks des Hosts und installiert einen eigenen TracerProvider; es fasst also nie die privaten Provider-Objekte an, die der Core-Exporter baut. Die beiden Datensätze überschreiben sich nicht.
Installation: ein Befehl, ein Gateway-Neustart
Das Plugin steht im kuratierten Katalog (Community-Tier, gepinnt auf 1.18.2):
hermes plugins install hermes_otel
hermes plugins enable hermes_otel
Hermes 0.21 und neuer installiert die drei opentelemetry-*-Abhängigkeiten des Plugins in die eigene virtuelle Umgebung und wendet sie nach jedem hermes update erneut an. Starte danach jedes laufende Gateway neu.
Älter als 0.21 oder mit --no-deps installiert? Dann zieh die Abhängigkeiten selbst nach:
<hermes venv>/bin/pip install -r ~/.hermes/plugins/hermes_otel/requirements.txt
So sieht ein Turn aus, wenn du ihn aufklappst
Das Plugin bildet Host-Events auf Spans ab, ungefähr so:
agent / cron <- der Root-Span für den gesamten Turn
├── skill.{name} <- ein geladener Skill, offen bis der Turn endet
└── llm.{model} <- ein run_conversation
├── api.{model} <- ein HTTP-Roundtrip, mit Tokens und Finish Reason
│ ├── tool.{name} <- jeder Tool-Aufruf: Args, Ergebnis, Outcome
│ └── approval.{pattern} <- Warten auf einen Menschen oder den Smart Guardian
└── subagent.{role} <- delegate_task, das eigene Trace des Kindes hängt hier
api.*-Spans tragen ein Attribut hermes.query_source, das angibt, ob der Aufruf aus der Agent-Loop selbst kam (main), von einem delegierten Kind (subagent) oder im Auftrag des Agenten erfolgte (auxiliary — Titling, Kompression, Mixture-of-Agents-Aggregation); hermes.auxiliary.task benennt dabei den Job. Tool-Spans tragen hermes.tool.outcome: completed, error, timeout, blocked oder cancelled. Die Attribute werden sowohl in der OpenInference- als auch in der OTel-GenAI-Konvention ausgegeben, Phoenix und Langfuse funktionieren also ohne eigenes Mapping.
Konfigurieren mit einer YAML-Datei — oder einer Umgebungsvariable
Für ein einziges Backend brauchst du überhaupt keine Konfigurationsdatei:
export OTEL_PHOENIX_ENDPOINT=http://localhost:6006/v1/traces
Für mehrere legst du ~/.hermes/hermes_otel.yaml an:
project_name: hermes-agent
backends:
- type: phoenix
endpoint: http://localhost:6006/v1/traces # nur Traces
- type: lgtm
endpoint: http://localhost:4318/v1/traces # Traces + Metriken + Logs
metrics: true
- type: honeycomb
api_key: ${HONEYCOMB_API_KEY} # ${VAR} wird beim Laden aufgelöst
capture_logs: true
Die Backends werden parallel gefüttert, jedes mit einer eigenen Export-Queue. Im docker-compose/-Verzeichnis des Repos liegt ein fertiger Stack für jedes selbst hostbare Backend — Phoenix oder Jaeger lokal hochzuziehen ist damit der kürzeste Weg zum ersten Trace.
Datenschutz: standardmäßig voller Inhalt, also lieber auf Preview umstellen
Lies diesen Teil zuerst. Der Standard content_capture: full schickt den vollständigen Prompt und die vollständige Antwort jedes Modellaufrufs sowie Tool-Argumente und Ausgabe (auf 1200 Zeichen gekürzt) an das Backend, das du konfiguriert hast.
| Wert | Was den Prozess verlässt |
|---|---|
full |
Voller Prompt und volle Antwort, Tool-Inhalt auf 1200 Zeichen gekürzt |
preview |
Nur gekürzte Vorschauen |
off |
Keine Inhalte, nur Struktur |
Ohne konfiguriertes Backend hält das Plugin einen lokalen SQLite-Store unter $HERMES_HOME für sein Dashboard und schickt nichts nach außen. Bei mehreren Profilen: Jedes Profil hat seine eigene Installation, seine Einstellungen und seine Telemetrie, und ein gemultiplextes Gateway traced jedes Profil, das es bedient, unter dessen eigenem Namen.
Im Chat fragen, ohne ein Backend anzufassen
Das Plugin bringt einen Skill mit, hermes_otel:observability, samt Terminal-Query-Tool. Nach der Installation kannst du einfach fragen „warum war mein letzter Turn langsam?“ oder „was hat diese Session gekostet?“ — es liest den lokalen Live-Store, ein Backend ist nicht nötig:
python3 ~/.hermes/plugins/hermes_otel/skills/observability/scripts/otel.py trace last
Die Ausgabe ist ein lesbarer Waterfall mit Dauer pro Span, Tokens, Cache-Hits und Finish Reason. Die Subcommands umfassen status, traces, span, sessions, stats, metrics, logs sowie ein schreibgeschütztes sql — alle mit --json, --since und --source.
Wann du es besser weglässt
- Wenn du nur wissen willst, ob das Gateway lebt, ist das eingebaute Gateway-Monitoring leichter und bewusst inhaltsfrei.
- Wenn Langfuse dein einziges Backend ist, deckt dich das mitgelieferte Langfuse-Plugin bereits ab.
- Auf einer kleinen Kiste mit vielen winzigen Aufgaben kosten Spans pro Turn. Starte eine Woche lang mit
previewplus Sampling, bevor du es dauerhaft einschaltest.
Zwei ehrliche Grenzen: Das Verknüpfen von MCP-Server-Spans mit dem Agent-Trace ist auf Plugin-Seite implementiert, wartet aber noch auf Support im Host. Und das Plugin arbeitet fail-open — seine Exporter laufen in eigenen Threads, es ist also kein Audit-Log. Wenn du Nachweise brauchst, die einen Crash überleben, behalte den lokalen Store oder exportiere in ein Backend unter deiner Kontrolle.
Wenn du noch Plugins auswählst, fang mit so funktioniert der Plugin-Katalog an — hermes plugins search verrät dir, auf welchen Commit ein Plugin gepinnt ist. Um diese Spans in einem Browser-Arbeitsbereich zu durchstöbern, passt Hermes Workspace gut dazu, und die Befehlsdetails stehen in der hermes plugins-Referenz.