Day 2:Week 13, Day 2: The `ReAct` (`Reason + Act`) Loop from Scratch — Loop Guards & Duplicate Action Detection
Battle-tested daily lesson note • 100% runnable code, interview Q&A, test suite & interactive quiz
Week 13, Day 2: The ReAct (Reason + Act) Loop from Scratch — Loop Guards & Duplicate Action Detection
1. The ReAct Paradigm (Yao et al., 2022)
Before ReAct, researchers either used pure Chain-of-Thought (Reason Only — no external tools, prone to hallucinating live facts) or pure Action agents (Act Only — no reasoning trace, prone to aimless tool calls).
ReAct interleaves explicit reasoning traces (Thought) with external tool executions (Action Observation) in a closed feedback loop:
User Goal: "Why is checkout failing and how do I fix it?"
│
▼
┌───────────────────────────────────────────────────────────────────────┐
│ Step 1: │
│ Thought: "I need to check recent error logs for payments-api." │
│ Action: get_pod_logs(service="payments-api") │
│ Observation: "ERROR: ERR_PG_LOCK_9021 on orders table (PID 4412)" │
├───────────────────────────────────────────────────────────────────────┤
│ Step 2: │
│ Thought: "Logs show ERR_PG_LOCK_9021. Let me look up the runbook." │
│ Action: search_runbook(query="ERR_PG_LOCK_9021") │
│ Observation: "Run pg_terminate_backend(4412) to clear lock." │
├───────────────────────────────────────────────────────────────────────┤
│ Step 3: │
│ Thought: "I now have both the root cause and exact remediation." │
│ Final Answer: "Checkout is failing due to PostgreSQL lock..." │
└───────────────────────────────────────────────────────────────────────┘
2. Two Mandatory Production Guards for Any ReAct Loop
What happens in production if you write while not done: around an LLM agent?
- Unbounded Step Explosion (
max_stepsGuard): An agent gets confused and calls tools 80 times in a row, costing$4.00and90 secondson a single user prompt. Every productionReActloop enforcesmax_steps(typically5–10steps), forcing a graceful summary if reached. - Stuck-in-a-Rut Duplicate Action Guard: Weak or low-temperature models frequently call the exact same tool with the exact same arguments twice in a row (
Action(t) == Action(t-1)). OurReActengine hashes(tool_name, canonical_json_args)and injects a corrective system observation ("Duplicate tool call blocked: you already called X with these exact arguments!") to break the cycle immediately!
In Simple English: The ReAct Loop (Think -> Act -> Look)
Think of ReAct (Reason + Act) like troubleshooting a broken Wi-Fi router:
- Thought: "The internet is down. First let me check if the router lights are green."
- Action: Walk over and look at the router (Call Tool
check_logs()). - Observation: "The DNS error light is blinking red!"
- Thought: "Great, now I know the exact bug — let me flush DNS and test again."
Why Loop Guards Are Mandatory: Without a max_steps budget and a Duplicate-Call Detector (stopping if the agent calls check_logs(pod="payments") 3 times in a row with no change), an agent gets stuck spinning forever and burns through your entire monthly API budget overnight!