Жизненный цикл сеансов Hermes Agent и запланированные задачи

Политика сброса сессии

Политика сброса управляет тем, когда сеанс автоматически "теряет память" — он получает новый session_id, а старый контекст архивируется.

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

Четыре режима сброса

ModeПоведениеПрименимые сценарии
noneНикогда не выполнять автосброс; контекст управляется исключительно механизмом сжатия.Сценарии, требующие длительного непрерывного контекста
idleАвтоматический сброс после простоя более N минутИзредка используемые агенты
dailyАвтоматический сброс ежедневно в указанное времяАгенты, используемые для ежедневных рутинных задач
bothСброс по бездействию или ежедневный сброс — срабатывает тот, который произойдёт первым.Большинство сценариев (рекомендуется по умолчанию)

Настройка политики сброса

Пример

# config.yaml — глобальная политика сброса
session_reset
:
  mode
: both              # none | idle | daily | both
  at_hour
: 4              # Время ежедневного сброса (4 AM, местное время)
  idle_minutes
: 1440      # Тайм-аут бездействия (1440 минут = 24 часа)
  notify
: true            # Уведомлять пользователя при сбросе

# Настройка политики сброса для каждой платформы
platforms
:
  telegram
:
    session_reset
:
      mode
: idle
      idle_minutes
: 720   # Сессия Telegram сбрасывается после 12 часов бездействия
  slack
:
    session_reset
:
      mode
: none          # Разговоры в Slack никогда автоматически не сбрасываются

Эффект сброса

Когда сессия вызывает сброс, происходит следующее:

  • Старые сессии помечаются как завершённые в SQLite (причина: "session_reset")
  • Сгенерировать новый session_id (формат: YYYYMMDD_HHMMSS_8-значный случайный hex)
  • У нового SessionEntry флаг was_auto_reset помечается как true
  • Кэшированные экземпляры Agent очищаются
  • Пользователь увидит уведомление "Сессия была сброшена" в следующем сообщении.

Сессии с активными фоновыми процессами никогда не сбрасываются. Hermes проверяет колбэк has_active_processes, чтобы гарантировать, что он никогда не прерывает выполняющиеся задачи.


Механизм восстановления после перезапуска

Механизм восстановления после перезапуска Hermes Gateway гарантирует, что текущие сессии не теряются после неожиданного сбоя или запланированного перезапуска.

Два маркера восстановления

ОтметкаСценарий срабатыванияПоведениеУровень серьёзности
resume_pendingВосстановление после сбоя, тайм-аут drainСохраните session_id и продолжите разговор при следующем посещении.мягкое восстановление
suspendedкоманда /stop или 3 последовательных сбоя перезапуска.Принудительный сброс, сгенерировать новый session_id.жёсткий сброс

Процесс восстановления при запуске

Когда Gateway запускается, процесс восстановления выглядит следующим образом:

Шаг 1: Проверьте маркер .clean_shutdown.

Если он существует, предыдущее завершение было чистым, поэтому процесс восстановления пропускается.

Шаг 2: Если маркер .clean_shutdown не существует, предыдущий выход был аварийным.

Gateway вызывает suspend_recently_active(), помечая сессии, активные за последние 120 секунд, как resume_pending.

Шаг 3: Обнаружение зацикливания (бесконечного цикла).

Если сессия всё ещё активна после 3 последовательных перезапусков, она может быть зациклена; Gateway пометит её как suspended.

Шаг 4: Возобновление ожидающих сессий.

Gateway синтезирует MessageEvent для каждой сессии resume_pending, запуская автоматическое продолжение работы Agent.

Маркер тайм-аута drain

Во время корректного завершения/перезапуска, если сессия обрабатывается, но превышает время ожидания drain, Gateway пометит её как resume_pending.

Причины пометки в различных сценариях:

Причина пометкиЗначение
restart_timeoutТайм-аут завершения при перезапуске
shutdown_timeoutТайм-аут завершения при остановке
restart_interruptedВосстановление после сбоя (запускается из suspend_recently_active)

Маркер resume_pending не сбрасывается в get_or_create_session() — он сбрасывается после следующего успешного ответа Agent. Если восстановленная сессия снова прерывается, маркер остаётся, что позволяет повторить попытку при следующем перезапуске. После 3 последовательных сбоев он переводится в состояние suspended.


Механизм очереди сообщений

Когда пользователь отправляет несколько сообщений подряд, пока Agent обрабатывает сообщение, механизм очереди сообщений Gateway гарантирует, что сообщения не теряются.

Структура очереди

В Gateway используется двухуровневая схема очередей:

  • Ожидающая очередь с одним слотом (_pending_messages): у каждой сессии есть только один слот «next»; повторные отправки перезаписывают его.
  • Очередь переполнения (_queued_events): когда слот занят, сообщения добавляются в хвост очереди переполнения.

Команда /queue

Команда /queue позволяет отправлять задачи пакетами, и каждая задача создаёт полный ход Агента.

Пример

# Отправить в Telegram/Discord
/queue review src/стиль кода main.py
/queue as src/Напиши модульные тесты для utils.py
/queue обнови инструкции по установке в README.md

