Ask a plain language model a factual question and it will answer — confidently, and sometimes wrongly, because it is guessing from memory with no way to check. Give it the ability to reason about what it needs and act to go get it, in a loop, and something changes: it stops guessing and starts investigating. That loop has a name — ReAct, for Reason + Act — and it is the pattern underneath essentially every modern AI agent.
- Explain the ReAct loop — Thought, Action, Observation — and why it interleaves reasoning with acting
- Step through a real ReAct trace and see how the agent investigates instead of guessing
- Understand, with data, why ReAct beats reasoning-only and acting-only approaches
- Connect ReAct to production agents (function calling, frameworks) and its failure modes
Watch the loop turn
The fastest way to understand ReAct is to watch one run. Below is a real trace. Hit Next move and follow the agent as it thinks, acts, observes, and thinks again — notice that it never answers until it has actually looked:
Who lived longer — Isaac Newton or Albert Einstein?
I need each man's lifespan. I'll look up Einstein first, then Newton, then compare.
Three kinds of move repeat in a cycle:
- Thought — the model reasons in plain language about what it needs and what to do next. This is chain-of-thought, but mid-task.
- Action — it calls a tool: a search, a lookup, a calculation, an API. The action is structured so your code can run it.
- Observation — the tool's result comes back and is fed to the model as new context.
Then it thinks again with that new information, and the loop continues until it emits a final answer (a Finish action).
- ReAct repeats three moves: Thought (reason), Action (call a tool), Observation (read the result)
- The model reasons about what it needs, then acts to get it, then reasons again — until it can answer
- Interleaving reasoning and acting lets each cover the other's weakness
Where the idea comes from — and the evidence
ReAct is not folklore; it is a 2022 research result. In "ReAct: Synergizing Reasoning and Acting in Language Models" (Yao et al., Princeton and Google, published at ICLR 2023), the authors showed that prompting a model to interleave reasoning traces with tool actions beat both reasoning-only and acting-only baselines — often by a lot.
The two problems it solved are worth naming precisely:
REASON only think → think → think → answer → confident, unchecked (hallucinates)
ACT only act → act → act → answer → fetches facts, no plan, gets lost
ReAct think → act → observe → think → … → reasons AND checks against reality
The numbers, from the paper:
- On knowledge tasks — HotpotQA (multi-hop question answering) and Fever (fact verification) — ReAct produced more trustworthy answers than chain-of-thought alone, because every reasoning step could be grounded in a real lookup instead of the model's fallible memory. Pure chain-of-thought had a higher rate of confidently hallucinated facts.
- On decision-making tasks — ALFWorld (a text world where an agent must complete household tasks) and WebShop (navigating a shopping site) — ReAct beat imitation-learning and reinforcement-learning baselines by a wide margin: roughly +34% absolute success on ALFWorld and +10% on WebShop, with nothing but a handful of prompt examples.
- ReAct comes from Yao et al. (2022 / ICLR 2023): interleave reasoning with tool actions
- It reduces hallucination on knowledge tasks by grounding each thought in a real observation
- It beat learning-based baselines on decision tasks (~+34% ALFWorld, ~+10% WebShop) from prompting alone
- A readable, grounded reasoning trace makes the agent inspectable and correctable
The anatomy of a good loop
Switch the simulator above to the paper's example and step through it — the Colorado orogeny question is the exact trace from the ReAct paper. Watch how it decomposes a hard multi-hop question:
- A thought breaks the question into a plan (find the orogeny → find the area → find the elevation).
- Each action fetches one missing piece.
- Each observation either answers a sub-question or reveals the next one.
- A final thought assembles the pieces, and Finish returns the answer.
Two design details make or break this:
- Actions must be machine-runnable. The model emits something structured —
Search["High Plains"], or a JSON tool call — that your code parses and executes. Vague actions can't be run. - The loop needs a stop condition. ReAct ends when the model emits a Finish. In production you also add a hard cap on steps, so a confused agent can't loop forever.
- A good loop decomposes a hard question into single-fact actions and reassembles the answer
- Actions must be structured so your code can run them
- The loop stops on a Finish action — plus a hard step cap in production
- Search/Lookup actions are agentic RAG: retrieval the agent chooses, mid-loop
From paper to production
Almost every agent you use today is a descendant of ReAct. When a model does "function calling" — deciding to call a tool, reading the result, and continuing — that is the ReAct loop, with the Thought/Action/Observation format handled by the API instead of hand-written prompt examples.
Here is the loop in code, stripped to its essence:
from anthropic import Anthropic
client = Anthropic()
def run(question: str, tools, handlers, max_steps: int = 6) -> str:
messages = [{"role": "user", "content": question}]
for _ in range(max_steps): # the hard step cap — no infinite loops
resp = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
tools=tools,
messages=messages,
)
messages.append({"role": "assistant", "content": resp.content})
if resp.stop_reason != "tool_use":
# No action requested → the model is finished. Return its answer.
return next(b.text for b in resp.content if b.type == "text")
# ACTION: run each tool the model called; feed OBSERVATIONS back in.
results = []
for block in resp.content:
if block.type == "tool_use":
observation = handlers[block.name](block.input)
results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": str(observation),
})
messages.append({"role": "user", "content": results})
return "Stopped: hit the step limit before finishing."
That for loop is ReAct. The model's text is the Thought, a tool_use block is the Action, the tool_result you append is the Observation, and a turn with no tool call is the Finish.
- Modern "function calling" agents are ReAct with the format handled by the API
- The loop is a simple
forwith a step cap: model text = Thought, tool call = Action, tool result = Observation - Real failure modes — looping, drift, bad observations — are solved by harness engineering, not clever prompts
When to reach for it
ReAct shines when a task needs information or actions the model doesn't already have and can't get in one shot: multi-step questions, anything that touches live data, tool-driven workflows, decisions that unfold over several moves.
It is overkill when the answer is already in the prompt (just answer), or when a single tool call with a fixed pre-step would do (plain RAG, no loop). As always: use the simplest thing that works, and reach for the loop when the task genuinely requires the model to investigate.
- Use ReAct for multi-step tasks needing live data, tools, or unfolding decisions
- Skip it when the answer is in the prompt, or a single retrieval step suffices
- The loop — think, act, observe, repeat — is the foundation the rest of agent-building sits on
- In the trace "Search["Isaac Newton"]", which of the three ReAct phases is that, and what phase comes right after it?
- Why does interleaving reasoning with actions reduce hallucination compared to reasoning alone?
- Name one ReAct failure mode and the engineering fix for it.
Source: Shunyu Yao, Jeffrey Zhao, Dian Yu, Nan Du, Izhak Shafran, Karthik Narasimhan, Yuan Cao, “ReAct: Synergizing Reasoning and Acting in Language Models,” arXiv:2210.03629 (2022); ICLR 2023.