ReAct loop — Thought, Action, Observation until a stop condition fires
the five ingredients
1. message buffer
user, assistant, tool, assistant, tool, ...
Anthropic + OpenAI schemas both encode this
2. tool registry
name - schema - callable; validated on dispatch
registry is the sandbox boundary
3. stop condition
explicit finish, no tool calls, budget exhausted
pick one; mixing them hides early-termination bugs
4. turn budget
hard cap on iterations; 40-400 is normal
scale to task class, not a single global
5. observation formatter
every 400 error becomes a string, not a crash
parallel tool calls need a tool_use_id
one cycle, annotated
Thought "I need tax on 120 then add it"
native reasoning channel in 2026 (Responses API), previously inline tokens
Action calculator(expr="120 * 0.15")
structured output, dispatched through the tool registry
Observation 18.0
untrusted; retrieved content may contain injected instructions
Thought "add 120 + 18.0 and finish"
loop repeats until an assistant turn has no tool calls
Action calculator(expr="120 + 18.0")
parallel dispatch possible; tool_use_id correlates outcomes
Observation 138.0
observations feed back; loop budget decrements
Finish "the total including 15% tax is 138.0"
stop condition; trace is emitted as a span per OTel GenAI
ReAct (Yao et al., 2023) is the 2026 substrate. Frameworks wrap it; the loop does not change.