Каждая задача в очереди выполняется в порядке FIFO, при этом каждая задача создаёт полный ход Агента; они не объединяются.

Используйте команду /new или /reset, чтобы очистить очередь сообщений текущей сессии.

Если вы отправляете несколько сообщений подряд, пока Агент обрабатывает, промежуточные будут перезаписаны (сохраняется только последнее); сообщения в команде /queue не перезаписываются — каждая задача /queue выполняется по порядку.


Запланированные задачи (Cron)

Hermes имеет полноценную поддержку запланированных задач, позволяя вам настроить Агента на периодическое выполнение конкретных задач.

Запланированные задачи могут привязываться к Skill и доставлять результаты на указанную платформу.

Настройка запланированных задач

Запланированные задачи определяются в jobs.json и поддерживают несколько форматов расписания.

{
  "jobs": [
    {
      "id": "daily-news-summary",
      "schedule": "0 8 * * *",
      "description": "每天早上 8 点抓取 AI 行业新闻并生成摘要",
      "skill": "ai-news-summarizer",
      "deliver_to": {
        "platform": "telegram",
        "chat_id": "-1001234567890"
      }
    },
    {
      "id": "weekly-code-review",
      "schedule": "0 10 * * 1",
      "description": "每周一早上 10 点审查项目代码变更",
      "skill": "code-review-assistant",
      "deliver_to": {
        "platform": "discord",
        "chat_id": "123456789"
      }
    },
    {
      "id": "health-check",
      "schedule": "*/30 * * * *",
      "description": "每 30 分钟检查服务器健康状态",
      "skill": "server-health-checker",
      "deliver_to": {
        "platform": "telegram",
        "chat_id": "123456789"
      }
    }
  ]
}

Поддерживаемые форматы расписания

ФорматированиеПримерОписание
Cron-выражение0 8 * * *Стандартное cron-выражение из 5 полей
Интервал30mКаждые 30 минут
Относительное время+90sВыполнить один раз через 90 секунд
Количество повторовrepeat.times: 5Автоматически остановить после 5 выполнений

Можно настроить в настольной версии; нажмите "Расписание" в левом нижнем углу:

Нажмите "Создать запланированную задачу":

Создать задачу:

После привязки запланированной задачи к Навыку вывод будет автоматически форматироваться в соответствии с форматом вывода, определённым Навыком. Это гарантирует, что при доставке результатов запланированной задачи на платформу обмена сообщениями их представление будет согласованным и удобочитаемым.


Cron, управляемый Chronos (для опытных)

Chronos — это управляемое решение Hermes для запланированных задач, специально разработанное для моделей развёртывания с масштабированием до нуля.

Когда ваш Gateway полностью остановлен в режиме простоя, Chronos всё равно может гарантировать своевременный запуск запланированных задач.

Зачем нужен Chronos?

Встроенный cron-тикер требует, чтобы процесс Gateway работал непрерывно, — если Gateway масштабируется до нуля, запланированные задачи не будут запускаться.

Chronos делегирует управление запланированными задачами NAS (Nous Account Service), который пробуждает Gateway через внешний планировщик при срабатывании задачи.

Рабочий процесс Chronos

Рабочий процесс Chronos разделён на четыре шага:

Шаг 1: Агент вычисляет время следующего запуска и регистрирует одноразовый таймер в NAS.

Шаг 2: NAS использует внешний планировщик (например, запланированные триггеры Fly Machines), чтобы вызвать обратный вызов в указанное время.

Шаг 3: Внешний планировщик выполняет обратный вызов к NAS, и NAS генерирует короткоживущий JWT-токен.

Шаг 4: NAS вызывает эндпоинт /api/cron/fire Агента, используя JWT-токен. Агент проверяет его, выполняет задачу и повторно регистрирует следующий одноразовый таймер.

Гарантия не более одного раза

Chronos использует операции CAS (Compare-And-Set) на уровне хранилища, чтобы гарантировать, что каждая запланированная задача выполняется только один раз.

Даже если планировщик отправляет дублирующиеся запросы на запуск из-за сетевых повторных попыток, Агент может выполнить дедупликацию с помощью CAS, гарантируя, что задачи не будут выполняться повторно.

Настройка Chronos

Пример

# config.yaml - конфигурация Cron, управляемая Chronos
cron
:
  provider
: "chronos"                         # Используйте Chronos вместо встроенного тикера
  chronos
:
    portal_url
: "https://portal.nousresearch.com"
    callback_url
: "https://my-agent.fly.dev"  # публично доступный URL Агента
    expected_audience
: "agent:inst_abc123"    # Аудитория для проверки JWT
    nas_jwks_url
: "https://portal.nousresearch.com/.well-known/jwks.json"

Chronos — рекомендуемое решение для планирования для управляемых развёртываний Hermes. Если вы используете самостоятельно размещённое развёртывание и ваш Gateway никогда не масштабируется до нуля, встроенного cron-тикера вполне достаточно. Если callback_url пуст или у Агента нет учётной записи Nous, система автоматически переключается на встроенный тикер.

Другие расширения