> ## Documentation Index
> Fetch the complete documentation index at: https://docs2.openclaw.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Обнаружение циклов инструментов

OpenClaw имеет два взаимодействующих защитных механизма для повторяющихся паттернов вызовов инструментов:

1. **Обнаружение циклов** (`tools.loopDetection.enabled`) — по умолчанию отключено. Отслеживает скользящую историю вызовов инструментов на предмет повторяющихся паттернов и повторных попыток с неизвестными инструментами.
2. **Защита после Compaction** (`tools.loopDetection.postCompactionGuard`) — по умолчанию включена, если только `tools.loopDetection.enabled` явно не задано как `false`. Активируется после каждой повторной попытки после Compaction и прерывает запуск, когда агент выдает один и тот же триплет `(tool, args, result)` в пределах окна.

Оба механизма настраиваются в одном блоке `tools.loopDetection`, но защита после Compaction работает всякий раз, когда главный переключатель явно не выключен. Установите `tools.loopDetection.enabled: false`, чтобы отключить обе поверхности.

## Зачем это нужно

* Обнаруживать повторяющиеся последовательности, которые не дают прогресса.
* Обнаруживать высокочастотные циклы без результата (тот же инструмент, те же входные данные, повторяющиеся ошибки).
* Обнаруживать конкретные паттерны повторных вызовов для известных инструментов опроса.
* Предотвращать бесконечные циклы «переполнение контекста, затем Compaction, затем тот же цикл».

## Блок конфигурации

Глобальные значения по умолчанию, со всеми документированными полями:

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  tools: {
    loopDetection: {
      enabled: false, // master switch for the rolling-history detectors
      historySize: 30,
      warningThreshold: 10,
      criticalThreshold: 20,
      unknownToolThreshold: 10,
      globalCircuitBreakerThreshold: 30,
      detectors: {
        genericRepeat: true,
        knownPollNoProgress: true,
        pingPong: true,
      },
      postCompactionGuard: {
        windowSize: 3, // armed after compaction-retry; runs unless enabled is explicitly false
      },
    },
  },
}
```

Переопределение для отдельного агента (необязательно):

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  agents: {
    list: [
      {
        id: "safe-runner",
        tools: {
          loopDetection: {
            enabled: true,
            warningThreshold: 8,
            criticalThreshold: 16,
          },
        },
      },
    ],
  },
}
```

### Поведение полей

| Поле                             | По умолчанию | Эффект                                                                                                                                                         |
| -------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `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, которые иначе сжигали бы неограниченное количество токенов, поэтому пользователь без конфигурации все равно получает защиту.

```json5 theme={"theme":{"light":"min-light","dark":"min-dark"}}
{
  tools: {
    loopDetection: {
      // master switch; set false to disable the guard along with the rolling detectors
      enabled: true,
      postCompactionGuard: {
        windowSize: 3, // default
      },
    },
  },
}
```

* Меньший `windowSize` строже (меньше попыток до прерывания).
* Больший `windowSize` дает агенту больше попыток восстановления.
* Защита никогда не прерывает запуск, когда результаты меняются, а только когда результаты байт-в-байт идентичны в пределах окна.
* Она намеренно узкая: срабатывает только сразу после повторной попытки после Compaction.

<Note>
  Защита после Compaction работает всякий раз, когда главный флаг явно не равен `false`, даже если вы никогда не писали блок `tools.loopDetection`. Чтобы проверить, ищите `post-compaction guard armed for N attempts` в журнале Gateway сразу после события Compaction.
</Note>

## Журналы и ожидаемое поведение

Когда цикл обнаружен, OpenClaw сообщает о событии цикла и либо ослабляет, либо блокирует следующий цикл инструментов в зависимости от серьезности. Это защищает пользователей от неконтролируемых затрат токенов и зависаний, сохраняя обычный доступ к инструментам.

* Сначала идут предупреждения.
* Подавление следует, когда паттерны сохраняются после порога предупреждения.
* Критические пороги блокируют следующий цикл инструментов и показывают ясную причину обнаружения цикла в записи запуска.
* Защита после Compaction выдает ошибки `compaction_loop_persisted` с именем проблемного инструмента и числом идентичных вызовов.

## Связанные материалы

<CardGroup cols={2}>
  <Card title="Подтверждения Exec" href="/ru/tools/exec-approvals" icon="shield">
    Политика разрешения/запрета для выполнения команд shell.
  </Card>

  <Card title="Уровни мышления" href="/ru/tools/thinking" icon="brain">
    Уровни усилия рассуждения и взаимодействие с политикой провайдера.
  </Card>

  <Card title="Субагенты" href="/ru/tools/subagents" icon="users">
    Запуск изолированных агентов для ограничения неконтролируемого поведения.
  </Card>

  <Card title="Справочник по конфигурации" href="/ru/gateway/configuration-reference" icon="gear">
    Полная схема `tools.loopDetection` и семантика слияния.
  </Card>
</CardGroup>
