Планируйте автоматический запуск задач с помощью естественного языка или cron-выражений. Hermes предоставляет управление cron через единый инструмент cronjob с операциями в стиле действий, вместо отдельных инструментов для создания, просмотра и удаления.
Что умеет cron
Cron-задачи могут:
планировать одноразовые или повторяющиеся задачи
приостанавливать, возобновлять, редактировать, запускать и удалять задачи
прикреплять ноль, один или несколько навыков к задаче
доставлять результаты обратно в исходный чат, локальные файлы или настроенные платформы
запускаться в новых сессиях агента со стандартным статическим списком инструментов
запускаться в режиме без агента — скрипт по расписанию, его stdout доставляется дословно, без участия LLM (см. раздел Режим без агента ниже)
Всё это доступно самому Hermes через инструмент cronjob, так что вы можете создавать, приостанавливать, редактировать и удалять задачи, просто попросив об этом на обычном языке — без необходимости использовать CLI.
Сессии, запущенные через cron, не могут рекурсивно создавать новые cron-задачи. Hermes отключает инструменты управления cron внутри выполнения cron-задач, чтобы предотвратить бесконечные циклы планирования.
Создание запланированных задач
В чате через /cron
/cronadd30m"Remind me to check the build"
/cronadd"every 2h""Check server status"
/cronadd"every 1h""Summarize new feed items"--skillblogwatcher
/cronadd"every 1h""Use both skills and combine the result"--skillblogwatcher--skillmaps
Из автономного CLI
hermescroncreate"every 2h""Check server status"
hermescroncreate"every 1h""Summarize new feed items"--skillblogwatcher
hermescroncreate"every 1h""Use both skills and combine the result"\--skillblogwatcher\--skillmaps\--name"Skill combo"
Через естественный диалог
Просто попросите Hermes обычным языком:
Every morning at 9am, check Hacker News for AI news and send me a summary on Telegram.
Hermes использует единый инструмент cronjob внутри.
Cron-задачи с навыками
Cron-задача может загружать один или несколько навыков перед выполнением промпта.
Один навык
cronjob(action="create",skill="blogwatcher",prompt="Check the configured feeds and summarize anything new.",schedule="0 9 * * *",name="Morning feeds",)
Несколько навыков
Навыки загружаются по порядку. Промпт становится инструкцией, добавленной поверх этих навыков.
cronjob(action="create",skills=["blogwatcher","maps"],prompt="Look for new local events and interesting nearby places, then combine them into one short brief.",schedule="every 6h",name="Local brief",)
Это полезно, когда вы хотите, чтобы запланированный агент наследовал переиспользуемые рабочие процессы без необходимости вставлять полный текст навыка в сам cron-промпт.
Запуск задачи внутри директории проекта
Cron-задачи по умолчанию запускаются в отрыве от какого-либо репозитория — не загружаются AGENTS.md, CLAUDE.md или .cursorrules, а инструменты terminal / file / code-exec запускаются из рабочей директории, в которой был запущен шлюз. Передайте --workdir (CLI) или workdir= (вызов инструмента), чтобы изменить это:
# Standalone CLI (schedule and prompt are positional)
hermescroncreate"every 1d at 09:00"\"Audit open PRs, summarize CI health, and post to #eng"\--workdir/home/me/projects/acme
# From a chat, via the cronjob toolcronjob(action="create",schedule="every 1d at 09:00",workdir="/home/me/projects/acme",prompt="Audit open PRs, summarize CI health, and post to #eng",)
Когда workdir установлен:
AGENTS.md, CLAUDE.md и .cursorrules из этой директории внедряются в системный промпт (в том же порядке обнаружения, что и в интерактивном CLI)
terminal, read_file, write_file, patch, search_files и execute_code используют эту директорию в качестве рабочей (через TERMINAL_CWD)
Путь должен быть абсолютной существующей директорией — относительные пути и отсутствующие директории отклоняются при создании/обновлении
Передайте --workdir "" (или workdir="" через инструмент) при редактировании, чтобы очистить его и вернуть прежнее поведение
note Сериализация
Задачи с workdir выполняются последовательно на каждом такте планировщика, а не в параллельном пуле. Это сделано намеренно — TERMINAL_CWD является глобальным для процесса, поэтому две задачи с workdir, запущенные одновременно, повредили бы рабочие директории друг друга. Задачи без workdir по-прежнему выполняются параллельно.
Редактирование задач
Вам не нужно удалять и создавать задачи заново, чтобы изменить их.
Чат
/cronedit<job_id>--schedule"every 4h"
/cronedit<job_id>--prompt"Use the revised task"
/cronedit<job_id>--skillblogwatcher--skillmaps
/cronedit<job_id>--remove-skillblogwatcher
/cronedit<job_id>--clear-skills
Автономный CLI
hermescronedit<job_id>--schedule"every 4h"
hermescronedit<job_id>--prompt"Use the revised task"
hermescronedit<job_id>--skillblogwatcher--skillmaps
hermescronedit<job_id>--add-skillmaps
hermescronedit<job_id>--remove-skillblogwatcher
hermescronedit<job_id>--clear-skills
Примечания:
повторное использование --skill заменяет список прикреплённых навыков задачи
--add-skill добавляет навык к существующему списку, не заменяя его
pause — сохраняет задачу, но прекращает её планирование
resume — повторно включает задачу и вычисляет следующий запуск
run — запускает задачу на следующем такте планировщика
remove — полностью удаляет задачу
Как это работает
Выполнение cron обрабатывается демоном шлюза. Шлюз запускает такты планировщика каждые 60 секунд, выполняя все подлежащие запуску задачи в изолированных сессиях агента.
hermesgatewayinstall# Install as a user service
sudohermesgatewayinstall--system# Linux: boot-time system service for servers
hermesgateway# Or run in foreground
hermescronlist
hermescronstatus
Поведение планировщика шлюза
На каждом такте Hermes:
загружает задачи из ~/.hermes/cron/jobs.json
проверяет next_run_at относительно текущего времени
запускает новую сессию AIAgent для каждой подлежащей запуску задачи
опционально внедряет один или несколько прикреплённых навыков в эту новую сессию
выполняет промпт до завершения
доставляет финальный ответ
обновляет метаданные запуска и следующее запланированное время
Файловая блокировка в ~/.hermes/cron/.tick.lock предотвращает перекрытие тактов планировщика, чтобы одна и та же группа задач не была запущена дважды.
Варианты доставки
При планировании задач вы указываете, куда будет направлен результат:
Вариант
Описание
Пример
"origin"
Туда, где была создана задача
По умолчанию в мессенджерах
"local"
Сохранить только в локальные файлы (~/.hermes/cron/output/)
По умолчанию в CLI
"telegram"
Домашний канал Telegram
Использует TELEGRAM_HOME_CHANNEL
"telegram:123456"
Конкретный чат Telegram по ID
Прямая доставка
"telegram:-100123:17585"
Конкретная тема Telegram
Формат chat_id:thread_id
"discord"
Домашний канал Discord
Использует DISCORD_HOME_CHANNEL
"discord:#engineering"
Конкретный канал Discord
По имени канала
"slack"
Домашний канал Slack
"whatsapp"
WhatsApp домой
"signal"
Signal
"matrix"
Домашняя комната Matrix
"mattermost"
Домашний канал Mattermost
"email"
Email
"sms"
SMS через Twilio
"homeassistant"
Home Assistant
"dingtalk"
DingTalk
"feishu"
Feishu/Lark
"wecom"
WeCom
"weixin"
Weixin (WeChat)
"bluebubbles"
BlueBubbles (iMessage)
"qqbot"
QQ Bot (Tencent QQ)
"all"
Разослать на все подключённые домашние каналы
Определяется в момент запуска
"telegram,discord"
Разослать на конкретный набор каналов
Список через запятую
"origin,all"
Доставить в исходный чат плюс все остальные подключённые каналы
Комбинируйте любые токены
Финальный ответ агента доставляется автоматически. Вам не нужно вызывать send_message в cron-промпте.
Маршрутизация через (all)
all позволяет отправить одну cron-задачу на все настроенные каналы мессенджеров, без необходимости перечислять их по имени. Он определяется в момент запуска, так что задача, созданная до подключения Telegram, автоматически его учтёт на следующем такте после установки TELEGRAM_HOME_CHANNEL.
Семантика: all расширяется до всех платформ с настроенным домашним каналом. Ноль каналов — это нормально; задача просто не будет иметь целей доставки, что будет зафиксировано как ошибка доставки.
all комбинируется с явными целями. origin,all доставляет в исходный чат плюс все остальные подключённые домашние каналы, дедуплицируя по (platform, chat_id, thread_id).
Обёртка ответа
По умолчанию доставляемый cron-вывод оборачивается в заголовок и подвал, чтобы получатель знал, что это запланированная задача:
Cronjob Response: Morning feeds
-------------
<agent output here>
Note: The agent cannot see this message, and therefore cannot respond to it.
Чтобы доставлять необработанный вывод агента без обёртки, установите cron.wrap_response в false:
# ~/.hermes/config.yamlcron:wrap_response:false
Тихое подавление
Если финальный ответ агента начинается с [SILENT], доставка полностью подавляется. Вывод всё равно сохраняется локально для аудита (в ~/.hermes/cron/output/), но сообщение не отправляется цели доставки.
Это полезно для мониторинговых задач, которые должны сообщать только о проблемах:
Check if nginx is running. If everything is healthy, respond with only [SILENT].
Otherwise, report the issue.
Неудачные задачи всегда доставляются независимо от маркера [SILENT] — только успешные запуски могут быть подавлены.
Тайм-аут скрипта
Предварительные скрипты (прикреплённые через параметр script) имеют стандартный тайм-аут 120 секунд. Если вашим скриптам нужно больше времени — например, для включения случайных задержек, чтобы избежать ботоподобных шаблонов — вы можете увеличить это значение:
Или установите переменную окружения HERMES_CRON_SCRIPT_TIMEOUT. Порядок разрешения: переменная окружения → config.yaml → значение по умолчанию 120с.
Режим без агента (только скрипт)
Для повторяющихся задач, которые не требуют логики LLM — классические сторожевые процессы, оповещения о диске/памяти, пульсации, CI-пинги — передайте no_agent=True при создании. Планировщик запускает ваш скрипт по расписанию и доставляет его stdout напрямую, полностью пропуская агента:
Stdout скрипта (обрезанный) → доставляется дословно как сообщение.
Пустой stdout → тихий такт, без доставки. Это шаблон сторожевого процесса: «сообщать, только когда что-то не так».
Ненулевой код возврата или тайм-аут → доставляется оповещение об ошибке, чтобы сломанный сторожевой процесс не замолчал незаметно.
{"wakeAgent": false} на последней строке → тихий такт (тот же механизм, что и для LLM-задач).
Никаких токенов, никакой модели, никакого резервного провайдера — задача никогда не обращается к уровню инференса.
Файлы .sh / .bash запускаются через /bin/bash; всё остальное — через текущий интерпретатор Python (sys.executable). Скрипты должны находиться в ~/.hermes/scripts/ (те же правила изоляции, что и для предварительных скриптов).
Агент настраивает это за вас
Схема инструмента cronjob предоставляет no_agent напрямую Hermes, так что вы можете описать сторожевой процесс в чате и позволить агенту настроить его:
Ping me on Telegram if RAM is over 85%, every 5 minutes.
Hermes запишет скрипт проверки в ~/.hermes/scripts/ через write_file, а затем вызовет:
Он автоматически выбирает no_agent=True, когда содержимое сообщения полностью определяется скриптом (сторожевые процессы, пороговые оповещения, пульсации). Тот же инструмент также позволяет агенту приостанавливать, возобновлять, редактировать и удалять задачи — так что весь жизненный цикл управляется через чат без необходимости прикасаться к CLI.
Cron-задачи запускаются в изолированных сессиях без памяти о предыдущих запусках. Но иногда вывод одной задачи — это именно то, что нужно следующей. Параметр context_from автоматически устанавливает эту связь — промпт задачи B получает последний вывод задачи A в качестве контекста во время выполнения.
# Job 1: Collect raw datacronjob(action="create",prompt="Fetch the top 10 AI/ML stories from Hacker News. Save them to ~/.hermes/data/briefs/raw.md in markdown format with title, URL, and score.",schedule="0 7 * * *",name="AI News Collector",)# Job 2: Triage — receives Job 1's output as context# Get Job 1's ID from: cronjob(action="list")cronjob(action="create",prompt="Read ~/.hermes/data/briefs/raw.md. Score each story 1–10 for engagement potential and novelty. Output the top 5 to ~/.hermes/data/briefs/ranked.md.",schedule="30 7 * * *",context_from="<job1_id>",name="AI News Triage",)# Job 3: Ship — receives Job 2's output as contextcronjob(action="create",prompt="Read ~/.hermes/data/briefs/ranked.md. Write 3 tweet drafts (hook + body + hashtags). Deliver to telegram:7976161601.",schedule="0 8 * * *",context_from="<job2_id>",name="AI News Brief",)
Как это работает:
При запуске задачи 2 Hermes читает последний вывод задачи 1 из ~/.hermes/cron/output/{job1_id}/*.md
Этот вывод автоматически добавляется в начало промпта задачи 2
Задаче 2 не нужно жёстко прописывать «прочитай этот файл» — она получает содержимое как контекст
Цепочка может быть любой длины: Задача 1 → Задача 2 → Задача 3 → ...
Зависимые задачи, где работа шага N зависит от вывода шага N−1
Шаблоны fan-out/fan-in, где одна задача агрегирует результаты нескольких других
Восстановление провайдера
Cron-задачи наследуют ваши настроенные резервные провайдеры и ротацию пула учётных данных. Если ключ API первичного провайдера ограничен по скорости или провайдер возвращает ошибку, cron-агент может:
Переключиться на альтернативного провайдера, если у вас настроены fallback_providers (или устаревший fallback_model) в config.yaml
Переключиться на следующие учётные данные из вашего пула учётных данных для того же провайдера
Это делает cron-задачи, запускающиеся с высокой частотой или в часы пик, более устойчивыми — один ключ с ограничением скорости не приведёт к сбою всего запуска.
Форматы расписания
Финальный ответ агента доставляется автоматически — вам не нужно включать send_message в cron-промпт для того же назначения. Если cron-запуск вызывает send_message для той же цели, куда планировщик уже доставит ответ, Hermes пропускает этот дублирующий вызов и сообщает модели, что пользовательский контент должен быть в финальном ответе. Используйте send_message только для дополнительных или других целей.
Относительные задержки (однократно)
30m → Run once in 30 minutes
2h → Run once in 2 hours
1d → Run once in 1 day
Интервалы (повторяющиеся)
every 30m → Every 30 minutes
every 2h → Every 2 hours
every 1d → Every day
Cron-выражения
0 9 * * * → Daily at 9:00 AM
0 9 * * 1-5 → Weekdays at 9:00 AM
0 */6 * * * → Every 6 hours
30 8 1 * * → First of every month at 8:30 AM
0 0 * * 0 → Every Sunday at midnight
ISO-метки времени
2026-03-15T09:00:00 → One-time at March 15, 2026 9:00 AM
При update передайте skills=[], чтобы удалить все прикреплённые навыки.
Наборы инструментов для cron-задач
Cron запускает каждую задачу в новой сессии агента без привязанного чат-канала. По умолчанию cron-агент получает тот набор инструментов, который вы настроили для платформы cron в hermes tools — не CLI по умолчанию, не всё подряд.
hermestools
# → pick the "cron" platform in the curses UI# → toggle toolsets on/off just like you would for Telegram/Discord/etc.
Более точное управление для каждой задачи доступно через поле enabled_toolsets в cronjob.create (или для существующей задачи через cronjob.update):
cronjob(action="create", name="weekly-news-summary",
schedule="every sunday 9am",
enabled_toolsets=["web", "file"], # just web + file, no terminal/browser/etc.
prompt="Summarize this week's AI news: ...")
Когда enabled_toolsets установлен для задачи, он имеет приоритет; иначе применяется конфигурация платформы cron из hermes tools; иначе Hermes использует встроенные значения по умолчанию. Это важно для контроля затрат: включение moa, browser, delegation в каждую крошечную задачу «получить новости» раздувает схему инструментов в каждом LLM-вызове.
Пропуск агента полностью: wakeAgent
Если ваша cron-задача использует предварительный скрипт (через script=), скрипт может решить во время выполнения, должен ли Hermes вообще вызывать агента. Выведите последнюю строку stdout в формате:
{"wakeAgent": false}
…и cron пропустит запуск агента для этого такта. Полезно для частых опросов (каждые 1–5 минут), которые должны пробуждать LLM только когда состояние действительно изменилось — иначе вы будете платить за пустые шаги агента снова и снова.
# pre-check scriptimportjson,syslatest=fetch_latest_issue_count()prev=read_state("issue_count")iflatest==prev:print(json.dumps({"wakeAgent":False}))# skip this ticksys.exit(0)write_state("issue_count",latest)print(json.dumps({"wakeAgent":True,"context":{"new_issues":latest-prev}}))
Когда wakeAgent не указан, значение по умолчанию — true (пробудить агента как обычно).
Цепочки задач: context_from
Cron-задача может получать последний успешный вывод одной или нескольких других задач, перечисляя их имена (или ID) в context_from:
cronjob(action="create", name="daily-digest",
schedule="every day 7am",
context_from=["ai-news-fetch", "github-prs-fetch"],
prompt="Write the daily digest using the outputs above.")
Последние завершённые выводы указанных задач вставляются перед промптом как контекст для этого запуска. Каждая задача должна быть действительным ID или именем (см. cronjob action="list"). Примечание: цепочка читает последний завершённый вывод — она не ждёт выполнения вышестоящих задач в том же такте.
Хранилище задач
Задачи хранятся в ~/.hermes/cron/jobs.json. Вывод запусков задач сохраняется в ~/.hermes/cron/output/{job_id}/{timestamp}.md.
Задачи могут хранить model и provider как null. Когда эти поля опущены, Hermes определяет их во время выполнения из глобальной конфигурации. Они появляются в записи задачи только тогда, когда установлено переопределение для конкретной задачи.
Хранилище использует атомарные файловые записи, поэтому прерванные записи не оставляют частично записанных файлов задач.
Самодостаточные промпты всё ещё важны
warning Важно
Cron-задачи запускаются в полностью новой сессии агента. Промпт должен содержать всё, что нужно агенту, что уже не предоставлено прикреплёнными навыками.
ПЛОХО:"Check on that server issue"
ХОРОШО:"SSH into server 192.168.1.100 as user 'deploy', check if nginx is running with 'systemctl status nginx', and verify https://example.com returns HTTP 200."
Безопасность
Промпты запланированных задач проверяются на инъекции и попытки кражи учётных данных при создании и обновлении. Промпты, содержащие невидимые Unicode-трюки, попытки SSH-бэкдоров или очевидные попытки кражи секретов, блокируются.