Технологии

Telegram в Hermes Agent: allowlist и изоляция тем

Раздельный белый список для личных сообщений и групп плюс устойчивое сопоставление темы с сессией — конкретное инженерное решение, которое стоит разобрать как образец.

Бот в мессенджере отличается от веб-интерфейса одним свойством: он доступен всем, кто узнал его имя. Веб-приложение можно спрятать за формой входа, бот — нет. Поэтому вопрос «кто вообще может с ним разговаривать» здесь не настройка, а первое архитектурное решение.

В Hermes Agent это решение сделано аккуратнее, чем в типичной самодельной реализации, и разобрать его стоит независимо от того, будете вы пользоваться фреймворком или нет. Речь идёт о двух вещах: раздельном белом списке для личных сообщений и групп и об устойчивом сопоставлении темы разговора с внутренней сессией.

Сведения приведены по состоянию на 28.07.2026 и требуют проверки. И повторим то, что важно: Persona не использует Hermes Agent — это разбор чужого решения, а не описание нашего стека. Что это за фреймворк — в обзоре Hermes Agent; почему вокруг имени столько путаницы — в материале про три разные вещи под именем Hermes.

#Короткий ответ

Два независимых механизма вместо одного:

  • Список разрешённых отправителей — кто может обращаться к агенту в личных сообщениях;
  • Список разрешённых групповых чатов — в каких группах агент вообще реагирует.

Их независимость — не украшение. Она означает, что членство в разрешённой группе не превращает участника в того, кто может отдавать агенту команды. Это ровно та ошибка, на которой ломается большинство самодельных ботов.

Плюс третий механизм — темы внутри группы отображаются в отдельные сессии, устойчиво и без перемешивания.

#Как это устроено

#Два уровня доступа

Уровень Что проверяет Что даёт Чего не даёт
Отправитель Идентификатор пишущего Право обращаться в личных сообщениях Ничего в группах
Групповой чат Идентификатор чата Агент реагирует в этой группе Права владельца участникам
Условие ответа Упоминание или ответ боту Агент не встревает в каждую реплику —

Третья строка — отдельный уровень, который часто путают с доступом. Он отвечает не на вопрос «можно ли», а на вопрос «уместно ли сейчас»: агент в группе по умолчанию молчит, пока к нему не обратились явно.

Практический смысл разделения: разрешить группу — не значит авторизовать её участников. Сообщения других людей могут быть наблюдаемым контекстом, но команды исполняет только владелец. Если свести оба уровня к одному списку, любой участник разрешённой группы получает управление личным агентом.

#Отображение темы в сессию

     TELEGRAM                          ВНУТРИ АГЕНТА

  личные сообщения        ──▶   сессия «Личное»
   (chat_id владельца)

  группа A                ──▶   сессия «Группа A»
   ├─ тема «релиз»        ──▶   сессия «A / релиз»
   └─ тема «найм»         ──▶   сессия «A / найм»

  группа B                ──▶   сессия «Группа B»

  задача по расписанию    ──▶   отдельная изолированная
                                 сессия, результат
                                 доставляется в заданный чат

                                        │
                                        ▼
                          ОБЩАЯ КУРИРУЕМАЯ ПАМЯТЬ
                          (одна на всё, привязана
                           к человеку, а не к чату)

Три правила, которые задают поведение схемы:

  • Пара «чат плюс тема» отображается ровно в одну сессию. Устойчиво: перезапуск процесса не создаёт вторую ленту на тот же чат.
  • Группа не сливается с личными сообщениями автоматически. Даже когда пишет один и тот же человек.
  • Задача по расписанию работает в своей сессии. Её результат доставляется в заданный чат, но контекст фонового запуска не подмешивается в текущий разговор.

Последнее правило решает проблему, которую в самодельных реализациях обнаруживают поздно: утренняя сводка, сформированная в контексте вчерашнего вечернего обсуждения, наследует его тему и выглядит странно.

#Что из этого следует на практике

Идентификаторы, а не имена. Проверка по имени пользователя ненадёжна: имя меняется и может быть занято другим человеком. Числовой идентификатор постоянен.

Пустой список означает «никто». Отсутствие настройки не должно трактоваться как «разрешено всем». Это разница между отказом по умолчанию и разрешением по умолчанию, и она определяет, что произойдёт при неполной конфигурации.

Неизвестный отправитель не создаёт следов. Правильная реакция — не заводить ни сессию, ни запись в истории. Иначе бот, который просто «отвечает отказом», всё равно накапливает мусор, а при некоторой настойчивости и расходует ваш бюджет на модель.

Ограничение сообщений в группах — данность, а не помеха. У ботов в групповых чатах доступ к сообщениям ограничен по умолчанию: без изменения настроек бот видит в основном упоминания, ответы и команды. Это стоит объяснять пользователю, а не пытаться обойти.

