Telegram-DMs stapeln sich in einem Thread? Gib jeder neuen Nachricht ihr eigenes Topic


Du verfolgst drei Dinge gleichzeitig in Telegram: einen Production-Bug, den Entwurf eines Wochenberichts und ein Skript, das du einem Freund flickst. Also schaltest du den /topic-Modus ein und gibst jedem eine eigene Spur. Perfektes Setup – bis dein Daumen abrutscht und du eine Zeile direkt ins Hauptfenster des Chats tippst statt in ein Topic.

Diese Nachricht startet keinen neuen Thread. Sie landet in dem Topic, das du zuletzt benutzt hast. Jetzt sitzt in deinem Wochenbericht eine Debugging-Schlussfolgerung, und das Modell fängt fröhlich an, beides zu vermischen. Du scrollst eine Weile zurück, bis du die Stelle findest, an der es schiefging.

Der Topic-Modus ist nicht kaputt; er trifft eine konservative Entscheidung – eine Nachricht im Root-Chat heißt „setz die letzte Konversation fort“. Wenn du lieber möchtest, dass jede Root-Nachricht bei null anfängt, hat Hermes am 19. Oktober genau dafür einen Schalter gemerged: dm_topic_auto_transfer.

Wie sich der Topic-Modus heute verhält

Schick /topic in einer DM, und Hermes prüft, ob der Bot Topics anlegen darf (Threaded Mode muss in BotFather an sein), aktiviert den Multi-Session-Topic-Modus für diesen Chat, legt ein angepinntes System-Topic für Status und Befehle an und bietet an, frühere Sessions wiederherzustellen, die nie an ein Topic gebunden waren.

Von da an ist der Root-Chat eine Lobby: Normale Prompts werden mit einem Hinweis auf All Messages abgelehnt, während Systembefehle wie /status, /sessions, /usage und /help dort weiterhin funktionieren.

Jedes Topic ist eine eigenständige Session – eigene Historie, eigener Modellzustand, eigene Tool-Ausführung, eigene Session-ID. Der Isolationsschlüssel ist agent:main:telegram:dm:{chat_id}:{thread_id}, für Hermes sind zwei Topics in derselben DM also zwei verschiedene Konversationen.

Die Falte ist die konservative Entscheidung von oben: Manche Clients liefern eine im Root-Chat getippte Nachricht ohne message_thread_id aus. Hermes behandelt solche Nachrichten als Fortsetzung und antwortet in deinem zuletzt aktiven Topic – in der Doku Lobby-Recovery genannt. Die Erinnerung, die dich zurück in ein Topic schubsen soll, ist auf eine Nachricht pro 30 Sekunden pro (Profil, Chat) begrenzt, damit Vergessen und zehn Prompts hintereinander nicht zehn Antworten erzeugen.

Der Schalter: ein Konfigurationsschlüssel

Eine Zeile in der config.yaml deines Profils:

gateway:
  platforms:
    telegram:
      extra:
        dm_topic_auto_transfer: true   # default: false

Der Schlüssel telegram.extra.dm_topic_auto_transfer auf oberster Ebene funktioniert ebenfalls (das ist der, der in den Desktop-Einstellungen angezeigt wird). Er ist strikt opt-in: Lässt du ihn weg, ändert sich nichts, inklusive des Fallbacks auf dein zuletzt aktives Topic.

Ist er an, macht eine einfache Nachricht in der Root-DM Folgendes:

  1. Hermes legt sofort ein neues Topic an (genannt „Hermes Chat“, bis die Auto-Title-Pipeline es umbenennt);
  2. In diesem Topic startet eine neue Session;
  3. Deine Antwort wird in diesem Topic gepostet.

Mit anderen Worten: Der Root-Chat ist keine Lobby mehr, sondern eine Tür – eine verirrte Nachricht, ein brandneuer Raum.

Was nie verschoben wird

