Tools

تشخیص حلقهٔ ابزار

Edit source

OpenClaw دو حفاظ همکاری‌کننده برای الگوهای تکراری فراخوانی ابزار دارد:

  1. تشخیص حلقه (tools.loopDetection.enabled) — به‌صورت پیش‌فرض غیرفعال است. تاریخچهٔ لغزان فراخوانی ابزار را برای الگوهای تکراری و تلاش‌های دوباره برای ابزار ناشناخته پایش می‌کند.
  2. محافظ پس از Compaction (tools.loopDetection.postCompactionGuard) — به‌صورت پیش‌فرض فعال است، مگر اینکه tools.loopDetection.enabled به‌صراحت false باشد. پس از هر تلاش دوبارهٔ Compaction مسلح می‌شود و وقتی agent سه‌تایی یکسان (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      },    },  },}

بازنویسی برای هر agent (اختیاری):

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 الگوهای متناوب پینگ‌پنگی را تشخیص می‌دهد.
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

وقتی اجراکننده پس از سرریز زمینه یک تلاش دوبارهٔ Compaction را کامل می‌کند، محافظی با بازهٔ کوتاه را مسلح می‌کند که چند فراخوانی ابزار بعدی را پایش می‌کند. اگر agent همان سه‌تایی (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 بیشتر تلاش‌های بازیابی بیشتری به agent می‌دهد.
  • وقتی نتایج در حال تغییر باشند، محافظ هرگز توقف نمی‌کند؛ فقط وقتی نتایج در سراسر بازه از نظر بایتی یکسان باشند.
  • این محافظ عمداً محدود است: فقط بلافاصله پس از یک تلاش دوبارهٔ Compaction فعال می‌شود.

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

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

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

مرتبط

Was this useful?