---
read_when:
    - Користувач повідомляє, що агенти застрягають, повторюючи виклики інструментів
    - Потрібно налаштувати захист від повторюваних викликів
    - Ви редагуєте політики інструментів/середовища виконання агента
    - Ви стикаєтеся з перериваннями `compaction_loop_persisted` після повторної спроби через переповнення контексту
summary: Як увімкнути й налаштувати запобіжники, які виявляють повторювані цикли викликів інструментів
title: Виявлення зациклення інструментів
x-i18n:
    generated_at: "2026-05-11T21:01:43Z"
    model: gpt-5.5
    provider: openai
    source_hash: cc261bebc0e3138a98ea8be166edbaf4e133c8f582429c5380fe2954196a6fc5
    source_path: tools/loop-detection.md
    workflow: 16
---

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
{
  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
{
  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
{
  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="/uk/tools/exec-approvals" icon="shield">
    Політика дозволу/заборони для виконання shell.
  </Card>
  <Card title="Рівні мислення" href="/uk/tools/thinking" icon="brain">
    Рівні зусилля міркування та взаємодія з політикою провайдера.
  </Card>
  <Card title="Субагенти" href="/uk/tools/subagents" icon="users">
    Запуск ізольованих агентів для обмеження неконтрольованої поведінки.
  </Card>
  <Card title="Довідник конфігурації" href="/uk/gateway/configuration-reference" icon="gear">
    Повна схема `tools.loopDetection` і семантика злиття.
  </Card>
</CardGroup>
