Define a stopping rule
A model can repeatedly propose the same tool call when a result is missing or misunderstood. Put a limit in the application that runs the loop. Do not rely solely on the next model reply deciding to stop.
Start with two clear rules: a maximum number of steps for one run, and a maximum number of identical consecutive calls. Tune these limits to the workflow. Repeating a read may be useful; repeating a write can have consequences. This local example stops before dispatching a repeated operation and never calls MandAPI or a tool.
Check calls before dispatch
Canonicalize the action and arguments, then hash the serialized value. Only include fields that define the operation. Request timestamps or random identifiers would make equivalent operations look different.
import hashlib
import json
class LoopGuard:
def __init__(self, max_steps=8, max_identical=2):
self.max_steps = max_steps
self.max_identical = max_identical
self.steps = 0
self.last = None
self.repeated = 0
def check(self, name, arguments):
if self.steps >= self.max_steps:
raise RuntimeError("Step limit reached")
raw = json.dumps(
{"name": name, "arguments": arguments},
sort_keys=True, separators=(",", ":"),
)
fingerprint = hashlib.sha256(raw.encode()).hexdigest()
self.repeated = self.repeated + 1 if fingerprint == self.last else 1
self.last = fingerprint
if self.repeated > self.max_identical:
raise RuntimeError("Repeated operation stopped")
self.steps += 1
return {"step": self.steps, "fingerprint": fingerprint}
guard = LoopGuard()
print(guard.check("lookup_order", {"order_id": "demo-001"}))
print(guard.check("lookup_order", {"order_id": "demo-001"}))
try:
guard.check("lookup_order", {"order_id": "demo-001"})
except RuntimeError as error:
print(error)Integrate with a model loop
Run the guard after validating a proposed call and before executing it. Store its trace with the run identifier, operation result, and stop reason. On a stop, return a useful explanation or route the task to a person. The rules live in your application; there is no special Decisions API or model confidence score involved.
Check the result
The demonstration accepts two identical lookups and stops the third. Also test distinct calls until the step limit is reached. This fingerprint only catches exact normalized repetition, not semantic equivalence; retain the step limit as a separate boundary.