Ретроспективной истории не будет. Обычный бот получает только те обновления, которые пришли после подключения. Обещать импорт прошлой переписки нельзя.

Как это же строится с нуля, включая дедупликацию обновлений и подтверждения, — в руководстве по агенту в Telegram.

#Где интуиция подводит

«Достаточно проверить, что пишет владелец». Недостаточно: в группе владелец пишет вперемешку с другими, и весь текст группы попадает в контекст. Проверка отправителя отвечает на вопрос «кто прислал эту реплику», а не «чему можно доверять в контексте».

«Разрешил группу — значит доверяю участникам». Разрешение группы говорит только о том, что агент здесь реагирует. Права участников — отдельный вопрос, и по умолчанию у них не должно быть права запускать инструменты.

«Темы — это косметика». Без изоляции тем обсуждение из одной темы всплывает в другой. На рабочих группах это не неудобство, а утечка контекста между разговорами разных людей.

«Allowlist защищает от промпт-инъекции». Не защищает. Он отвечает на вопрос, чьи сообщения обрабатываются, а не на вопрос, что делать с инструкциями внутри разрешённого текста. Это разные слои: разбор второго — в руководстве по белым спискам и правам агента.

«Если бот не отвечает в группе — он сломан». Скорее всего он просто не видит сообщений: у ботов в группах ограниченный доступ по умолчанию.

#Чем это отличается от нашего подхода

Общая идея у нас совпадает: владелец задаётся числовым идентификатором, разрешённые группы — отдельным списком, и это два независимых механизма. Совпадение не случайно — задача одна и хороших решений у неё немного.

Различие в том, что мы добавляем поверх. В Persona групповая поверхность ограничена ещё и по инструментам: в группе доступен ровно один инструмент — поиск в сети, независимо от того, кто прислал сообщение. Причина в свойствах остальных инструментов, а не в недоверии к конкретным людям: универсальный HTTP-инструмент принимает произвольные заголовки и тело, а прямое открытие страницы обходит проверку адреса.

И отдельно у нас вызовы, которые выполняют код или удаляют данные, не исполняются из текста мессенджера вовсе — они паркуются за одноразовой кнопкой подтверждения, причём имя инструмента и аргументы перечитываются из записи в базе, а не берутся из нажатия.

Полное сравнение, включая раздел о том, где сторонний фреймворк объективно лучше нас, — в материале Persona Agent и Hermes Agent.

#Частые вопросы

#Зачем два отдельных списка вместо одного?

Потому что они отвечают на разные вопросы: кто может обращаться к агенту лично и где агент вообще реагирует. Сведение их в один список приводит к тому, что участие в разрешённой группе даёт человеку права владельца — а это уже не ограничение доступа, а его отсутствие.

#Может ли участник группы управлять чужим агентом?

При правильной настройке — нет: разрешение группы означает только то, что агент в ней реагирует, а команды исполняет владелец. Сообщения остальных участников остаются наблюдаемым контекстом. Если этого разделения нет, любой участник получает управление.

#Зачем изолировать темы в отдельные сессии?

Чтобы контекст одного обсуждения не всплывал в другом. В рабочей группе с несколькими темами это принципиально: без изоляции агент подмешивает в ответ по одной теме содержание разговора по другой, причём с участием разных людей.

#Проверять по имени пользователя или по идентификатору?

По числовому идентификатору. Имя пользователя меняется владельцем в любой момент и может быть впоследствии занято другим человеком, поэтому проверка по имени — это проверка того, что легко подделать.

#Что делать с сообщениями от неизвестных отправителей?

Не создавать ни сессию, ни запись в истории. Ответ отказом кажется вежливым, но накапливает мусор и в некоторых конфигурациях расходует бюджет на модель. Правильное поведение — тихо игнорировать всё, что вне списка.

#Спасает ли allowlist от инструкций внутри текста?

Нет, это разные слои защиты. Allowlist определяет, чьи сообщения вообще обрабатываются; что делать с инструкциями внутри разрешённого текста — вопрос политики прав на инструменты, которая не должна зависеть от содержимого сообщений.

#Вывод

Решение, которое стоит перенять независимо от фреймворка: два независимых списка — отправители и группы, — устойчивое отображение пары «чат плюс тема» в одну сессию и отдельная сессия для фоновых задач. Плюс проверка по числовым идентификаторам и отказ по умолчанию при пустой конфигурации.

Чего оно не даёт: защиты от инструкций внутри разрешённого текста. Для этого нужен второй слой — политика прав на инструменты, не зависящая от того, что написано в сообщении.

Хотите ИИ, который помнит вас?

Persona держит контекст между чатами и работает на вашем железе — если развернуть её у себя и подключить локальную модель.

Создать аккаунт