Das zweite Modell, das du nie konfiguriert hast: Hermes' Lane für Hilfsaufrufe


An einem Montagmorgen öffnest du deine Session-Liste, und das wichtige Gespräch von gestern heißt {"title": "Fix the CI... — ein abgeschnittenes JSON-Fragment. Ein andermal stellst du das Hauptmodell auf ein billiges, schnelles um, und die Kommando-Freigabe wird seltsam: harmlose Befehle werden blockiert, offensichtlich gefährliche gehen durch. Jemand anders, der llama.cpp lokal laufen lässt, klagt, dass „eine Kompression mehrere Minuten dauert“. Diese drei Symptome wirken unabhängig, doch ihre Wurzel ist oft dieselbe unsichtbare Lane: Hilfsaufgaben (auxiliary tasks).

Die Aufruf-Lane, die du täglich benutzt und nie konfiguriert hast

Dein Hauptmodell macht nicht alles selbst. Neben dem Gespräch, das du siehst, feuert Hermes einen Strom kleiner Hintergrundanfragen ab:

  • Benennen jeder neuen Session;
  • Zusammenfassen, wenn das Kontextfenster vollläuft;
  • Klassifizieren, ob ein Befehl anhalten und dich fragen soll;
  • ein Vision-Modell bitten, ein Bild zu beschreiben, wenn dein Hauptmodell nur Text kann;
  • Skills-Suche, Umschreiben von Memory-Queries, Kanban-Aufgabenzerlegung, der /goal-Zufriedenheits-Judge, Mail-Scoring und der Selbst-Review am Turn-Ende, der Memory speichert oder einen Skill patcht.

Diese Aufgaben haben im Code Namen. Auf main gibt es 13 eingebaute:

Task key Anzeigename Was sie tut
vision Vision Bild-/Screenshot-Analyse (der Beschreiber für reine Text-Hauptmodelle)
compression Compression Kontext-Zusammenfassung
approval Approval Klassifizierer für die intelligente Kommando-Freigabe
mcp MCP Reasoning über MCP-Tools
title_generation Title generation Session-Titel
review Review der Reviewer-Subagent von /review
memory_query_rewrite Memory query rewrite schreibt Memory-Retrieval-Queries um
tts_audio_tags TTS audio tags Einfügen von Gemini-TTS-Tags
skills_hub Skills hub Skills-Suche und -Installation
triage_specifier Triage specifier erweitert eine Kanban-Triage-Notiz zu einer Spec
kanban_decomposer Kanban decomposer zerlegt eine Aufgabe in einen Graphen von Kindaufgaben
profile_describer Profile describer automatische Profilbeschreibungen
curator Curator Review-Durchlauf zur Skill-Nutzung

Dazu kommen goal_judge (/goal-Zufriedenheit), monitor (Scoring wichtiger Mails), background_review (der Selbstverbesserungs-Fork nach dem Turn) und die beiden MoA-Slots moa_reference / moa_aggregator. Sie erben standardmäßig dein Hauptmodell, weshalb du vielleicht monatelang „ein Modell macht alles“ gefahren hast, ohne zu bemerken, dass diese Lane existiert — bis sie bricht.

Die Konfigurationsform: ein Schlüssel entscheidet, auf welchem Modell eine Aufgabe läuft

Jede Aufgabe hat dieselbe Blockform:

auxiliary:
  # globale Schalter
  transient_retries: 2          # Wiederholungen beim selben Provider bei einem transienten Aussetzer, begrenzt auf 0..6
  free_only: false              # true = Hintergrundverkehr nutzt nie eine BEZAHLTE OpenRouter-Lane
  openrouter_model: ""          # überschreibt das OpenRouter-Modell der Auto-Kette
  stream_only_base_urls: []     # Endpunkte, die nicht-streamenden Chat ablehnen (HTTP 400)

  # ein Block pro Aufgabe, gleiche Form
  title_generation:
    enabled: true               # false = überhaupt keine Titel
    model_upgrade_enabled: true # false = den sofort abgeleiteten Titel behalten, nie ein Modell aufrufen
    provider: auto              # auto = das Hauptmodell erben
    model: ""                   # leer = dem Provider folgen
    prefer_fast_model: false    # true = die schnelle Stufe des Providers nutzen
    language: ""                # Sprache für die Titel
    timeout: 30
  approval:
    provider: auto
    model: ""                   # hier empfiehlt sich ein schnelles, günstiges Modell
    timeout: 30
  curator:
    timeout: 600                # der Skill-Review kann auf einem Reasoning-Modell Minuten dauern

Drei leicht zu machende Fehler:

  • provider: auto bedeutet „das Hauptmodell erben“ — es ist kein echter Provider-Name. Um ein bestimmtes günstiges Modell festzulegen, setze provider und model beide.
  • Die Timeouts sind nicht willkürlich gewählt: die Freigabe-Klassifizierung liegt standardmäßig bei 30 s (sie muss schnell sein), kanban_decomposer bekommt 180 s, curator 600 s. Kompression mit einem lokalen Modell ist der klassische Fall, in dem 120 s nicht reichen — die übliche Quelle für „die Kompression ist lokal so langsam“.
  • background_review hat ein zusätzliches max_input_tokens: 600000, das den Gesamtinput begrenzt, den der Selbst-Review erneut abspielt. Leite ihn auf ein anderes Modell um, und er spielt statt des vollständigen Gesprächs einen kompakten Auszug ab — grob 3–5× günstiger.

Der einfachste Ort für solche Änderungen ist der unterste Eintrag im Modell-Menü:

hermes model          # im Menü „Configure auxiliary models...“ wählen
hermes config get auxiliary.title_generation   # die effektiven Werte ansehen

Plugins können ebenfalls eigene Hilfsaufgaben registrieren, und sie erscheinen im selben Menü. Führe hermes config get <key> aus, bevor du irgendetwas konfigurierst — diese Schlüssel sind noch in Bewegung: in der v0.21.0-CLI dieser Maschine hat title_generation kein Feld model_upgrade_enabled, während main es bereits hat.

Die Charge vom 17. September: zehn Gesichter des stillen Fehlers

Am 17. September 2026 ist eine ganze Gruppe von Fixes für diese Lane gemergt worden. Was sie eint: ein Fehler wirft nie einen Fehler, er erzeugt nur ein seltsames Symptom.

Was du siehst Die eigentliche Ursache PR
Ein Titel, der manchmal ein JSON-Fragment ist die Titelgenerierung las reasoning_content als Prosa oder speicherte abgeschnittenes JSON #113960
Titel werden nie fertig, Wiederholungen stapeln sich kein Erholungspfad nach gestapelten Parameter-Ablehnungen #113958
Das Ausschalten des Modell-Upgrades lässt Titel leer der sofort abgeleitete Titel sollte überleben, aber ein Modellaufruf überschrieb ihn #113955
Ein toter Endpunkt blockiert den Hintergrundverkehr ewig Auto-Titel sollten nach einem Timeout-Fenster aufgeben und den Endpunkt nennen, der nicht geantwortet hat #113968
Nachdem das Hauptmodell sein Kontingent erreicht hat, stockt die ganze Lane der Durchlauf über fallback_providers übersprang keinen quotenbegrenzten Kandidaten #113965
DeepSeek gibt bei strukturierter Ausgabe 400 zurück und der Fallback stirbt mit ein 400 darf keine Fallback-Kandidaten töten und keinen aussichtslosen ersten Request kosten #113966
Alles im Hintergrund scheitert, sobald xAIs OAuth-Token abläuft Hilfsaufrufe sollten sich erholen, nicht scheitern #113964
Ein Custom-Provider gibt still ein 401 zurück key_cmd ist ein Callable, und fünf Auflösungszweige riefen entweder .strip() darauf auf oder schickten sein repr als Bearer-Token #114333
Eine lokale ollama-base_url wirkt nie diese Lane löste die lokale Adresse nie auf und rief den Server nie wirklich auf #113961
Das /goal-Judging scheitert mit einem undurchsichtigen Judge-Fehler es sollte sagen, dass die Nous-Authentifizierung fehlgeschlagen ist #113963

Die lehrreichste davon: ein Custom-Provider, der key_cmd nutzt, um bei Bedarf ein Token zu prägen (der einzig richtige Ansatz, wenn Credentials ablaufen). Die Haupt-Runtime reichte das zurückgegebene Callable immer unangetastet durch, während fünf Zweige des Hilfs-Clients einen String erwarteten — also stürzten sie entweder ab oder schickten <CommandTokenSource object at 0x…> als Bearer-Token an den Server. Das zweite Ergebnis ist schlimmer: es gibt keinen Fehler, es gibt nur still ein 401.

Warum solche Bugs so schwer aufzuspüren sind

Weil sie auf einem „auxiliary“-Pfad leben, der bewusst degradieren soll: ein fehlgeschlagener Titel darf deinen Chat nicht kaputtmachen, ein langsamer Freigabe-Klassifizierer soll auf eine Rückfrage zurückfallen, eine fehlgeschlagene Kompression braucht ein Sicherheitsnetz. Sauber zu degradieren ist richtiges Design, und der Preis dafür ist, dass Fehler verschluckt werden. Du siehst Symptome — seltsame Titel, nutzlose Freigaben, langsame Kompression — statt einer Fehlermeldung.

Daraus folgt eine sehr praktische Empfehlung: lege für jede Hilfsaufgabe ein schnelles, günstiges Modell fest (besonders für approval und title_generation). Wenn du dann das Hauptmodell wechselst, eines herabstufst oder vorübergehend keinen Zugriff darauf hast, bleibt das Hintergrundverhalten stabil — und beim Debuggen erkennst du sofort, ob „mein Hauptmodell hat sich geändert“ oder „die Hintergrund-Lane hat sich unter mir geändert“ gilt.

Release-Status

Jeder Fix oben ist am 17. September 2026 in main gemergt worden. Das neueste getaggte Release, v0.21.3 (Tag v2026.9.14, 14. September), enthält sie nicht. Prüfe, was du hast:

hermes --version
hermes config get auxiliary.title_generation

Wenn dich einer dieser Punkte gerade aktiv ärgert — JSON-Fragment-Titel und das stille 401 bei Custom-Providern sind die beiden schlimmsten —, führe hermes update aus und warte auf das nächste Tag, oder tracke in der Zwischenzeit main lokal.

Weiterlesen: um zu verhindern, dass Hilfsaufrufe Geld verbrennen, fang mit der Konfiguration des Reasoning-Aufwands an; häufige Kompression gehört zur selben Problemfamilie und wird in Kompression und der schlanke Schwanz behandelt; Timeouts und Port-Details, wenn ein lokales Modell deine Hilfsaufgaben fährt, stehen im lokalen llama.cpp-Leitfaden; und das Onboarding neuer Provider behandelt, worauf du achten musst, wenn du Hilfsaufgaben an einen neuen Anbieter hängst.

Zusammenfassung

  • Hermes hat eine Hintergrund-Aufruf-Lane (auxiliary) mit 13 eingebauten Aufgaben plus MoA- und Selbst-Review-Slots, die standardmäßig alle das Hauptmodell erben.
  • Jede Aufgabe hat denselben Konfigurationsblock: provider / model / base_url / api_key / timeout / extra_body / reasoning_effort; provider: auto bedeutet „dem Hauptmodell folgen“.
  • Um Geld zu sparen und berechenbar zu bleiben: lege günstige Modelle auf häufige kleine Aufgaben (approval, title_generation) und erhöhe den Timeout für compression, wenn ein lokales Modell sie übernimmt.
  • Die Charge vom 17. September behebt zehn stille Fehler (JSON-Fragment-Titel, ein hängender Quota-Fallback, das stille 401 bei Custom-Providern und mehr) und ist noch in keinem getaggten Release.