Skip to content

Architekturüberblick

源码版本v2026.7.20

Hermes Agent ist ein Open-Source-Desktop-Agent (MIT-Lizenz) von Nous Research. Die Kernpositionierung: «ein persistenter Agent, der mit dir wächst». Eine Nachricht kommt herein – von Telegram/Discord/Slack oder einer anderen Oberfläche – durchläuft die Hauptschleife, die Modell + Werkzeuge (tools) aufruft, um die Aufgabe zu erledigen, und die Erfahrung wird in Gedächtnis und Skills destilliert, um beim nächsten Mal wiederverwendet zu werden.

Schichtansicht

Jede Schicht in einem Satz

  • UI-Schicht: TUI / CLI / Web / ACP (Editor-Protokoll) — nur Eingänge, halten keine Geschäftslogik.
  • Gateway-Schicht: gateway/run.py vereinheitlicht den Zugriff; Plattformen sind Adapter (adapter); Sitzung (session) und Zustellung sind getrennt; Streams (streams) und Hooks sind steckbar.
  • Hauptschleife: run_conversation orchestriert «Modellaufruf → Werkzeugaufruf → Ergebnis-Rückfüllung → Budget-Dekrement (budget decrement)», mit Fallback (fallback) bei Misserfolg.
  • Fähigkeitsschicht: Tools sind atomare Funktionen (tools/registry.py); Skills sind höher geordnete, evolvierende Flüsse (von der Lernschleife umgeschrieben); Provider (provider)/MCP/Plugins (plugins) liefern Modelle und externe Fähigkeiten.
  • Planung & Erweiterung: Cron treibt geplante Aufgaben, Subagent delegiert isoliert (null Kontextkosten (context cost)), 6 Sandbox-Backends isolieren die Ausführung.
  • Lernschleife: Destilliert die Konversationserfahrung in Skills und ein Benutzermodell und bildet so das Flywheel, das den Agenten «besser, je mehr man ihn nutzt» macht.

Top-Down: repräsentative Signaturen jeder Schicht

Um Hermess Schichtung zu verstehen, genügt es, auf die «Signaturen» zu schauen, die jede Schicht im Code zeigt.

UI-Schicht → Weiterleiter an die Hauptschleife. Alle Hüllen rufen AIAgent.run_conversation auf, doch das ist nur eine Weiterleitung (run_agent.py:6350):

python
def run_conversation(self, user_message, system_message=None,
                     conversation_history=None, ..., moa_config=None) -> Dict[str, Any]:
    """Forwarder — see ``agent.conversation_loop.run_conversation``."""
    from agent.conversation_loop import run_conversation
    token = set_conversation_context(self._conversation_root_id())
    with scoped_runtime_main({}):
        return run_conversation(self, user_message, ...)

Die Konversations-ID wird über ein ContextVar nach unten gereicht — alle LLM-Aufrufe innerhalb der Hauptschleife (Kompression (compression), Vision, MoA-Slot, Background-Review-Fork) tragen automatisch das Tag.

Gateway-Schicht → Generaldirektor der Plattformadapter. GatewayRunner setzt Autorisierungs-/Kanban-/Slash-Command-Fähigkeiten über Mixins zusammen (gateway/run.py:22392); der Einstieg start_gateway(replace=True) killt zuerst die alte Instanz — ein Hintertürchen für den Fall, dass beim systemd-Neustart der alte Prozess nicht sauber beendet wurde:

python
class GatewayRunner(GatewayAuthorizationMixin, GatewayKanbanWatchersMixin, GatewaySlashCommandsMixin):
    """Main gateway controller. Manages the lifecycle of all platform adapters
    and routes messages to/from the agent."""

Hauptschleife → wo wirklich gearbeitet wird. run_conversation liegt in agent/conversation_loop.py und orchestriert «Modellaufruf → Werkzeugaufruf → Ergebnis-Rückfüllung → Budget-Dekrement» mit Fallback bei Misserfolg; Signatur siehe oben.

