- Обнаружение циклов (
tools.loopDetection.enabled) — по умолчанию отключено. Отслеживает скользящую историю вызовов инструментов на предмет повторяющихся паттернов и повторных попыток с неизвестными инструментами. - Защита после Compaction (
tools.loopDetection.postCompactionGuard) — по умолчанию включена, если толькоtools.loopDetection.enabledявно не задано какfalse. Активируется после каждой повторной попытки после Compaction и прерывает запуск, когда агент выдает один и тот же триплет(tool, args, result)в пределах окна.
tools.loopDetection, но защита после Compaction работает всякий раз, когда главный переключатель явно не выключен. Установите tools.loopDetection.enabled: false, чтобы отключить обе поверхности.
Зачем это нужно
- Обнаруживать повторяющиеся последовательности, которые не дают прогресса.
- Обнаруживать высокочастотные циклы без результата (тот же инструмент, те же входные данные, повторяющиеся ошибки).
- Обнаруживать конкретные паттерны повторных вызовов для известных инструментов опроса.
- Предотвращать бесконечные циклы «переполнение контекста, затем Compaction, затем тот же цикл».
Блок конфигурации
Глобальные значения по умолчанию, со всеми документированными полями:Поведение полей
| Поле | По умолчанию | Эффект |
|---|---|---|
enabled | false | Главный переключатель для детекторов скользящей истории. Значение false также отключает защиту после Compaction. |
historySize | 30 | Количество последних вызовов инструментов, сохраняемых для анализа. |
warningThreshold | 10 | Порог, после которого паттерн классифицируется только как предупреждение. |
criticalThreshold | 20 | Порог для блокировки повторяющихся циклических паттернов без прогресса. |
unknownToolThreshold | 10 | Блокировать повторные вызовы одного и того же недоступного инструмента после такого количества промахов. |
globalCircuitBreakerThreshold | 30 | Глобальный порог прерывателя для отсутствия прогресса по всем детекторам. |
detectors.genericRepeat | true | Предупреждает о повторяющихся паттернах «тот же инструмент + те же параметры» и блокирует, когда те же вызовы также возвращают одинаковые исходы. |
detectors.knownPollNoProgress | true | Обнаруживает известные паттерны, похожие на опрос, без изменения состояния. |
detectors.pingPong | true | Обнаруживает чередующиеся паттерны ping-pong. |
postCompactionGuard.windowSize | 3 | Количество вызовов инструментов после Compaction, в течение которых защита остается активной, и число идентичных триплетов, после которого запуск прерывается. |
exec проверки отсутствия прогресса сравнивают стабильные результаты команд и игнорируют изменчивые метаданные времени выполнения, такие как длительность, PID, идентификатор сессии и рабочий каталог. Когда доступен идентификатор запуска, недавняя история вызовов инструментов оценивается только в пределах этого запуска, поэтому запланированные циклы Heartbeat и новые запуски не наследуют устаревшие счетчики циклов из более ранних запусков.
Рекомендуемая настройка
- Для небольших моделей установите
enabled: trueи оставьте пороги по умолчанию. Флагманским моделям редко нужно обнаружение по скользящей истории, и они могут оставить главный переключатель вfalse, при этом по-прежнему получая пользу от защиты после Compaction. - Сохраняйте порядок порогов как
warningThreshold < criticalThreshold < globalCircuitBreakerThreshold. - Если возникают ложные срабатывания:
- Увеличьте
warningThresholdи/илиcriticalThreshold. - При необходимости увеличьте
globalCircuitBreakerThreshold. - Отключите только конкретный детектор, вызывающий проблемы (
detectors.<name>: false). - Уменьшите
historySizeдля менее строгого исторического контекста.
- Увеличьте
- Чтобы отключить все (включая защиту после Compaction), явно установите
tools.loopDetection.enabled: false.
Защита после Compaction
Когда runner завершает повторную попытку после Compaction вследствие переполнения контекста, он активирует защиту с коротким окном, которая отслеживает следующие несколько вызовов инструментов. Если агент выдает один и тот же триплет(toolName, argsHash, resultHash) несколько раз в пределах окна, защита делает вывод, что Compaction не разорвал цикл, и прерывает запуск с ошибкой compaction_loop_persisted.
Защита управляется главным флагом tools.loopDetection.enabled с одним нюансом: она остается включенной, когда флаг не задан или равен true, и деактивируется только когда флаг явно задан как false. Это намеренно. Защита существует, чтобы выходить из циклов Compaction, которые иначе сжигали бы неограниченное количество токенов, поэтому пользователь без конфигурации все равно получает защиту.
- Меньший
windowSizeстроже (меньше попыток до прерывания). - Больший
windowSizeдает агенту больше попыток восстановления. - Защита никогда не прерывает запуск, когда результаты меняются, а только когда результаты байт-в-байт идентичны в пределах окна.
- Она намеренно узкая: срабатывает только сразу после повторной попытки после Compaction.
Защита после Compaction работает всякий раз, когда главный флаг явно не равен
false, даже если вы никогда не писали блок tools.loopDetection. Чтобы проверить, ищите post-compaction guard armed for N attempts в журнале Gateway сразу после события Compaction.Журналы и ожидаемое поведение
Когда цикл обнаружен, OpenClaw сообщает о событии цикла и либо ослабляет, либо блокирует следующий цикл инструментов в зависимости от серьезности. Это защищает пользователей от неконтролируемых затрат токенов и зависаний, сохраняя обычный доступ к инструментам.- Сначала идут предупреждения.
- Подавление следует, когда паттерны сохраняются после порога предупреждения.
- Критические пороги блокируют следующий цикл инструментов и показывают ясную причину обнаружения цикла в записи запуска.
- Защита после Compaction выдает ошибки
compaction_loop_persistedс именем проблемного инструмента и числом идентичных вызовов.
Связанные материалы
Подтверждения Exec
Политика разрешения/запрета для выполнения команд shell.
Уровни мышления
Уровни усилия рассуждения и взаимодействие с политикой провайдера.
Субагенты
Запуск изолированных агентов для ограничения неконтролируемого поведения.
Справочник по конфигурации
Полная схема
tools.loopDetection и семантика слияния.