Eine chinesische Antwort wurde zum Session-Titel: der Längen-Guard zählt nur Leerzeichen


Du wechselst das Modell, startest ein paar neue Sessions und suchst später die, in der du den Deploy-Plan besprochen hast. Die Sidebar zeigt einen ganzen Satz: 好的,这个可以做。不过我现在看不到代码,所以先把改造方案列出来…. Das ist kein Titel, das ist die Antwort des Modells. Und jede neue Session sieht so aus und zieht die Liste über den ganzen Bildschirm.

Das ist mehr als ein geschwätziges Modell. Das Modell hat die Anweisung, nur einen kurzen Titel zurückzugeben, tatsächlich ignoriert — aber Hermes hat einen Guard genau für diesen Fehlerfall. Er kann nur kein Chinesisch zählen. Gemeldet wurde das Problem am 20. Oktober 2026 (issue #141969). Hier kommen der Mechanismus, die Belege und drei Workarounds, die heute funktionieren.

Wie ein Titel entsteht

Titel entstehen in zwei Schritten. Zuerst kommt ein Instant-Titel, lokal aus deiner ersten Nachricht abgeleitet, ohne Modellaufruf. Dann kommt das Modell-Upgrade: ein Hintergrundaufruf bekommt eine Vorschau der Konversation und wird gebeten, einen kurzen Titel in einem JSON-Feld zurückzugeben.

Schritt zwei verhält sich normalerweise. Aber geschwätzige Modelle ignorieren manchmal das Format und antworten dem Nutzer stattdessen, wobei sie eine ganze Antwort als Inhalt des Feldes zurückgeben. Das nennt der Code answer-shaped output.

Der blinde Fleck: len(title.split())

Um das abzufangen, hat agent/title_generator.py eine einfache Obergrenze:

_MAX_TITLE_WORDS = 12
...
# Guard gegen answer-shaped Output: ein Titel mit vielen Wörtern stammt von einem
# Modell, das die Aufgabe ignoriert und stattdessen die Nachricht beantwortet hat.
if title is not None and len(title.split()) > _MAX_TITLE_WORDS:
    return None

Die Logik ist vernünftig: ein echter Titel läuft nicht über zwölf Wörter hinaus, während eine Antwort meist weit darüber liegt. Das Problem ist str.split(), das an Whitespace trennt. Englisch, Deutsch und Französisch sind wortgetrennt und verhalten sich brav; Chinesisch, Japanisch und Koreanisch nicht, also tokenisiert ein ganzer Satz zu einem, drei, vielleicht acht „Wörtern“.

Die Messungen im Issue stammen direkt aus einer echten state.db:

Was als Titel gespeichert wurde Zeichen len(split()) 12-Wörter-Guard
好的,这个可以做。不过我现在看不到 hermesbubble 的代码… 76 3 läuft durch
可以,直接在这说。先判断一个关键点:登录页本身能打开吗? 32 1 läuft durch
先确认一下:你说的 Hermes 是哪个项目/镜像? 80 8 läuft durch
我是 ChatGPT,由 OpenAI 开发。当前对话里没有提供… 73 4 läuft durch

Auf derselben Maschine hatten ältere Sessions, die vor dem Provider-Wechsel entstanden, alle ordentliche Titel mit 17–24 Zeichen. Anders gesagt: in leerzeichengetrennten Sprachen funktioniert der Guard, im Chinesischen existiert er praktisch nicht. In einer Hinsicht ist er schlimmer als nutzlos — die akzeptierte Antwort wird mit title_source='llm' persistiert und ist von einem echten Titel nicht zu unterscheiden, außer dass du dich erinnerst, was drinstand.

Die vorgeschlagene Richtung

Das Issue schlägt vor, den Guard script-aware zu machen: die Wortzahl für leerzeichengetrennten Text behalten und eine Zeichen-Obergrenze für CJK-Läufe ergänzen. Ein Titel hat typischerweise 10–25 chinesische Zeichen, während eine Antwort über 40 läuft, also lässt 30 Platz für einen mehrteiligen Titel:

_MAX_TITLE_WORDS = 12
# CJK hat keine Leerzeichen, also zählt len(split()) stark zu wenig. Ein Titel bleibt
# auch bei den Zeichen kurz; eine Antwort nicht. ~30 lässt Platz für einen echten
# mehrteiligen Titel.
_MAX_TITLE_CJK_CHARS = 30

def _cjk_char_count(text: str) -> int:
    return sum(1 for ch in text if
               "\u4e00" <= ch <= "\u9fff"      # CJK Unified Ideographs
               or "\u3040" <= ch <= "\u30ff"   # Hiragana/Katakana
               or "\uac00" <= ch <= "\ud7a3")  # Hangul

Zum Status, damit es klar ist: zum Zeitpunkt des Schreibens ist dieses Issue noch offen und kein Patch wurde gemergt. Was folgt, sind also Workarounds, die du jetzt nutzen kannst, keine Release-Note.

Drei Dinge, die du jetzt tun kannst

Eins: die Session umbenennen. hermes sessions rename nimmt eine Session-id und den neuen Titel:

hermes sessions rename 8f3c1d2a "deploy plan discussion"

Für die Historie, die schon einen Satz als Titel bekommen hat, behebt das die Fälle einzeln. Session-ids kommen aus hermes sessions list, ein Präfix genügt.

Zwei: den Instant-Titel behalten und das Modell-Upgrade stoppen. Der Instant-Titel wird aus deiner eigenen Nachricht abgeleitet, ist also von der Konstruktion her kurz. Schalte den Hintergrund-Modellaufruf ab:

hermes config set auxiliary.title_generation.model_upgrade_enabled false

Der Trade-off sind schlichtere Titel — sie spiegeln deinen ersten Satz, statt die Konversation zusammenzufassen.

Drei: Auto-Titel komplett abschalten. Wenn du Sessions sowieso selbst benennst:

hermes config set auxiliary.title_generation.enabled false

Neue Sessions bekommen dann keinen automatischen Titel und du benennst sie selbst. Beachte, dass auxiliary.title_generation.language die Titelsprache steuert (leer bedeutet: der Konversation folgen) — die Länge behebt das nicht, erwarte also nicht, dass du damit um diesen Bug herumkommst.

Die allgemeine Lehre

„Länge über Wörterzählen schätzen“ ist in einer einsprachigen Codebasis ein Reflex und in einem mehrsprachigen Produkt still falsch: kein Fehler, keine Warnung, nur eine Prüfung, die für manche Schriftsysteme lautlos durchläuft. Jeder Guard, der Länge oder Komplexität durch Trennen an Whitespace schätzt, sollte fragen, was passiert, wenn die Sprache keine Leerzeichen hat.

Ein paar verwandte Bereiche lohnen sich, wenn du auf Chinesisch oder in einer anderen CJK-Sprache arbeitest: Session-Grenzen und Archivierung behandelt der session boundaries guide; export, rename und --resume sind in der hermes sessions reference dokumentiert; und wenn deine UI-Sprache sich vom Modell unterscheidet, erklärt der language packs guide, welche Oberflächen der Einstellung folgen.

Die Kurzfassung

Ein Session-Titel wurde zu einer vollständigen Antwort, weil der Längen-Guard Wörter mit split() zählt und damit blind für CJK-Text ist: 76 chinesische Zeichen zählen als drei Wörter, eine Zwölf-Wörter-Grenze greift also nie. Kurzfristig hilft hermes sessions rename oder auxiliary.title_generation.model_upgrade_enabled abzuschalten und den Instant-Titel zu behalten; der echte Fix ist ein script-aware Guard, und der ist noch nicht gemergt.