Постоянные цели (`/goal`)
/goal даёт Hermes постоянную цель, которая сохраняется между шагами. После каждого шага лёгкая модель-судья проверяет, выполнена ли цель последним ответом ассистента. Если нет, Hermes автоматически отправляет промпт продолжения в ту же сессию и продолжает работу — пока цель не будет достигнута, вы не поставите её на паузу или не очистите, или не закончится бюджет шагов.
Это наша реализация паттерна Ralph loop, вдохновлённая /goal из Codex CLI 0.128.0 от Эрика Траута (OpenAI). Основная идея — поддерживать цель между шагами и не останавливаться, пока она не достигнута — принадлежит им. Реализация здесь независима и адаптирована под архитектуру Hermes.
Когда использовать
Используйте /goal для задач, где вы хотите, чтобы Hermes работал самостоятельно, без необходимости повторять запрос на каждом шаге:
-
"Исправить все ошибки линтера в
src/и убедиться, чтоruff checkпроходит" -
"Перенести функцию X из репозитория Y, включая тесты, и добиться зелёного CI"
-
"Исследовать, почему ID сессий иногда смещаются при сжатии во время выполнения, и написать отчёт"
-
"Создать небольшой CLI для переименования файлов по их EXIF-датам, затем протестировать его на папке
photos/"
Задачи, где агент делает один шаг и останавливается, не требуют /goal. Задачи, где иначе пришлось бы трижды сказать "продолжай" — вот где это сияет.
Быстрый старт
/goal Fix every failing test in tests/hermes_cli/ and make sure scripts/run_tests.sh passes for that directory
Вот что вы увидите:
-
Цель принята —
⊙ Goal set (20-turn budget): <your goal> -
Шаг 1 выполняется — Hermes начинает работать, как если бы вы отправили цель обычным сообщением.
-
Судья работает — после шага модель-судья решает
doneилиcontinue. -
Цикл запускается при необходимости — если
continue, вы увидите↻ Continuing toward goal (1/20): <judge's reason>, и Hermes автоматически сделает следующий шаг. -
Завершение — в итоге вы увидите либо
✓ Goal achieved: <reason>, либо⏸ Goal paused — N/20 turns used.
Команды
| Команда | Описание |
|---|---|
/goal <text> |
Устанавливает (или заменяет) текущую цель. Немедленно запускает первый шаг, так что вам не нужно отправлять отдельное сообщение. |
/goal или /goal status |
Показывает текущую цель, её статус и использованные шаги. |
/goal pause |
Останавливает цикл автоматического продолжения без удаления цели. |
/goal resume |
Возобновляет цикл (сбрасывает счётчик шагов до нуля). |
/goal clear |
Полностью удаляет цель. |
Работает одинаково в CLI и на всех платформах-шлюзах (Telegram, Discord, Slack, Matrix, Signal, WhatsApp, SMS, iMessage, Webhook, API-сервер и веб-панель).
Детали поведения
Судья (Judge)
После каждого шага Hermes вызывает вспомогательную модель с:
-
Текстом текущей цели
-
Последним ответом агента (последние ~4 КБ текста)
-
Системным промптом, предписывающим судье отвечать строгим JSON:
{"done": <bool>, "reason": "<one-sentence rationale>"}
Судья намеренно консервативен: он отмечает цель как done только когда ответ явно подтверждает завершение цели, когда конечный результат явно получен, или когда цель недостижима/заблокирована (считается ВЫПОЛНЕННОЙ с причиной блокировки, чтобы не тратить бюджет на невозможные задачи).
Семантика отказоустойчивости
Если судья ошибается (сбой сети, некорректный ответ, недоступный вспомогательный клиент), Hermes считает вердикт как continue — сломанный судья никогда не блокирует прогресс. Бюджет шагов является реальной страховкой.
Бюджет шагов
По умолчанию — 20 шагов продолжения (goals.max_turns в config.yaml). Когда бюджет исчерпан, Hermes автоматически ставит на паузу и сообщает, что делать дальше:
⏸ Goal paused — 20/20 turns used. Use /goal resume to keep going, or /goal clear to stop.
/goal resume сбрасывает счётчик до нуля, так что вы можете продолжать размеренными порциями.
Сообщения пользователя всегда имеют приоритет
Любое ваше сообщение, отправленное, пока активна цель, имеет приоритет над циклом продолжения. В CLI ваше сообщение попадает в _pending_input перед запланированным продолжением; на шлюзе оно проходит через адаптер FIFO так же. Судья запускается снова после вашего шага — так что если ваше сообщение завершает цель, судья это заметит и остановится.
Безопасность во время выполнения (шлюз)
Пока агент уже работает, /goal status, /goal pause и /goal clear безопасны — они затрагивают только состояние панели управления и не прерывают текущий шаг. Установка новой цели во время выполнения (/goal <new text>) отклоняется с сообщением, предлагающим сначала выполнить /stop, чтобы старое продолжение не конфликтовало с новым.
Постоянство
Состояние цели хранится в SessionDB.state_meta с ключом goal:<session_id>. Это означает, что /resume продолжает с того места, где вы остановились — установите цель, закройте ноутбук, вернитесь завтра, выполните /resume, и цель всё ещё будет в точности такой, какой вы её оставили (активной, на паузе или выполненной).
Кэш промптов
Промпт продолжения — это обычное сообщение от пользователя, добавленное в историю. Он не изменяет системный промпт, не заменяет наборы инструментов и не затрагивает разговор так, чтобы аннулировать кэш промптов Hermes. Выполнение цели на 20 шагов с точки зрения кэша стоит столько же, сколько 20 шагов обычного разговора.
Конфигурация
Добавьте в ~/.hermes/config.yaml:
goals:
# Max continuation turns before Hermes auto-pauses and asks you to
# /goal resume. Default 20. Lower this if you want tighter loops;
# raise it for long-running refactors.
max_turns: 20
Выбор модели судьи
Судья использует вспомогательную задачу goal_judge. По умолчанию она разрешается в вашу основную модель (см. Вспомогательные модели). Если вы хотите направить судью на дешёвую быструю модель для снижения затрат, добавьте переопределение:
auxiliary:
goal_judge:
provider: openrouter
model: google/gemini-3-flash-preview
Вызов судьи небольшой (~200 выходных токенов) и выполняется один раз за шаг, так что дешёвая быстрая модель — обычно правильный выбор.
Пример
You: /goal Create four files /tmp/note_{1..4}.txt, one per turn, each containing its number as text
⊙ Goal set (20-turn budget): Create four files /tmp/note_{1..4}.txt, one per turn, each containing its number as text
Hermes: Creating /tmp/note_1.txt now.
💻 echo "1" > /tmp/note_1.txt (0.1s)
I've created /tmp/note_1.txt with the content "1". I'll continue with the remaining files on the next turn as you specified.
↻ Continuing toward goal (1/20): Only 1 of 4 files has been created; 3 files remain.
Hermes: [Continuing toward your standing goal]
💻 echo "2" > /tmp/note_2.txt (0.1s)
Created /tmp/note_2.txt. Two more to go.
↻ Continuing toward goal (2/20): 2 of 4 files created; 2 remain.
Hermes: [Continuing toward your standing goal]
💻 echo "3" > /tmp/note_3.txt (0.1s)
Created /tmp/note_3.txt.
↻ Continuing toward goal (3/20): 3 of 4 files created; 1 remains.
Hermes: [Continuing toward your standing goal]
💻 echo "4" > /tmp/note_4.txt (0.1s)
All four files have been created: /tmp/note_1.txt through /tmp/note_4.txt, each containing its number.
✓ Goal achieved: All four files were created with the specified content, completing the goal.
You: _
Четыре шага, один вызов /goal, ноль ваших запросов "продолжай".
Когда судья ошибается
Ни один судья не идеален. Следите за двумя типами ошибок:
Ложноотрицательный — судья говорит continue, когда цель на самом деле выполнена. Бюджет шагов ловит это. Вы увидите ⏸ Goal paused и сможете выполнить /goal clear или просто отправить новое сообщение.
Ложноположительный — судья говорит done, когда работа ещё остаётся. Вы увидите ✓ Goal achieved, но знаете, что это не так. Отправьте последующее сообщение, чтобы продолжить, или установите цель более точно: /goal <more specific text>. Системный промпт судьи намеренно консервативен, чтобы ложноположительные результаты были реже ложноотрицательных.
Если вы считаете вердикт судьи неубедительным, текст причины в строке ↻ Continuing toward goal или ✓ Goal achieved точно говорит, что увидел судья. Обычно этого достаточно, чтобы понять, была ли неоднозначной формулировка цели или ответ модели.
Авторство
/goal — это реализация паттерна Ralph loop в Hermes. Дизайн для пользователя — поддерживать цель между шагами, не останавливаться, пока она не достигнута, с управлением create/pause/resume/clear — был популяризирован и выпущен в Codex CLI 0.128.0 Эриком Траутом из команды Codex в OpenAI. Наша реализация независима (центральный реестр CommandDef, хранение в SessionDB.state_meta, судья через вспомогательный клиент, продолжение через FIFO адаптера на стороне шлюза), но идея принадлежит им. Заслуги там, где заслуги.