Agents and tools
The ReAct loop
Reason, act, observe, repeat, with hard stop conditions so the loop cannot run forever.
ReAct (Yao et al., 2022) interleaves reasoning traces with actions and observations. Before ReAct, a lot of work treated chain-of-thought (reason only) and action generators (act only) as separate tricks. Interleaving them lets reasoning update the plan when an observation surprises you, and lets actions ground reasoning in something other than the model's memory.
Concept
Before you start: an agent is a model-directed loop. An observation is whatever the environment returns after an action: tool JSON, shell stdout, a browser DOM, test failures.
The big idea
In practice today the "thought" may be a private chain-of-thought or just the model's decision to call a tool. The structure is the same:
Thought: I need the order status before I can answer.
Action: get_order(order_id="ORD-12345")
Observation: {"status": "shipped", "eta": "2026-10-16"}
Thought: I have enough to reply.
Final: Your order shipped; ETA Oct 16.Production loop with budgets:
def decide(observation):
if observation is None:
return "tool", "get_order", "ORD-12345"
return "final", "Your order shipped; ETA Oct 16.", None
observation = None
for step in range(8):
kind, payload, arg = decide(observation)
if kind == "final":
print(payload)
break
print(f"Action: {payload}({arg})")
observation = {"status": "shipped", "eta": "2026-10-16"}
print("Observation:", observation)Output:
Action: get_order(ORD-12345)
Observation: {'status': 'shipped', 'eta': '2026-10-16'}
Your order shipped; ETA Oct 16.Each tool result is appended as an ordinary message so the next thought sees ground truth. A real loop also checks tokens, dollars and wall time on every step.
Termination conditions you should always define:
- The model emits a final answer (no tool calls)
- A success predicate in code (
tests_passed,ticket_filed) - Max steps, max tokens, max dollars, max wall time
- User cancel or approval timeout
- Repeated identical tool calls (loop detector)
Grounding the next decision in a fresh observation is what separates agents from pure chain-of-thought hallucination.
Walking through a cost cut
A research agent in the source averaged 12 tool calls and $0.40 per query. A loop detector (identical search query twice) plus a 6-step cap cut cost to $0.11 with almost no quality drop on an internal eval. Most excess calls were thrashing, not exploring.
Common mistakes
- No stop condition except "the model says it is done." Loops and bills follow.
- "Try again" with no new observation. Self-talk is not recovery.
- Trusting the thought trace as a log of what happened. The observation is the log.
Check yourself
- The model charges a card, crashes before it writes a final answer, and the loop retries. What must the tool do? Use an idempotency key so a second
chargeis a no-op. The loop will retry. - Name three termination conditions besides "the model stopped." Max steps, max dollars, a code-level success check, a loop detector or a user cancel.
Key takeaways
- ReAct is reason → act → observe, then repeat.
- Always cap steps, tokens, dollars and wall time.
- Detect identical tool calls and break.
- The next decision must see the real observation, not a summary of what the model hoped happened.
Further learning
ReAct: Synergizing Reasoning and Acting in Language ModelsWhile large language models (LLMs) have demonstrated impressive capabilities across tasks in language understanding and interactive decision making, their abilities for reasoning (e.g. chain-of-thought prompting) and …arXiv.org
Next, choose plan-then-execute or interleaved planning.
Related
Agents and agent architectures
Workflows vs agents, the core patterns, ReAct loops, planning and knowing when to stop.
Tool use and function calling
Letting models call your code: tool schemas, the tool loop, and designing tools models use well.
Agent planning
Write a plan first when you need approval or a large decomposition. Interleave the next action when the environment keeps surprising you.