Перейти к содержанию

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]

Что вы увидите:

  1. Цель принята⊙ Цель установлена (лимит: 20 оборотов): <ваша цель>
  2. Оборот 1 запускается — Hermes начинает работу, как если бы вы отправили цель как обычное сообщение.
  3. Судья запускается — после оборота модель-судья решает: done (готово) или continue (продолжить).
  4. Цикл срабатывает при необходимости — если continue, вы увидите ↻ Продолжение к цели (1/20): <причина судьи>, и Hermes автоматически делает следующий шаг.
  5. Завершение — в итоге вы видите либо ✓ Цель достигнута: <причина>, либо ⏸ Цель приостановлена — использовано 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-адаптер на стороне шлюза), но идея принадлежит им. Воздаём должное там, где это заслужено.