---
read_when:
    - یک کاربر گزارش می‌دهد که عامل‌ها در تکرار فراخوانی ابزارها گیر می‌کنند
    - باید محافظت در برابر فراخوانی‌های تکراری را تنظیم کنید
    - شما در حال ویرایش سیاست‌های ابزار/زمان اجرای عامل هستید
    - پس از تلاش مجدد به‌دلیل سرریز زمینه، با توقف‌های `compaction_loop_persisted` مواجه می‌شوید
summary: نحوهٔ فعال‌سازی و تنظیم محافظ‌هایی که حلقه‌های تکراری فراخوانی ابزار را تشخیص می‌دهند
title: تشخیص حلقهٔ ابزار
x-i18n:
    generated_at: "2026-07-12T11:02:47Z"
    model: gpt-5.6
    postprocess_version: locale-links-v1
    provider: openai
    source_hash: fccbb81281b6c6921e6dad50d15295c1be3f59c664f2caed900bf3dce14bc40a
    source_path: tools/loop-detection.md
    workflow: 16
---

OpenClaw دو سازوکار محافظتی هماهنگ برای مقابله با الگوهای تکراری فراخوانی ابزار دارد که هر دو در `tools.loopDetection` پیکربندی می‌شوند:

1. **تشخیص حلقه** (`enabled`) - به‌طور پیش‌فرض غیرفعال است. تاریخچهٔ لغزان فراخوانی ابزار را برای یافتن الگوهای تکراری و تلاش‌های مجدد برای ابزارهای ناشناخته زیر نظر می‌گیرد.
2. **محافظ پس از Compaction** (`postCompactionGuard`) - هرگاه `enabled` صراحتاً `false` نباشد فعال است. پس از هر تلاش مجدد متعاقب Compaction آماده می‌شود و اگر عامل در محدودهٔ تعیین‌شده همان سه‌تایی `(tool, args, result)` را تکرار کند، اجرا را متوقف می‌کند.

برای غیرفعال‌کردن هر دو سازوکار محافظتی، `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
      },
    },
  },
}
```

بازنویسی ویژهٔ هر عامل (اختیاری، در `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: {
      // 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` را ننوشته باشید. برای بررسی، بلافاصله پس از یک رویداد Compaction، عبارت `post-compaction guard armed for N attempts` را در گزارش Gateway جست‌وجو کنید.
</Note>

## گزارش‌ها و رفتار مورد انتظار

هنگامی که حلقه‌ای تشخیص داده می‌شود، OpenClaw یک رویداد حلقه را ثبت می‌کند و بسته به شدت، دربارهٔ چرخهٔ بعدی ابزار هشدار می‌دهد یا آن را مسدود می‌کند؛ به این ترتیب، ضمن حفظ دسترسی عادی به ابزارها، از مصرف مهارنشدهٔ توکن و قفل‌شدن جلوگیری می‌شود.

- ابتدا هشدارها صادر می‌شوند.
- اگر یک الگو از آستانهٔ هشدار عبور کرده و ادامه یابد، مسدودسازی انجام می‌شود.
- آستانه‌های بحرانی چرخهٔ بعدی ابزار را مسدود می‌کنند و دلیل روشنی برای تشخیص حلقه در رکورد اجرا نمایش می‌دهند.
- محافظ پس از Compaction خطاهای `compaction_loop_persisted` را با ذکر ابزار متخلف و تعداد فراخوانی‌های یکسان تولید می‌کند.

## مرتبط

<CardGroup cols={2}>
  <Card title="تأییدهای اجرای فرمان" href="/fa/tools/exec-approvals" icon="shield">
    خط‌مشی اجازه/رد برای اجرای پوسته.
  </Card>
  <Card title="سطوح تفکر" href="/fa/tools/thinking" icon="brain">
    سطوح تلاش استدلالی و تعامل آن‌ها با خط‌مشی ارائه‌دهنده.
  </Card>
  <Card title="عامل‌های فرعی" href="/fa/tools/subagents" icon="users">
    ایجاد عامل‌های مجزا برای محدودکردن رفتار مهارنشده.
  </Card>
  <Card title="مرجع پیکربندی" href="/fa/gateway/config-tools#toolsloopdetection" icon="gear">
    طرح‌وارهٔ کامل `tools.loopDetection` و معناشناسی ادغام.
  </Card>
</CardGroup>
