

























@@ -5,37 +5,45 @@ read_when:
55 - A user reports agents getting stuck repeating tool calls
66 - You need to tune repetitive-call protection
77 - You are editing agent tool/runtime policies
8+ - You hit `compaction_loop_persisted` aborts after a context-overflow retry
89---
91010-OpenClaw can keep agents from getting stuck in repeated tool-call patterns.
11-The guard is **disabled by default**.
11+OpenClaw has two cooperating guardrails for repetitive tool-call patterns:
121213-Enable it only where needed, because it can block legitimate repeated calls with strict settings.
13+1. **Loop detection** (`tools.loopDetection.enabled`) — disabled by default. Watches the rolling tool-call history for repeated patterns and unknown-tool retries.
14+2. **Post-compaction guard** (`tools.loopDetection.postCompactionGuard`) — enabled by default unless `tools.loopDetection.enabled` is explicitly `false`. Arms after every compaction-retry and aborts the run when the agent emits the same `(tool, args, result)` triple within the window.
15+16+Both are configured under the same `tools.loopDetection` block, but the post-compaction guard runs whenever the master switch is not explicitly off. Set `tools.loopDetection.enabled: false` to silence both surfaces.
14171518## Why this exists
16191720- Detect repetitive sequences that do not make progress.
1821- Detect high-frequency no-result loops (same tool, same inputs, repeated errors).
1922- Detect specific repeated-call patterns for known polling tools.
23+- Prevent context-overflow then compaction then same-loop cycles from running indefinitely.
20242125## Configuration block
222623-Global defaults:
27+Global defaults, with every documented field shown:
24282529```json5
2630{
2731 tools: {
2832 loopDetection: {
29- enabled: false,
33+ enabled: false, // master switch for the rolling-history detectors
3034 historySize: 30,
3135 warningThreshold: 10,
3236 criticalThreshold: 20,
37+ unknownToolThreshold: 10,
3338 globalCircuitBreakerThreshold: 30,
3439 detectors: {
3540 genericRepeat: true,
3641 knownPollNoProgress: true,
3742 pingPong: true,
3843 },
44+ postCompactionGuard: {
45+ windowSize: 3, // armed after compaction-retry; runs unless enabled is explicitly false
46+ },
3947 },
4048 },
4149}
@@ -64,67 +72,83 @@ Per-agent override (optional):
64726573### Field behavior
667467-- `enabled`: Master switch. `false` means no loop detection is performed.
68-- `historySize`: number of recent tool calls kept for analysis.
69-- `warningThreshold`: threshold before classifying a pattern as warning-only.
70-- `criticalThreshold`: threshold for blocking repetitive loop patterns.
71-- `globalCircuitBreakerThreshold`: global no-progress breaker threshold.
72-- `detectors.genericRepeat`: detects repeated same-tool + same-params patterns.
73-- `detectors.knownPollNoProgress`: detects known polling-like patterns with no state change.
74-- `detectors.pingPong`: detects alternating ping-pong patterns.
75-76-For `exec`, no-progress checks compare stable command outcomes and ignore volatile runtime metadata such as duration, PID, session ID, and working directory.
77-When a run id is available, recent tool-call history is evaluated only within that run so scheduled heartbeat cycles and fresh runs do not inherit stale loop counts from earlier runs.
75+| Field | Default | Effect |
76+| -------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
77+| `enabled` | `false` | Master switch for the rolling-history detectors. Setting `false` also disables the post-compaction guard. |
78+| `historySize` | `30` | Number of recent tool calls kept for analysis. |
79+| `warningThreshold` | `10` | Threshold before a pattern is classified as warning-only. |
80+| `criticalThreshold` | `20` | Threshold for blocking repetitive loop patterns. |
81+| `unknownToolThreshold` | `10` | Block repeated calls to the same unavailable tool after this many misses. |
82+| `globalCircuitBreakerThreshold` | `30` | Global no-progress breaker threshold across all detectors. |
83+| `detectors.genericRepeat` | `true` | Detects repeated same-tool + same-params patterns. |
84+| `detectors.knownPollNoProgress` | `true` | Detects known polling-like patterns with no state change. |
85+| `detectors.pingPong` | `true` | Detects alternating ping-pong patterns. |
86+| `postCompactionGuard.windowSize` | `3` | Number of post-compaction tool calls during which the guard stays armed and the count of identical triples that aborts the run. |
87+88+For `exec`, no-progress checks compare stable command outcomes and ignore volatile runtime metadata such as duration, PID, session ID, and working directory. When a run id is available, recent tool-call history is evaluated only within that run so scheduled heartbeat cycles and fresh runs do not inherit stale loop counts from earlier runs.
78897990## Recommended setup
809181-- For smaller models, start with `enabled: true`, defaults unchanged. Flagship models rarely need loop detection and can leave it disabled.
92+- For smaller models, set `enabled: true` and leave the thresholds at their defaults. Flagship models rarely need rolling-history detection and can leave the master switch at `false` while still benefiting from the post-compaction guard.
8293- Keep thresholds ordered as `warningThreshold < criticalThreshold < globalCircuitBreakerThreshold`.
8394- If false positives occur:
84-- raise `warningThreshold` and/or `criticalThreshold`
85-- (optionally) raise `globalCircuitBreakerThreshold`
86-- disable only the detector causing issues
87-- reduce `historySize` for less strict historical context
95+- Raise `warningThreshold` and/or `criticalThreshold`.
96+- Optionally raise `globalCircuitBreakerThreshold`.
97+- Disable only the specific detector causing issues (`detectors.<name>: false`).
98+- Reduce `historySize` for less strict historical context.
99+- To disable everything (including the post-compaction guard), set `tools.loopDetection.enabled: false` explicitly.
8810089101## Post-compaction guard
9010291-When the runner completes an auto-compaction-retry (after a context-overflow), it arms a short-window guard that watches the next few tool calls. If the agent emits the _same_ `(toolName, args, result)` triple multiple times within that window, the guard concludes that compaction did not break the loop and aborts the run with a `compaction_loop_persisted` error.
103+When the runner completes a compaction-retry after a context-overflow, it arms a short-window guard that watches the next few tool calls. If the agent emits the same `(toolName, argsHash, resultHash)` triple multiple times within the window, the guard concludes that compaction did not break the loop and aborts the run with a `compaction_loop_persisted` error.
9210493-This is a separate code path from the global `tools.loopDetection` detectors. It is independently configurable:
105+The guard is gated by the master `tools.loopDetection.enabled` flag with one twist: it stays **enabled when the flag is unset or `true`** and only deactivates when the flag is explicitly `false`. This is intentional. The guard exists to escape compaction loops that would otherwise burn unbounded tokens, so a no-config user still gets the protection.
9410695107```json5
96108{
97109 tools: {
98110 loopDetection: {
99- enabled: true, // existing master switch; set false to disable loop guards
111+// master switch; set false to disable the guard along with the rolling detectors
112+ enabled: true,
100113 postCompactionGuard: {
101- windowSize: 3, // default: 3
114+ windowSize: 3, // default
102115 },
103116 },
104117 },
105118}
106119```
107120108-- `windowSize`: number of post-compaction tool calls during which the guard stays armed _and_ the count of identical (tool, args, result) triples that triggers an abort.
121+- Lower `windowSize` is stricter (fewer attempts before abort).
122+- Higher `windowSize` gives the agent more recovery attempts.
123+- The guard never aborts when results are changing, only when results are byte-identical across the window.
124+- It is intentionally narrow: it fires only in the immediate aftermath of a compaction-retry.
109125110-The guard never aborts when results are changing, only when results are byte-identical across the window. It is intentionally narrow: it fires only in the immediate aftermath of a compaction-retry.
126+<Note>
127+ The post-compaction guard runs whenever the master flag is not explicitly `false`, even if you never wrote a `tools.loopDetection` block. To verify, look for `post-compaction guard armed for N attempts` in the gateway log immediately after a compaction event.
128+</Note>
111129112130## Logs and expected behavior
113131114-When a loop is detected, OpenClaw reports a loop event and blocks or dampens the next tool-cycle depending on severity.
115-This protects users from runaway token spend and lockups while preserving normal tool access.
116-117-- Prefer warning and temporary suppression first.
118-- Escalate only when repeated evidence accumulates.
119-120-## Notes
132+When a loop is detected, OpenClaw reports a loop event and either dampens or blocks the next tool-cycle depending on severity. This protects users from runaway token spend and lockups while preserving normal tool access.
121133122-- `tools.loopDetection` is merged with agent-level overrides.
123-- Per-agent config fully overrides or extends global values.
124-- If no config exists, guardrails stay off.
134+- Warnings come first.
135+- Suppression follows when patterns persist past the warning threshold.
136+- Critical thresholds block the next tool-cycle and surface a clear loop-detection reason in the run record.
137+- The post-compaction guard emits `compaction_loop_persisted` errors with the offending tool name and identical-call count.
125138126139## Related
127140128-- [Exec approvals](/tools/exec-approvals)
129-- [Thinking levels](/tools/thinking)
130-- [Sub-agents](/tools/subagents)
141+<CardGroup cols={2}>
142+<Card title="Exec approvals" href="/tools/exec-approvals" icon="shield">
143+Allow/deny policy for shell execution.
144+</Card>
145+<Card title="Thinking levels" href="/tools/thinking" icon="brain">
146+Reasoning effort levels and provider-policy interaction.
147+</Card>
148+<Card title="Sub-agents" href="/tools/subagents" icon="users">
149+Spawning isolated agents to bound runaway behavior.
150+</Card>
151+<Card title="Configuration reference" href="/gateway/configuration-reference" icon="gear">
152+Full `tools.loopDetection` schema and merging semantics.
153+</Card>
154+</CardGroup>
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。