Fähigkeitsschicht → Werkzeugregistrierung. Jedes tools/*.py ruft beim Modul-Import registry.register auf (tools/registry.py:365); override=True ist nötig, damit Plugins eingebaute Tools überschreiben dürfen:

python
def register(self, name, toolset, schema, handler, check_fn=None,
             requires_env=None, is_async=False, description="", emoji="",
             max_result_size_chars=None, dynamic_schema_overrides=None, override=False):
    """Register a tool.  Called at module-import time by each tool file.
    ``override=True`` is an explicit opt-in for plugins ... Without it,
    registrations that would shadow an existing tool are rejected."""

Wer ein eingebautes Tool ersetzen will, muss explizit override=True setzen und die allow_tool_override-Konfiguration freischalten — das verhindert, dass ein Plugin heimlich das browser-Tool tauscht. Gleichnamige MCP-Tools laufen über einen separaten Kanal.

Planung & Erweiterung → der cron-tick. tick (cron/scheduler.py:3888) ist ein einzelner, durch eine Dateisperre geschützter Scan; das Gateway ruft ihn alle 60 Sekunden aus einem Hintergrundthread auf. Der Parameter adapters erlaubt Cron-Aufgaben, die bereits aufgebauten Plattformverbindungen des Gateways wiederzuverwenden, statt selbst neu zu verbinden.

Lernschleife → Konsolidierung des Lerngraphen. build_learning_graph (agent/learning_graph.py:248-328) fügt gelernte (nicht eingebaute) Skills und Erinnerungen zu Knoten/Kanten zusammen. Es ruft zuerst build_skill_nodes(_skill_roots()) auf, um zwei Wurzeln (base und profile) zu scannen, und filtert dann Skills mit source != "base" und created_by == "agent" oder use_count > 0 als «gelernte» heraus — eingebaute Skills kommen nicht in den Lerngraphen, damit das Evolutionssignal nicht von Rauschen überdeckt wird.

Schichtungs-Motiv

Warum diese Schichtung? In einem Satz: die Schichten, die sich ändern dürfen, dürfen die Schichten, die sich nicht ändern dürfen, nicht verschmutzen.

  • Die UI-Schicht wechselt häufig die Hülle (TUI/Web/IDE-Protokolle haben je eigene Iterationsrhythmen (iteration rhythm)) — ein Hüllenwechsel darf die Geschäftslogik nicht zwingen, sich zu ändern; deshalb hängen die Hüllen nur Callbacks ein (step_callback/event_callback) und dringen nicht in run_conversation ein.
  • In der Gateway-Schicht ist das Andocken neuer Plattformen die Norm (QQbot, Enterprise-WeChat, neue Discord-Stile) — aber die Hauptschleife soll von Plattformen nichts merken; deshalb ist die Plattformlogik reine Adapterlogik, und das Gateway entkoppelt nur Nachrichten und Agent-Aufrufe.
  • Die Fähigkeitsschicht ist das «Atom», die Lernschleife ist die «Evolution» — Atome dürfen nicht vom Evolutionspfad verschmutzt werden (sonst kollabiert die Hauptschleife mit, wenn ein Background-Review einen Bug in ein Tool schreibt); deshalb ändert learning_mutations skills/, nicht tools/.
  • Planung & Erweiterung ist ein Querschnitt: Cron und Subagenten «triggern die Hauptschleife außerhalb der Hauptschleife», sie teilen sich run_conversation, halten aber keinen direkten Agent-Zustand.

Häufige Missverständnisse

  • «Hermes ist ein Agent-Framework» — nein. Es ist eine konkrete Desktop-Agent-Implementierung; Hauptschleife, Tool-Set und Skill-Verzeichnis gehören zu Hermes selbst. Die Framework-artigen Fähigkeiten (MCP-, Plugin-, Provider-Abstraktionen) sind Grenzen, die es zum Erweitern freilegt, nicht sein Wesen.
  • «Die Lernschleife optimiert automatisch die Modell-Prompts» — nein. Sie ändert nur SKILL.md unter skills/ und das Gedächtnis unter ~/.hermes/skills/, nicht die System-Prompt-Templates (prompt templates). Prompt-Templates sind feste Dateien im Repo; sie zu ändern erfordert einen Release.
  • «Subagenten sind verteilt» — nein. Subagenten forken den Agenten innerhalb desselben Prozesses (teilen sich die Runtime); die Sandbox isoliert die Ausführung (Code läuft in Docker/SSH/Modal/Daytona), nicht eine Verteilung des Agent-Zustands.
  • «Gateway-Schicht = Nachrichtenplattform-Anbindung» — nur halb richtig. Das Gateway verwaltet auch Sitzungszustand (session/), Zustellungs-Dedup (delivery_ledger), Stream-Verteilung (stream dispatch) (stream_*), Slash-Commands, Kanban-Watcher — das sind alles Aufgaben «zwischen Nachrichtenplattform und Agent», nicht nur Anbindung.

Empfohlene Lesereihenfolge

  1. Start und Einstieg — wie ein Befehl zu einem laufenden Agenten wird
  2. Hauptschleife des Agenten — was beim Eintreffen einer Nachricht passiert
  3. Fähigkeitsschicht — der Unterschied zwischen Tools und Skills
  4. Gateway-Schicht — wie die Multi-Plattform-Zustellung funktioniert
  5. Planung & Erweiterung — Automatisierung und Isolation
  6. Lernschleife — der Mechanismus der Selbst-Verbesserung

Inoffizielle Community-Lernseite. Basiert auf dem MIT-lizenzierten NousResearch/hermes-agent-Quellcode.