Tools

Виявлення циклів інструментів

OpenClaw має два узгоджені запобіжники проти повторюваних шаблонів викликів інструментів, обидва налаштовуються в tools.loopDetection:

  1. Виявлення циклів (enabled) — типово вимкнено. Відстежує ковзну історію викликів інструментів, щоб виявляти повторювані шаблони та повторні спроби виклику невідомих інструментів.
  2. Запобіжник після Compaction (postCompactionGuard) — увімкнений, якщо enabled явно не встановлено в false. Активується після кожної повторної спроби після Compaction і перериває виконання, якщо агент повторює ту саму трійку (інструмент, аргументи, результат) у межах вікна.

Установіть tools.loopDetection.enabled: false, щоб вимкнути обидва запобіжники.

Навіщо це потрібно

  • Виявляти повторювані послідовності, які не дають прогресу.
  • Виявляти високочастотні цикли без результату (той самий інструмент, ті самі вхідні дані, повторювані помилки).
  • Виявляти певні шаблони повторюваних викликів для відомих інструментів опитування.
  • Переривати цикли переповнення контексту -> Compaction -> той самий цикл, а не дозволяти їм виконуватися нескінченно.

Блок конфігурації

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

json5
{  tools: {    loopDetection: {      enabled: false, // головний перемикач детекторів ковзної історії      historySize: 30,      warningThreshold: 10,      criticalThreshold: 20,      unknownToolThreshold: 10,      globalCircuitBreakerThreshold: 30,      detectors: {        genericRepeat: true,        knownPollNoProgress: true,        pingPong: true,      },      postCompactionGuard: {        windowSize: 3, // активується після повторної спроби після Compaction; працює, якщо enabled явно не дорівнює false      },    },  },}

Перевизначення для окремого агента (необов’язково, у agents.list[].tools.loopDetection):

json5
{  agents: {    list: [      {        id: "safe-runner",        tools: {          loopDetection: {            enabled: true,            warningThreshold: 8,            criticalThreshold: 16,          },        },      },    ],  },}

Налаштування окремого агента накладаються на глобальний блок поле за полем (включно з вкладеними detectors і postCompactionGuard), тому агенту потрібно задавати лише поля, які він хоче змінити.

Поведінка полів

Поле Типове значення Вплив
enabled false Головний перемикач детекторів ковзної історії. false також вимикає запобіжник після Compaction.
historySize 30 Кількість останніх викликів інструментів, що зберігаються для аналізу.
warningThreshold 10 Кількість повторів, після якої шаблон класифікується як такий, що потребує лише попередження.
criticalThreshold 20 Кількість повторів для блокування шаблону циклу без прогресу. У разі помилкового налаштування середовище виконання підвищує це значення понад warningThreshold.
unknownToolThreshold 10 Блокує повторні виклики того самого недоступного інструмента після такої кількості невдалих спроб. Не залежить від detectors.
globalCircuitBreakerThreshold 30 Глобальний переривач циклів без прогресу для всіх детекторів. У разі помилкового налаштування середовище виконання підвищує це значення понад criticalThreshold. Не залежить від detectors.
detectors.genericRepeat true Попереджає про повторні виклики того самого інструмента з тими самими аргументами; блокує, коли ці виклики також повертають однакові результати.
detectors.knownPollNoProgress true Виявляє відомі шаблони опитування без прогресу (process з action: "poll"/"log", command_status).
detectors.pingPong true Виявляє почергові шаблони без прогресу між двома викликами.
postCompactionGuard.windowSize 3 Кількість спроб, протягом яких запобіжник залишається активним після Compaction, а також кількість однакових трійок, що спричиняє переривання виконання.

Для exec хешування відсутності прогресу порівнює стабільні результати команд (стан, код завершення, ознаку перевищення часу очікування, виведення) та ігнорує мінливі метадані середовища виконання, як-от тривалість, PID, ідентифікатор сеансу та робочий каталог. Результати надсилання вихідних повідомлень хешуються без мінливих ідентифікаторів окремих викликів (ідентифікатора повідомлення, ідентифікатора файлу, часової позначки), щоб результат «надіслано» не виглядав однаковим із результатом іншого надсилання. Коли доступний ідентифікатор виконання, історія оцінюється лише в межах цього виконання, тому заплановані цикли Heartbeat і нові виконання не успадковують застарілі лічильники циклів від попередніх виконань.

Рекомендоване налаштування

  • Для менших моделей установіть enabled: true і залиште порогові значення типовими. Провідним моделям детекція за ковзною історією потрібна рідко, тому можна залишити головний перемикач у стані false, водночас користуючись перевагами запобіжника після Compaction.
  • Зберігайте такий порядок порогових значень: warningThreshold < criticalThreshold < globalCircuitBreakerThreshold; середовище виконання збільшує criticalThreshold і globalCircuitBreakerThreshold, якщо ви встановите їх на рівні або нижче порогового значення, яке вони мають перевищувати.
  • Якщо виникають хибні спрацювання:
    • Збільште warningThreshold та/або criticalThreshold.
    • За потреби збільште globalCircuitBreakerThreshold.
    • Вимкніть лише конкретний детектор, який спричиняє проблеми (detectors.<name>: false).
    • Зменште historySize, щоб скоротити історичне вікно.
  • Щоб вимкнути все, включно із запобіжником після Compaction, явно встановіть tools.loopDetection.enabled: false.

Запобіжник після Compaction

Після повторної спроби з Compaction унаслідок переповнення контексту виконавець активує запобіжник із коротким вікном для кількох наступних викликів інструментів. Якщо агент видає ту саму трійку (toolName, argsHash, resultHash) postCompactionGuard.windowSize разів у межах цього вікна, запобіжник робить висновок, що Compaction не перервала цикл, і перериває виконання з помилкою compaction_loop_persisted.

Запобіжник керується головним прапорцем tools.loopDetection.enabled з однією особливістю: він залишається увімкненим, коли прапорець не задано або має значення true, і вимикається лише тоді, коли прапорець явно встановлено в false. Це зроблено навмисно — запобіжник дає змогу вийти з циклів Compaction, які інакше витрачали б необмежену кількість токенів, тому навіть користувач без конфігурації отримує цей захист.

json5
{  tools: {    loopDetection: {      // головний перемикач; установіть false, щоб вимкнути запобіжник разом із ковзними детекторами      enabled: true,      postCompactionGuard: {        windowSize: 3, // типове значення      },    },  },}
  • Менше значення windowSize є суворішим (менше спроб до переривання).
  • Більше значення windowSize дає агенту більше спроб відновлення.
  • Запобіжник ніколи не перериває виконання, доки результати змінюються; його активують лише побайтово однакові результати в межах вікна.
  • Він активується лише одразу після повторної спроби з Compaction, а не в інших точках виконання.

Журнали та очікувана поведінка

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

  • Спочатку з’являються попередження.
  • Блокування відбувається, коли шаблон зберігається після перевищення порога попередження.
  • Критичні порогові значення блокують наступний цикл роботи інструмента та додають чітку причину виявлення циклу до запису про виконання.
  • Запобіжник після Compaction генерує помилки compaction_loop_persisted, указуючи проблемний інструмент і кількість однакових викликів.

Пов’язані матеріали

Was this useful?
On this page

On this page