Goals
На этой странице
/goal даёт Hermes постоянную цель, которая сохраняется между оборотами. После каждого оборота лёгкая модель-судья проверяет, достигнута ли цель последним ответом ассистента. Если нет, Hermes автоматически передаёт продолжение обратно в ту же сессию и продолжает работу — пока цель не будет достигнута, вы не приостановите или не очистите её, или не закончится лимит оборотов.
Это наша реализация цикла Ralph, напрямую вдохновлённая /goal из Codex CLI 0.128.0 от Эрика Траута (Eric Traut, OpenAI). Основная идея — поддерживать цель между оборотами и не останавливаться, пока она не достигнута — принадлежит им. Реализация здесь независима и адаптирована к архитектуре Hermes.
Когда использовать¶
Используйте /goal для задач, где вы хотите, чтобы Hermes работал итеративно без ваших повторных запросов на каждом обороте:
- «Исправь все ошибки линтинга в
src/и проверь, чтоruff checkпроходит» - «Порти функцию X из репозитория Y, включая тесты, и добейся зелёного CI»
- «Выясни, почему идентификаторы сессий иногда дрейфуют при сжатии во время выполнения, и напиши отчёт»
- «Создай небольшую утилиту CLI для переименования файлов по EXIF-датам, затем протестируй её на папке photos/»
Задачи, где агент делает один оборот и останавливается, не требуют /goal. Этот инструмент shines там, где вам иначе пришлось бы трижды сказать «продолжай».
Быстрый старт¶
[code] /goal Исправь все падающие тесты в tests/hermes_cli/ и убедись, что scripts/run_tests.sh проходит для этой директории
[/code]
Что вы увидите:
- Цель принята —
⊙ Цель установлена (лимит: 20 оборотов): <ваша цель> - Оборот 1 запускается — Hermes начинает работу, как если бы вы отправили цель как обычное сообщение.
- Судья запускается — после оборота модель-судья решает:
done(готово) илиcontinue(продолжить). - Цикл срабатывает при необходимости — если
continue, вы увидите↻ Продолжение к цели (1/20): <причина судьи>, и Hermes автоматически делает следующий шаг. - Завершение — в итоге вы видите либо
✓ Цель достигнута: <причина>, либо⏸ Цель приостановлена — использовано N/20 оборотов.
Команды¶
| Команда | Что делает |
|---|---|
/goal <текст> |
Установить (или заменить) постоянную цель. Сразу запускает первый оборот, так что вам не нужно отправлять отдельное сообщение. |
/goal или /goal status |
Показать текущую цель, её статус и использованные обороты. |
/goal pause |
Остановить цикл автопродолжения без очистки цели. |
/goal resume |
Возобновить цикл (сбрасывает счётчик оборотов до нуля). |
/goal clear |
Полностью удалить цель. |
Работает одинаково в CLI и на всех платформах-шлюзах (Telegram, Discord, Slack, Matrix, Signal, WhatsApp, SMS, iMessage, Webhook, API-сервер и веб-панель).
Детали поведения¶
Судья¶
После каждого оборота Hermes вызывает вспомогательную модель с:
- Текстом текущей цели
- Самым последним финальным ответом агента (последние ~4 КБ текста)
- Системным промптом, предписывающим судье отвечать строгим JSON:
{"done": <bool>, "reason": "<обоснование в одно предложение>"}
Судья намеренно консервативен: он помечает цель как done только когда ответ явно подтверждает завершение цели, когда финальный результат явно получен, или когда цель недостижима/заблокирована (считается как DONE с причиной блокировки, чтобы не тратить лимит на невыполнимые задачи).
Отказоустойчивая семантика¶
Если судья выдаёт ошибку (сбой сети, некорректный ответ, недоступный вспомогательный клиент), Hermes считает вердикт как continue — сломанный судья никогда не блокирует прогресс. Лимит оборотов является настоящей предохранительной мерой.
Лимит оборотов¶
По умолчанию — 20 оборотов продолжения (goals.max_turns в config.yaml). Когда лимит исчерпан, Hermes автоматически приостанавливает цель и сообщает, как действовать дальше:
[code] ⏸ Цель приостановлена — использовано 20/20 оборотов. Используйте /goal resume для продолжения или /goal clear для остановки.
[/code]
/goal resume сбрасывает счётчик до нуля, так что вы можете продолжать работу в ограниченных сегментах.
Сообщения пользователя всегда имеют приоритет¶
Любое реальное сообщение, которое вы отправляете, пока активна цель, имеет приоритет над циклом продолжения. В 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:
[code] goals: # Максимальное количество оборотов продолжения до автопаузы Hermes и запроса # /goal resume. По умолчанию 20. Уменьшите для более плотных циклов; # увеличьте для длительных рефакторингов. max_turns: 20
[/code]
Выбор модели-судьи¶
Судья использует вспомогательную задачу goal_judge. По умолчанию она разрешается в вашу основную модель (см. Вспомогательные модели). Если вы хотите направить судью на дешёвую быструю модель для снижения затрат, добавьте переопределение:
[code] auxiliary: goal_judge: provider: openrouter model: google/gemini-3-flash-preview
[/code]
Вызов судьи небольшой (~200 выходных токенов) и выполняется один раз за оборот, поэтому дешёвая быстрая модель обычно является правильным выбором.
Пример работы¶
[code] Вы: /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, каждый содержит свой номер.
✓ Цель достигнута: Все четыре файла были созданы с указанным содержимым, цель выполнена.
Вы: _
[/code]
Четыре оборота, один вызов /goal, ни одного «продолжай» от вас.
Когда судья ошибается¶
Ни один судья не идеален. Два сценария отказа, на которые стоит обратить внимание:
Ложноотрицательный результат — судья говорит «продолжить», когда цель фактически достигнута. Лимит оборотов перехватывает это. Вы увидите ⏸ Цель приостановлена и можете выполнить /goal clear или просто отправить новое сообщение.
Ложноположительный результат — судья говорит «готово», когда работа ещё не завершена. Вы увидите ✓ Цель достигнута, но знаете, что это не так. Отправьте дополнительное сообщение, чтобы продолжить, или переформулируйте цель более точно: /goal <более конкретный текст>. Системный промпт судьи намеренно консервативен, чтобы ложноположительные результаты были реже ложноотрицательных.
Если вы считаете вердикт судьи неубедительным, текст причины в строках ↻ Продолжение к цели или ✓ Цель достигнута говорит вам, что именно увидел судья. Этого обычно достаточно, чтобы понять, была ли неоднозначной формулировка цели или ответ модели.
Атрибуция¶
/goal — это реализация Hermes паттерна цикла Ralph. Дизайн, ориентированный на пользователя — поддержание цели между оборотами, остановка только при достижении цели, с командами создания, паузы, возобновления и очистки — был популяризирован и выпущен в Codex CLI 0.128.0 Эриком Траутом из команды Codex в OpenAI. Наша реализация независима (центральный реестр CommandDef, персистентность SessionDB.state_meta, судья на вспомогательном клиенте, продолжение через FIFO-адаптер на стороне шлюза), но идея принадлежит им. Воздаём должное там, где это заслужено.