ReAct comes from one paper: “ReAct: Synergizing Reasoning and Acting in Language Models” by Yao, Zhao, Yu, Du, Shafran, Narasimhan, and Cao (October 2022, ICLR 2023). The idea in one sentence: have the model generate reasoning traces and task actions in an interleaved manner, so reasoning can guide which action comes next and each observation can update the reasoning. The paper evaluated that on four benchmarks — HotpotQA and FEVER for knowledge work, ALFWorld and WebShop for interactive decision-making.
That pattern won. The format it shipped in did not.
The 2022 implementation was a few-shot prompt containing a human-written Thought / Action / Observation trajectory, with your code parsing Action: search[term] out of the model’s text. In 2026 the same loop runs through native tool calling: the model emits a structured tool call, your runtime executes it, and the result goes back as a typed message. The reasoning moved inside the model. If you are reading older ReAct material, that distinction is the thing most likely to mislead you.
TL;DR
ReAct is a loop in which each action is chosen in light of the reasoning so far, and each observation feeds the next reasoning step. It is worth running when the next step depends on what the last step revealed, and wasteful when the path is already known.
The paper’s headline numbers are about decision-making, not question answering: an absolute 34% success-rate gain on ALFWorld and 10% on WebShop over imitation and reinforcement learning baselines, from one or two in-context examples. On HotpotQA, plain ReAct slightly trailed chain-of-thought.
Today you implement it with native tool calling, not a regex. You no longer own the parsing or the reasoning format. You still own the step budget, the tool surface, and how observations are worded.
What the Paper Actually Measured
It is worth being precise here, because ReAct is routinely cited as having beaten everything on all four benchmarks. It did not, and the real result is more interesting.
On the knowledge tasks, with PaLM-540B and a Wikipedia API the model could call:
| Prompting method | HotpotQA (EM) | FEVER (Acc) |
|---|---|---|
| Standard | 28.7 | 57.1 |
| Chain-of-thought | 29.4 | 56.3 |
| CoT with self-consistency | 33.4 | 60.4 |
| Act (actions, no reasoning) | 25.7 | 58.9 |
| ReAct | 27.4 | 60.9 |
| ReAct → CoT-SC | 35.1 | 62.0 |
| CoT-SC → ReAct | 34.2 | 64.6 |
| Supervised state of the art | 67.5 | 89.5 |
ReAct beat action-only prompting on both tasks, and beat chain-of-thought on FEVER (60.9 vs 56.3), but it came in slightly behind chain-of-thought on HotpotQA (27.4 vs 29.4 EM). The best results on both came from combining the two, switching between internal and retrieved knowledge. The paper’s qualitative finding is the one worth remembering: in a hand-labelled sample, hallucinated reasoning or facts accounted for 56% of chain-of-thought failures and 0% of ReAct failures, while ReAct’s own dominant failure was reasoning error at 47%, often failing to recover from repetitive steps. Grounding fixed hallucination and introduced loops.
On the interactive benchmarks, the gains are large and are where the famous numbers come from:
| Benchmark | ReAct | Best baseline | Trained on |
|---|---|---|---|
| ALFWorld (success rate, best of 6 prompts) | 71% | BUTLER 37% | 10⁵ expert trajectories per task type |
| WebShop (success rate) | 40.0% | IL 29.1%, IL+RL 28.7% | 1,012 human trajectories; +10,587 instructions |
Those are the absolute 34% and 10% improvements the abstract claims, and the comparison is the point: a prompt with one or two examples beat imitation and reinforcement learning agents trained on 10³–10⁵ task instances. ReAct’s average across six ALFWorld prompt sets was 57%, and even its worst set (48%) beat the best Act (45%) and BUTLER (37%) trials. For scale, human experts score 59.6% success on WebShop, so the loop closed much of a gap rather than all of it.
Two numbers deserve an asterisk when you quote them. ALFWorld’s 71% is the best of six prompt permutations, not a single-run result, and WebShop’s 10 points are measured against the previous best success rate (40.0 − 29.1 = 10.9).
The Loop, Stated Carefully
A broad control loop like The Sense-Think-Act Loop tells you that agents observe, reason, and act. ReAct is narrower and more useful: it specifies that the next action is chosen in light of the accumulated reasoning, and that each observation is fed back as text the model reads before choosing again.
In the Berkeley RDI lecture on agent history, Shunyu Yao puts the contribution plainly: acting-only models lack reasoning, and “for ReAct, the idea is to just generate both… reasoning can help acting, and acting can help reasoning” (LLM Agents: History & Overview, 15:23).
The most useful way to read a single turn is as a small test with three parts.
Hypothesis. The agent forms a local theory about what would move the task forward: the billing job probably failed on a dependency timeout; the answer is probably in the account history; one more search is probably needed before recommending anything. This is the Thought. It does not need to be a master plan. It needs to be specific enough to test.
Probe. The agent takes one action chosen to test that theory — query logs, call search, read a record, ask a follow-up, run a validation. This is the Action. The discipline is that the action is picked because it should reduce uncertainty, not because it is next in a script.
Evidence. The environment returns an Observation, and the agent decides whether the theory held, weakened, exposed a different problem, or finished the task. That observation is the input to the next turn.
So ReAct is not “think, then act”. It is: form a local hypothesis, run a probe, absorb the evidence, choose the next move from there. Many systems loop; what makes a loop ReAct-shaped is that the next step depends explicitly on evidence returned by the previous one.
2022 and 2026, Side by Side
The four moves are identical in both eras. What changed is where the reasoning lives and who guarantees the format.
The 2022 Loop in Code
This is the classic shape, small enough to read in one sitting. The tool is a fake two-page encyclopedia so you can run the loop without a search dependency, and the model is a 2026 model with native reasoning turned off — which is what it now takes to reproduce the original behaviour.
# classic_react.py — the 2022 text-parsed loop. pip install openai==3.29.0
import re
from openai import OpenAI
client = OpenAI()
PAGES = {
"colorado orogeny": "An episode of mountain building in Colorado and surrounding areas.",
"eastern sector": "The eastern sector extends into the High Plains and is called the Central Plains orogeny.",
}
ACTION = re.compile(r"Action:\s*(search|finish)\[(.+?)\]")
FEWSHOT = """Answer the question by emitting one Thought line and one Action line, then stopping.
Action is search[term] or finish[answer].
Question: Who wrote the screenplay for the 1982 film Blade Runner?
Thought: I should look up the film, then read off the screenwriters.
Action: search[Blade Runner]
Observation: Blade Runner is a 1982 film with a screenplay by Hampton Fancher and David Peoples.
Thought: The observation names both writers, so I can answer.
Action: finish[Hampton Fancher and David Peoples]
"""
def search(term): # stands in for the Wikipedia API in the paper
return PAGES.get(term.lower().strip(), f"No page found for '{term}'.")
transcript = f"{FEWSHOT}\nQuestion: What is the eastern sector of the Colorado orogeny called?\n"
for step in range(6): # step budget, because the loop cannot stop itself
reply = client.chat.completions.create(
model="gpt-5.6-terra",
reasoning_effort="none", # native reasoning off: in 2022 the thinking was the text
stop=["Observation:"],
messages=[{"role": "user", "content": transcript}],
).choices[0].message.content
match = ACTION.search(reply)
if match is None: # the format broke; most 2022 agent code lived here
transcript += "\nObservation: No Action line found. Emit exactly one Action line.\n"
continue
verb, argument = match.groups()
if verb == "finish":
print(argument)
break
transcript += f"{reply.strip()}\nObservation: {search(argument)}\n"
else:
print("Step budget exhausted without an answer.")
Five things in that listing are the whole history of the technique.
The prompt carries a hand-written trajectory, because that is what the method was — Yao describes the original as a few-shot prompt containing a human-written thought, action and observation sequence (LLM Agents: History & Overview, 15:55). The stop sequence exists because the model will happily hallucinate its own observations if you let it keep writing. The regex is load-bearing, and the match is None branch is where a surprising amount of 2021–2023 agent code actually lived. The transcript is one growing string, so every turn pays for every earlier turn. And the for loop with a fixed budget is the only thing preventing an unbounded run.
Note what the state of the art has done to the first argument: to get this loop to behave like 2022, you turn reasoning off.
ReAct in 2026
The pattern is now the default way agents are built, and almost nobody calls it ReAct. LangChain’s current agents documentation defines an agent as “a model calling tools in a loop until a given task is complete” and the constructor is create_agent — the word ReAct does not appear on the page. Anthropic’s tool use documentation describes the same round trip in terms of tool_use blocks and tool_result blocks. OpenAI’s function calling guide describes it as function_call items and function_call_output items. Same loop, three vocabularies, none of them the paper’s.
Yao, asked directly whether tool calling in a loop is ReAct, says the idea is “more implicitly used than explicitly” now, and separates the contribution into two halves: acting through tools, and the inner monologue or thinking (Language Agents: From Reasoning to Acting, 10:57). Harrison Chase, in the same conversation, puts the state of play in one line: “it’s the same ideas… but it’s obviously a very different implementation at this point in time” (12:29).
The two halves came apart, and each went somewhere different.
The acting half became an API contract. Your tool is a JSON schema; the model emits arguments against it; the provider validates the shape. There is no Action: line to parse and no format to re-teach.
The reasoning half went inside the model. Reasoning models produce their deliberation as a native thinking block rather than as prose in your transcript. The practical consequence shows up in the SDK rules: OpenAI’s guide notes that for reasoning models, any reasoning items returned alongside tool calls must be passed back with the tool call outputs. You are now custodian of reasoning you often cannot read.
Yao’s framing of why ReAct worked at all survives the change intact: “ReAct doesn’t change the outside… but it does change the inside through the context”, and thinking can be treated as “a[n] extra tool” (4:08). Reasoning was never a separate subsystem. It was a move the model could make in the same action space as everything else — which is exactly how a thinking block behaves today.
The Same Task, Natively
# native_react.py — the same task, 2026 shape. pip install openai==3.29.0
import json
from openai import OpenAI
client = OpenAI()
PAGES = {
"colorado orogeny": "An episode of mountain building in Colorado and surrounding areas.",
"eastern sector": "The eastern sector extends into the High Plains and is called the Central Plains orogeny.",
}
TOOLS = [
{
"type": "function",
"name": "search",
"description": "Look up one encyclopedia page by title. Returns a short summary, "
"or a not-found message naming no page. Call once per title.",
"parameters": {
"type": "object",
"properties": {
"term": {"type": "string", "description": "Page title, e.g. 'Colorado orogeny'."}
},
"required": ["term"],
"additionalProperties": False,
},
"strict": True,
}
]
def search(term):
return PAGES.get(term.lower().strip(), f"No page found for '{term}'.")
conversation = [
{"role": "user", "content": "What is the eastern sector of the Colorado orogeny called?"}
]
for step in range(6): # still a step budget; nothing else about the loop is yours
response = client.responses.create(model="gpt-6-astra", tools=TOOLS, input=conversation)
conversation += response.output # reasoning items ride along and must be passed back
calls = [item for item in response.output if item.type == "function_call"]
if not calls:
print(response.output_text)
break
for call in calls: # one turn can return several calls
term = json.loads(call.arguments)["term"]
conversation.append(
{
"type": "function_call_output",
"call_id": call.call_id,
"output": search(term),
}
)
else:
print("Step budget exhausted without an answer.")
Read the two listings against each other and the ledger is clear.
Gone: the few-shot trajectory, the stop sequence, the regex, the unparseable-reply branch, the single growing string, and the fiction that the model’s visible prose is its reasoning. Tool arguments arrive typed. Several calls can come back from one turn, which the text format could not express at all.
Still yours: the for range(6). The provider gave you structure, not judgement. Nothing in either SDK decides when the loop has gone far enough, so the step budget, the cost ceiling, and the stop condition remain your code — and the native version makes it easier to run twelve cheap steps without noticing.
Newly yours: observation wording, which is now a tool-design problem rather than a prompt-formatting one. "No page found for 'eastern sector'." is an observation the model can act on; a bare null or a stack trace is not. See Designing Tools for Agents for the full treatment, since the tool result is the observation in this architecture.
Harder: seeing what happened. In 2022 the trajectory was plain text you could read, diff, and paste into a bug report; the paper leaned on exactly that for its interpretability claim and for the hand-labelled failure analysis. When reasoning is a hidden or encrypted block, that analysis has to come from traces and tool-call sequences instead, which is why Evaluating Agent Trajectories, Not Just Outputs matters more now than it did when the thinking was sitting in your prompt.
A Worked Example
Suppose an operations agent is asked to find out why the nightly billing job failed and take the safest next step. The goal already assumes the boundaries described in Goals, Constraints, and Success Conditions: act toward recovery, stay inside permissions, stop when the evidence is good enough.
| Turn | Hypothesis | Probe | Evidence |
|---|---|---|---|
| 1 | The job failed on a payment-provider timeout | Read job logs and dependency health | Repeated timeouts from the provider API |
| 2 | Transient upstream outage, not our code | Check provider status and recent deploys | Provider degraded; no billing-related deploy |
| 3 | One retry is safe and inside policy | Retry the job once | Retry succeeds; backlog clears |
| 4 | The run can close if recovery is confirmed | Verify downstream records; write the summary | Records healthy; summary logged |
Nothing here was knowable in advance. Turn 3 is only reachable because turns 1 and 2 ruled out a code change — which is the shape of exploratory work, and the reason the loop earns its cost. In Yao’s words from the same lecture, the generality came from noticing that “many tasks can be turned into a text game” (20:43).
In a native implementation the turns look the same, but each one is a tool call with typed arguments, and the hypothesis is in a thinking block you may never see.
What ReAct Is Not
Three comparisons do most of the work.
Not chain-of-thought. Chain-of-thought prompting keeps the reasoning inside the model’s own text with no external check. ReAct pushes it into the world and lets the world push back. The paper quantified the difference: no hallucinated facts in its sampled ReAct failures, versus 56% for chain-of-thought.
Not one-shot tool calling. A single function call is a capability. ReAct is a control pattern around repeated calls.
Not every agent that loops. A retry loop and a fixed pipeline both loop. The distinguishing property is that the next action is selected from the last observation.
| Dimension | One-shot tool calling | ReAct-shaped loop |
|---|---|---|
| Pattern | Request a tool, execute, return | Repeated reason-act-observe cycle |
| Horizon | One step or a fixed sequence | Multi-step and adaptive |
| Role of observations | The result you return to the user | Input to the next decision |
| Best for | Clear, well-scoped actions | Paths that are unclear upfront |
| Main cost | Tool interface complexity | Serial model calls, latency, context growth |
Tool Use: How Agents Take Action explains how the agent can act. ReAct explains how it decides what to do next after acting.
Where It Breaks
The failure modes did not change when the format did. Three of them got harder to see.
Useless loops. The agent re-searches, re-reads, and re-checks without progress. The paper’s own hand-labelled analysis found reasoning errors — frequently a failure to recover from repetitive steps — in 47% of ReAct’s failures. This is the oldest failure in the pattern and it is still the most common. Step budgets, cost ceilings, and progress checks that can tell repetition from movement are not optional.
Context growth. Every turn adds a tool call and a result to the conversation. Native formats are more compact than a re-sent transcript, but the growth is the same shape, and long runs still decay. Short-Term Context, Retrieval, and Long-Term Memory is the follow-on topic for a reason.
Cascading assumptions. A wrong early hypothesis gets inherited. The loop then looks busy while digging deeper into the wrong branch. Harder to spot now: the hypothesis may be in a hidden thinking block, so the only evidence is a sequence of tool calls that each look individually reasonable.
Premature stopping. The agent stops on a plausible answer rather than a verified one. Nothing in a tool-calling API distinguishes the two.
Latency and cost. Serial model calls, one per turn. For predictable work a fixed workflow is faster, cheaper, and easier to reason about. ReAct is powerful for uncertain paths and wasteful for obvious ones; if you can draw the flowchart, write the flowchart.
Where to Go From Here
The honest 2026 summary is that ReAct is table stakes, not an architecture. You get the loop for free from any tool-calling SDK, and the engineering has moved to the parts the loop never solved: budgets and stop conditions, tool and observation design, context management across long runs, trajectory-level evaluation, and reflection on failed attempts — which is what Reflexion added on top of ReAct-style loops in the first place.
What is worth carrying forward is the discipline the paper’s format made unavoidable. When the thought was a line of text you could read, it was obvious whether the next action followed from the last observation. That property is what made the loop work, and it is the thing a hidden thinking block makes easy to stop checking.
FAQ
Is ReAct still relevant in 2026?
The idea is, to the point of invisibility: nearly every tool-calling agent runs a ReAct-shaped loop. The 2022 implementation is not. Writing a Thought/Action/Observation parser against a current model means fighting the native tool-calling and reasoning behaviour you are paying for.
Should I ever still text-parse a ReAct loop?
Two cases. Teaching, where seeing the trajectory as plain text is the point. And models without tool-calling support, mostly small local ones — and even there, constrained decoding to a JSON grammar is usually a better bet than a regex.
Is tool calling in a loop the same thing as ReAct?
Structurally, yes, and that is roughly how the paper’s author describes the situation: the idea is now “more implicitly used than explicitly”. The contribution had two halves — acting via tools, and an inner monologue — and in a modern stack the first is an API and the second is a model feature.
Where did the Thought part go?
Into the model. Reasoning models emit deliberation as a native thinking block, often summarised or encrypted rather than shown. You still have to carry those items back into the next request alongside your tool results, you just cannot always read them.
Is ReAct the same thing as the sense-think-act loop?
No. Sense-think-act is the general control model. ReAct is the specific claim that interleaving reasoning with action beats either alone, which the 2022 paper tested on four benchmarks.
Is ReAct the same thing as chain-of-thought?
No. Chain-of-thought reasons in text with no external feedback. ReAct interleaves reasoning with real actions and observations, which is why it hallucinated far less in the paper’s failure analysis.
Do all agents need ReAct?
No. Predictable work is better served by a fixed workflow or a single tool call. Reach for the loop when the next step depends on what the last step revealed.
How do you stop a ReAct agent from looping forever?
Explicit success conditions, a step budget, time and cost ceilings, escalation rules, and a progress check that can distinguish a new state from a repeated one. Both SDKs will loop as long as you let them; neither one decides when enough is enough.
Why does the loop get expensive?
One model call per turn, serially, with the conversation growing each time. Reasoning tokens add to that, and the compactness of native formats makes it easier not to notice.
What should I read next?
Designing Tools for Agents, because the tool result is the observation. Then Evaluating Agent Trajectories, Not Just Outputs, because the reasoning you used to read in the transcript now has to be inferred from traces.
Further watching
All three are by Shunyu Yao, ReAct’s first author. Timestamps were transcript-checked for this guide and link to the moment the claim appears.
- LLM Agents: History & Overview — Shunyu Yao (Berkeley RDI). The clearest short account of why reasoning and acting were combined, from the person who combined them. Start at 14:52 for the acting-only limitation and the core idea; the worked market-cap example runs 18:03–18:37; the generality argument — “many tasks can be turned into a text game” — is at 20:43.
- Language Agents: From Reasoning to Acting — Shunyu Yao with Harrison Chase (Latent Space, 86 min). The single best source on what survived and what changed. Chase on why the recipe landed when it did: 3:37. Yao on context being the thing ReAct changes, and thinking as an extra tool: 4:08–4:39. Whether a tool-calling loop counts as ReAct: 10:57. Chase’s “same ideas, very different implementation”: 12:29.
- Language Agents — Shunyu Yao, PhD defence (Princeton, 85 min). The research arc around the paper, including why digital environments are a different kind of problem from physical ones (3:38), why they have “tremendous practical values” and usable reward signals (6:48), and WebShop as a long-horizon benchmark (14:07).
Primary Sources
- ReAct: Synergizing Reasoning and Acting in Language Models — Yao et al., October 2022 (ICLR 2023). Every number in this guide was re-read from Tables 1, 3 and 4 and the §3–4 result discussions. The project page hosts prompts and trajectories.
- ReAct: Synergizing Reasoning and Acting in Language Models — Google Research’s summary of the work.
- Chain-of-Thought Prompting Elicits Reasoning in Large Language Models — Wei et al. The reasoning-only predecessor, and the baseline ReAct is measured against.
- Reflexion: Language Agents with Verbal Reinforcement Learning — Shinn et al. Adds self-reflection on top of ReAct-style loops.
- OpenAI function calling guide — the
function_callandfunction_call_outputround trip used in the second listing, including the rule about passing reasoning items back with tool results. - Anthropic tool use overview — the same loop as
tool_useandtool_resultblocks, withstop_reason: "tool_use"as the signal to execute. - LangChain agents documentation —
create_agent, and an agent defined as “a model calling tools in a loop until a given task is complete”.
Both listings target the openai 3.29.0 Python SDK; pin that version to reproduce them.