Постоянные цели (/goal)
/goal задает Гермесу долгосрочную задачу, которая сохраняется между этапами диалога. После каждого шага легкая модель-судья сначала выполнила цель в последнем ответе ассистента. Если нет, Гермес автоматически добавляет продолжение в тот же сеанс и продолжает работу — пока цель не будет достигнута, вы не поставите ее на паузу или не определите, либо не завершите лимит шагов.
Это наша разработка цикла Ральф, вдохновлённая /goal в Codex CLI 0.128.0 Эрикой Траута (OpenAI). Основная идея — цель сохранения активности между шагами и не останавливаться, пока она не выполнена — принадлежит им. Реализация здесь независима и адаптирована к архитектуре Hermes.
Когда использовать
Используйте /goal для задач, где вы хотите, чтобы Hermes работал итеративно, без повторного запроса на каждом этапе:
- "Исправить все ошибки линтера в
src/и убедиться, чтоruff checkпроходит" - «Перенести функционал X из репозитория Y, включая тесты и зелёного CI»
- «Разбраться, почему идентификаторы сессий иногда обсуждаются при сжатии посередине выполнения, и подготовить отчёт»
- "Создать небольшую CLI-утилиту для переименования файлов по датам из EXIF, а затем протестировать ее на странице фотографий/"
Задачи, когда агент делает один шаг и останавливается, не требуют /goal. Задачи, где вам пришлось бы трижды сказать "продолжай" — вот где это незаменимо.
Быстрый старт
/goal Исправить все падающие тесты в tests/hermes_cli/ и убедиться, что scripts/run_tests.sh для этого каталога проходит
Что вы покажете:
- Цель принята —
⊙ Цель установлена (бюджет 20 шагов): <ваша цель> - Шаг 1 достижения — Гермес начинает работу, как если бы вы отправили цель, как обычное сообщение.
- Судья запускается — после шага модель-судья решает:
готово(выполнено) илипродолжить(продолжить). - Цикл с приработком — если
продолжить, вы увидите↻ Продолжение к цели (1/20): <причина судьи>, и Гермес автоматически сделает следующий шаг. - Завершение — в итоге вы видите либо
✓ Цель достигнута: <причина>, либо⏸ Цель достижения — использовано N/20 шагов.
Команды
| Команда | Что делает |
|---|---|
/goal <текст> |
Установить (или заменить) постоянную цель. Немедленно запускает первый шаг, поэтому отдельное сообщение отправлять не нужно. |
/goal или /goal status |
Показать текущую цель, ее статус и использованные шаги. |
/целевая пауза |
Остановить цикл автоматического продолжения, не очищая цель. |
/goal резюме |
Возобновить цикл (сбрасывает счетчик шагов на ноль). |
/цель ясна |
Полностью удалить цель. |
Работает одинаково в CLI и на всех платформах-шлюзах (Telegram, Discord, Slack, Matrix, Signal, WhatsApp, SMS, iMessage, Webhook, сервер API и веб-панель).
Детали поведения
Судья
После каждого шага Гермес предлагает вспомогательную модель, передавая ей:
- Текст постоянной цели
- Последний итоговый ответ агента (последние ~4 КБ текста)
- Системный запрос, предписывающий судье ответить строгим JSON:
{"done": <bool>, "reason": "<одно предложение обоснования>"}
Судья намеренно соблюдает: он помечает цель как готово, только если ответ явно подтверждает завершение цели, когда получен конечный результат, или когда цель недостижима/заблокирована (в этом случае считается, что выполнено, чтобы вызвать блокировку, чтобы не расходовать бюджет на невыполнимые задачи).
Семантика отказо-открытие
Если судья ошибается (сетевая проблема, некорректный ответ, недоступен вспомогательный клиент), Гермес считает вердиктом «продолжить» — сломанный судья никогда не блокирует прогресс. Бюджет шагов представляет собой обмен данными.
Бюджет шагов
По умолчанию — 20 продолжений (goals.max_turns в config.yaml). Когда бюджет исчерпан, Hermes автоматически нажимает паузу и сообщает, как действовать дальше:
⏸ Цель приостановлена — использовано 20/20 шагов. Используйте /goal resume, чтобы продолжить, или /goal clear, чтобы остановиться.
/goal summary сбрасывает счётчик на ноль, так что вы можете продолжать работу в заданных порциях.
Сообщения пользователя всегда имеют приоритет
Любое реальное сообщение, отправленное вами, пока активна цель, получает приоритет цикла над продолжением. В CLI ваше сообщение открывается в _pending_input перед запланированным продолжением; в шлюзе он проходит через адаптер FIFO таким же образом. Судья запускается снова после вашего шага — если ваше сообщение случайно завершит цель, судья это заметит и остановится.
Безопасность во время выполнения (шлюз)
Пока агент уже работает, команды /goal status, /goal Pause и /goal Clear безопасно — они затрагивают только состояние управления и не прерывают текущий шаг. Установка новой цели во время выполнения (/goal <новый текст>) отклоняется с сообщением, используем сначала выбор /stop, чтобы проверить продолжение цепочки не с новой.
Сохранение состояния
Состояние сохраняется цели в SessionDB.state_meta по ключу goal:<session_id>. Это означает, что /resume подхватывает состояние с тем же местом — установите цель, закройте ноутбук, вернитесь завтра, выполните /resume, и цель останется в том же состоянии (активна, на паузе или завершена), в котором вы ее оставили.
Кэш промптов
Подсказка продолжения — обычное сообщение от пользователя, добавленное в историю. Он не изменяет системный запрос, не заменяет набор инструментов и не затрагивает диалог, чтобы отключить кэш-промптов Hermes. Выполнение 20-шаговой цели по затратам кэша эквивалентно 20 шагам обычного разговора.
Конфигурация
Добавьте в ~/.hermes/config.yaml:
goals:
# Максимальное количество продолжений до автоматической паузы и запроса
# /goal resume. По умолчанию 20. Уменьшите для более тесных циклов;
# увеличьте для длительных рефакторингов.
max_turns: 20
Выбор модели
Судья использует вспомогательную задачу goal_judge. По умолчанию она разрешена в вашей основной модели (см. Вспомогательные модели). Если вы хотите изменить судью на дешёвую модель, чтобы снизить затраты, переопределение элементов:
auxiliary:
goal_judge:
provider: openrouter
model: google/gemini-3-flash-preview
Вызов судьи небольшой (~200 выходных токенов) и результат один раз за шаг, поэтому дешёвая быстрая модель обычно является выбором.
Пример пошагового выполнения
Вы: /goal Создать четыре файла /tmp/note_{1..4}.txt, по одному за шаг, каждый содержит свой номер в виде текста
⊙ Цель установлена (бюджет 20 шагов): Создать четыре файла /tmp/note_{1..4}.txt, по одному за шаг, каждый содержит свой номер в виде текста
Hermes: Создаю /tmp/note_1.txt прямо сейчас.
💻 echo "1" > /tmp/note_1.txt (0.1s)
Я создал /tmp/note_1.txt с содержимым "1". Я продолжу с остальными файлами на следующем шаге, как вы указали.
↻ Продолжение к цели (1/20): Создан только 1 из 4 файлов; осталось 3 файла.
Hermes: [Продолжение к вашей постоянной цели]
💻 echo "2" > /tmp/note_2.txt (0.1s)
Создан /tmp/note_2.txt. Осталось ещё два.
↻ Продолжение к цели (2/20): Создано 2 из 4 файлов; осталось 2.
Hermes: [Продолжение к вашей постоянной цели]
💻 echo "3" > /tmp/note_3.txt (0.1s)
Создан /tmp/note_3.txt.
↻ Продолжение к цели (3/20): Создано 3 из 4 файлов; остался 1.
Hermes: [Продолжение к вашей постоянной цели]
💻 echo "4" > /tmp/note_4.txt (0.1s)
Все четыре файла созданы: /tmp/note_1.txt... /tmp/note_4.txt, каждый содержит свой номер.
✓ Цель достигнута: Все четыре файла созданы с указанным содержимым, цель выполнена.
Вы: _
Четыре шага, один вызов /goal, ноль ваших запросов "продолжить".
Когда судья ошибается
Ни один судья не идеален. Следите за двумя типами ошибок:
Ложноположительное продолжение — судья говорит «продолжить», хотя цель на самом деле выполнена. Бюджет шагов бесконечного цикла цикла. Вы увидите ⏸ Цель потока и сможете активировать /goalclear или просто отправить новое сообщение.
Ложноотрицательное завершение — судья говорит «выполнено», работа осталась. Вы увидите хотя✓ Цель достигнута, но знаете, что это не так. Отправьте следующее сообщение, чтобы продолжить, или переустановите цель более точно: /goal <более конкретный текст>. Системный совет судьи намеренно соблюдать, чтобы ложноотрицательные заключения были реже, чем ложноположительные продолжения.
Если вы считаете вердикт судьи неубедительным, то в строке «↻ Продолжение достижения цели» или «✓ Цель достижения» будет показано, что именно увидел судья. Обычно этого достаточно, чтобы понять, была ли цель сформулирована неоднозначно, или модель ответа была неточной.
Атрибуция
/goal — это реализация Гермеса паттерна цикла Ральф. Пользовательский дизайн — сохранение целей между шагами, продолжение следует, с командами создания/паузы/возобновления/очистки — был популяризирован и реализован в Codex CLI 0.128.0 Эриком Траутом из команды Codex в OpenAI. Наша реализация независима (центральный реестр CommandDef, персистентность через SessionDB.state_meta, обслуживание вспомогательного клиента, продолжение через адаптер-FIFO на стороне шлюза), но идея принадлежит им. Должность там, где должна быть.