L03 Code — Five-Stage Loop Internals
Goal: Run the 5-stage loop simulator and watch each stage execute — READ goal, GENERATE change, EVALUATE, KEEP/REVERT, LOG to TSV — the same sequence as a real
/autoresearchrun.
Run it:
cd docs/en/lectures/lecture-03-five-stage-loop-internals/code
python loop_simulator.pyStep 1: Bootstrap and configure
import csv, os, random, math
from datetime import datetime
MAX_ITERATIONS = 10
TARGET_SCORE = 0.90
RANDOM_SEED = 7
random.seed(RANDOM_SEED)
if not os.path.exists("research.md"):
with open("research.md", "w") as f:
f.write("# Research Goal\n\n## Target\n0.90\n\n## Metric\naccuracy\n")Key line: Writing research.md if it doesn't exist mirrors Stage 1 — the loop always reads from a file, never from memory.
Step 2 (Stage 1+2): Read goal and generate hypothesis
def read_target(path: str) -> float:
with open(path) as f:
for line in f:
line = line.strip()
if line and not line.startswith("#"):
try:
return float(line)
except ValueError:
continue
return TARGET_SCORE
target = read_target("research.md")Key line: read_target() runs at the start of every iteration — not once at startup. In a real loop the agent re-reads the entire git history here, learning from every prior experiment.
Step 3 (Stage 3): Evaluate the change
def fake_evaluate(iteration: int) -> float:
"""Simulate noisy improvement over iterations."""
ideal = 0.50 + 0.05 * math.log1p(iteration)
noise = random.gauss(0, 0.02)
return min(max(ideal + noise, 0.0), 1.0)Key line: math.log1p(iteration) — diminishing returns over time. Early iterations improve fast; later iterations improve slowly. This mirrors real research loops.
Step 4 (Stage 4): Keep or revert
for i in range(1, MAX_ITERATIONS + 1):
score = fake_evaluate(i)
delta = score - prev_score
if score >= prev_score:
status = "keep"
prev_score = score
if score > best_score:
best_score = score
else:
status = "revert"
# prev_score unchanged — revert means previous state is restoredKey line: status = "revert" but prev_score is not updated — a reverted change leaves the codebase exactly as it was. The score goes back to the previous best.
Step 5 (Stage 5): Log every iteration
writer.writerow([i, f"abc{i:04d}", round(score, 4),
round(delta, 4), status, f"auto-change-{i:03d}"])
tsv_file.flush()
if best_score >= target:
print(f"[done] target {target} reached at iteration {i}")
break
else:
print(f"[done] budget exhausted. best={best_score:.4f}")Key line: tsv_file.flush() after every row — if the loop crashes or is interrupted, the TSV already has all completed iterations. No data is lost.
Try Changing It
- After running, open
autoresearch-results.tsv— what columns does it have? Find the first "revert" row. - Change
MAX_ITERATIONS = 10toMAX_ITERATIONS = 3— does the loop reachTARGET_SCORE = 0.90? What does it print at the end? - Change
TARGET_SCORE = 0.90toTARGET_SCORE = 0.55— how many iterations does it take to reach the target? - In Stage 4, why is
prev_scoreNOT updated whenstatus = "revert"? What would happen if it were updated?