Loop guard: also identical call with identical result 3 times in a row; baseline restarts (run base 20500)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014aUaQeLnwbb1zTpN7kHeat
This commit is contained in:
@@ -156,8 +156,11 @@ class LlmAgent:
|
|||||||
err, text = proxy.call(fn["name"], args)
|
err, text = proxy.call(fn["name"], args)
|
||||||
messages.append({"role": "tool", "tool_call_id": c.get("id", ""),
|
messages.append({"role": "tool", "tool_call_id": c.get("id", ""),
|
||||||
"content": ("ERROR: " if err else "") + text[:12000]})
|
"content": ("ERROR: " if err else "") + text[:12000]})
|
||||||
if self.loop_guard and proxy.same_push_streak >= self.loop_guard:
|
streak = max(proxy.same_push_streak, proxy.same_call_streak)
|
||||||
final = f"Stopped: loop (the same source was pushed {proxy.same_push_streak} times in a row)."
|
if self.loop_guard and streak >= self.loop_guard:
|
||||||
|
final = (f"Stopped: loop (the same source was pushed {proxy.same_push_streak} times in a row)."
|
||||||
|
if proxy.same_push_streak >= self.loop_guard else
|
||||||
|
f"Stopped: loop (the same call with the same result {proxy.same_call_streak} times in a row).")
|
||||||
self.end_reason = "loop"
|
self.end_reason = "loop"
|
||||||
break
|
break
|
||||||
if self.end_reason == "loop":
|
if self.end_reason == "loop":
|
||||||
|
|||||||
@@ -71,6 +71,8 @@ class ToolProxy:
|
|||||||
self.activation_errors = [] # unique error messages of failed writes
|
self.activation_errors = [] # unique error messages of failed writes
|
||||||
self.same_push_streak = 0 # identical sap_push_source (object + source hash) in a row
|
self.same_push_streak = 0 # identical sap_push_source (object + source hash) in a row
|
||||||
self._last_push = None
|
self._last_push = None
|
||||||
|
self.same_call_streak = 0 # identical call (tool, arguments and result) in a row, any tool
|
||||||
|
self._last_call = None
|
||||||
self.log = open(log_path, "a")
|
self.log = open(log_path, "a")
|
||||||
self.adt = None
|
self.adt = None
|
||||||
self.fallbacks = [] # writes that needed the ADT activation fallback
|
self.fallbacks = [] # writes that needed the ADT activation fallback
|
||||||
@@ -171,6 +173,11 @@ class ToolProxy:
|
|||||||
for m in activation_messages(text, err):
|
for m in activation_messages(text, err):
|
||||||
if m not in self.activation_errors and len(self.activation_errors) < 30:
|
if m not in self.activation_errors and len(self.activation_errors) < 30:
|
||||||
self.activation_errors.append(m)
|
self.activation_errors.append(m)
|
||||||
|
if tool in MODEL_TOOLS and not result[1].startswith("Tool "):
|
||||||
|
ck = (tool, hashlib.md5(json.dumps(args, sort_keys=True).encode()).hexdigest(),
|
||||||
|
hashlib.md5(result[1].encode()).hexdigest())
|
||||||
|
self.same_call_streak = self.same_call_streak + 1 if ck == self._last_call else 1
|
||||||
|
self._last_call = ck
|
||||||
entry["is_error"], entry["result"] = result[0], result[1][:20000]
|
entry["is_error"], entry["result"] = result[0], result[1][:20000]
|
||||||
self.log.write(json.dumps(entry) + "\n")
|
self.log.write(json.dumps(entry) + "\n")
|
||||||
self.log.flush()
|
self.log.flush()
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ G0139, G0151, G0157, G0174, G0167, G0185. Use the same list before and after tra
|
|||||||
| temperature / top_p / top_k / min_p | 0.2 / 0.95 / 20 / 0 |
|
| temperature / top_p / top_k / min_p | 0.2 / 0.95 / 20 / 0 |
|
||||||
| max_tokens per turn | **16384**, sent in each request by `train/baseline.py` (`MAX_TOKENS`); the server limit stays 32768 |
|
| max_tokens per turn | **16384**, sent in each request by `train/baseline.py` (`MAX_TOKENS`); the server limit stays 32768 |
|
||||||
| Tool-call budget per task | 60 calls, 15 activations (T01 too) |
|
| Tool-call budget per task | 60 calls, 15 activations (T01 too) |
|
||||||
| Loop guard | `loop_guard` 3: the run ends when `sap_push_source` pushes the same source (object + md5) 3 times in a row; final report "Stopped: loop ...", `end_reason` "loop". Scores use the final state, so they do not change. Same after training. T01 of the first run (started before the guard) ran without it |
|
| Loop guard | `loop_guard` 3: the run ends when `sap_push_source` pushes the same source (object + md5) 3 times in a row, or when any tool is called 3 times in a row with the same arguments and the same result (read loop, e.g. G0105 pulled the same include 18 times); final report "Stopped: loop ...", `end_reason` "loop". Scores use the final state, so they do not change. Same after training. T01 of the first run (started before the guard) ran without it |
|
||||||
| Per run record | `end_reason` (report, loop, empty_response, tool_budget, time_budget, model_error, max_turns), `activation_failures`, `activation_error_messages` (unique), also in `baseline.json` |
|
| Per run record | `end_reason` (report, loop, empty_response, tool_budget, time_budget, model_error, max_turns), `activation_failures`, `activation_error_messages` (unique), also in `baseline.json` |
|
||||||
| Empty turn | retried (2 times), then the run stops ("Stopped: empty model response") |
|
| Empty turn | retried (2 times), then the run stops ("Stopped: empty model response") |
|
||||||
| Docker (A4H) | VM memory 36 GB (`MemoryMiB` 36864), container `--memory 32g --memory-swap 32g` (2026-10-04) |
|
| Docker (A4H) | VM memory 36 GB (`MemoryMiB` 36864), container `--memory 32g --memory-swap 32g` (2026-10-04) |
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
cd "$(dirname "$0")/.."
|
cd "$(dirname "$0")/.."
|
||||||
log() { echo "$(date '+%F %T') $*"; }
|
log() { echo "$(date '+%F %T') $*"; }
|
||||||
log "start baseline, 11 tasks, thinking off, max_tokens 16384, loop guard 3"
|
log "start baseline, 11 tasks, thinking off, max_tokens 16384, loop guard 3"
|
||||||
python3 train/baseline.py --label baseline --run-base 20400 > runs/stage1/baseline.log 2>&1 &
|
python3 train/baseline.py --label baseline --run-base 20500 > runs/stage1/baseline.log 2>&1 &
|
||||||
BP=$!
|
BP=$!
|
||||||
log "baseline PID $BP"
|
log "baseline PID $BP"
|
||||||
NOTE=0
|
NOTE=0
|
||||||
|
|||||||
Reference in New Issue
Block a user