Lesson 7 / 25
Detecting No Progress
Catch repetition and oscillation with a small guard that remembers recent tool calls.
Busy but stuck
An agent can stay within every limit yet make no progress, for example calling the same tool with the same arguments again and again, or flipping between two states. The simplest guard remembers the last few calls and stops when the same call repeats several times.
A repeat guard
This ran as shown. The same read_file call on the third time trips the guard. sort_keys=True makes the arguments compare equal regardless of key order.
from collections import deque
import json
class RepeatGuard:
def __init__(self, window=6, limit=3):
self.recent = deque(maxlen=window)
self.limit = limit
def seen_too_often(self, name, args):
key = (name, json.dumps(args, sort_keys=True))
self.recent.append(key)
return self.recent.count(key) >= self.limit
g = RepeatGuard()
for _ in range(3):
print(g.seen_too_often("read_file", {"path": "a.txt"}))
Output:
False False True
Some repeats are fine
Polling a job status may legitimately repeat a call. Allow it with a larger limit or a wait between calls, but still cap the total.
Quick check: What does the RepeatGuard detect?
- Slow network speeds
- The same tool call with the same arguments repeating
- Spelling mistakes
- Missing API keys
Answer
The same tool call with the same arguments repeating — It counts identical recent calls and flags a loop that is going nowhere.