Dieser Schalter behandelt genau einen Fall – ein Mensch tippt eine einfache Nachricht in die Root-DM. Alles andere bleibt per Design unangetastet:

  • Slash-Commands werden nicht verschoben. Ein im Root getipptes /status bleibt ein Lobby-Befehl und legt nie ein Topic an.
  • Interne Wakes und geroutete Events werden nicht verschoben. Cron-Auslösungen, von anderen Plattformen hereingeroutete Events und Hintergrundaufgaben landen nie in einem frischen Topic.
  • Nicht-DM-Verkehr bleibt unberührt. Gruppen und Kanäle haben mit dem Topic-Modus nichts zu tun.
  • Nicht autorisierte Absender werden nicht verschoben. Die Autorisierungsprüfung passiert in der Lobby-Phase.
  • Eine gescheiterte Topic-Erstellung fällt zurück. Wurde Threaded Mode in BotFather abgeschaltet, scheitert das Anlegen, und Hermes fällt auf den Default zurück: in deinem zuletzt aktiven Topic antworten, statt die Nachricht fallen zu lassen.

Ein Implementierungsdetail ist es wert zu kennen: Die Übergabe läuft am Adapter-Ingress, vor dem Session-Keying (sie liegt in telegram_topic_transfer.py im Telegram-Plugin). Der Turn, seine Session und die Antwort nutzen also alle das neue Topic – du bekommst nie eine Session in einem Thread und die Antwort in einem anderen.

Zwei kleine Fallen

Erstens: Die erste Antwort in einem neuen Topic hat keinen Reply-Anker. Deine ursprüngliche Nachricht liegt außerhalb des Topics, und Telegram lässt eine Antwort nicht hineinwandern, also sendet Hermes nur über message_thread_id, ohne Reply-Anker. Es sieht so aus, als hätte sich die Antwort nicht an deine Nachricht gehängt; der Inhalt liegt im neuen Topic, und das ist so erwartet.

Zweitens: In Multi-Bot-Setups wird der Schlüssel pro Bot gelesen. Wenn ein Gateway mehrere Telegram-Bots bedient (ein persönlicher Assistent, ein Team-Bot), wird der Schalter von dem Bot gelesen, der die Nachricht empfangen hat, nicht von dem, der gestartet wurde. Gut zu wissen, wenn du mehrere Profile hinter einem Gateway betreibst und annimmst, eine Änderung am Default-Profil decke alles ab.

Eine verwandte Nettigkeit: das automatische Umbenennen von Topics. Sobald Hermes einen Session-Titel erzeugt, benennt es das Telegram-Topic best-effort passend um – „New Topic“ wird zu „Database migration plan“. Fehler werden nur geloggt; die Session ist nicht betroffen. Wenn du Topics von Hand benennst und sie in Ruhe lassen willst, deckt die Doku ab, wie du das abschaltest.

Wann es sich lohnt und wann nicht

Es lohnt sich, wenn Telegram deine Multithread-Werkbank ist: ein Topic pro Spur, und du steigst oft über den Home-Screen der App in den Chat ein. Dass jede Nachricht ihr eigenes Topic wird, erzwingt „neuer Thread, neuer Kontext“, und das ist meistens genau das, was du wolltest.

Es lohnt sich nicht, wenn du überwiegend eine einzige laufende Konversation hast und Topics nur gelegentlich nutzt. Dann hängt jede Root-Nachricht einen weiteren Thread an, und bis das Auto-Titling hinterherkommt, siehst du eine Wand aus „Hermes Chat“.

Wenn dich eigentlich die Grenze zwischen Topic, Session und Kontext interessiert, kartiert der Session-Boundaries-Guide der Seite das. Der Beitrag zum Telegram-Inline-Picker behandelt die Auswahl von Modellen und Sessions direkt im Chat, und Peer-Bot-zu-Bot-DMs ist die andere Hälfte der Telegram-Geschichte. Du startest bei null? Die Installationsanleitung hat die Basis für die Plattformkonfiguration.

Kurz gefasst

dm_topic_auto_transfer ist ein winziger Schalter, der eine sehr konkrete Frage beantwortet: „Zu welcher Konversation gehörte diese verirrte Nachricht?“ Die alte Antwort war „zur letzten“, die neue ist „zu einer neuen“. Das alte Verhalten als Default zu behalten ist richtig – die meisten wollen kein neues Topic pro Nachricht –, aber wer Telegram als Werkbank begreift, entfernt mit dem Einschalten eine ganze Klasse von kreuzkontaminiertem Kontext.