A ReAct agent is a common way to turn a language model into something that can look things up, call APIs and act on the results. This guide explains the loop, walks through an example, covers what the original research showed and where ReAct breaks in production.
What Is a ReAct Agent?
A ReAct agent is an AI agent that alternates between reasoning about a task and taking actions with external tools, then uses each tool result to decide its next step until it can answer. "ReAct" stands for Reasoning + Acting. It has nothing to do with React, the JavaScript library.
The pattern comes from the ReAct paper by Shunyu Yao and colleagues at Princeton and Google, first posted in October 2022 and published at ICLR 2023. The authors reported that "on two interactive decision making benchmarks (ALFWorld and WebShop), ReAct outperforms imitation and reinforcement learning methods by an absolute success rate of 34% and 10% respectively, while being prompted with only one or two in-context examples."
Those gains were measured with PaLM-540B and few-shot prompting in 2022. They show the pattern works, not how a specific modern model will perform.
How the ReAct Loop Works: Thought, Action, Observation
A ReAct agent runs a repeating loop of three steps. The loop ends when the model produces a final answer or hits a stop condition such as a step limit.
Thought
The Thought step is a short reasoning trace the model writes before it acts. It states what the model already knows, what is still missing and which tool should fill the gap.
With some reasoning models, this step may happen internally instead of as visible text. The loop still includes a reasoning step either way.
Action
The Action step is a tool call: the model picks one tool and the arguments to pass to it. In the original paper, the action space for question answering was a simple Wikipedia API with three actions: search, lookup and finish.
Production agents usually use richer tools. A research agent might call the Olostep web search API to find sources, then call a scraper to read a specific page.
Observation
The Observation step is the tool's result, added back into the model's context. The model never runs the tool itself. The surrounding runtime executes the call, captures the output and appends it to the conversation history.
The next Thought then reasons over that new evidence. This is the step that grounds the agent in real data instead of model memory.
A ReAct Agent Example, Step by Step
A ReAct trace shows each Thought, Action and Observation in order. Here is a simplified trace for a question that needs live data, written in the classic text format from early ReAct prompts:
Question: What is the latest stable version of Python, and when was it released?
Thought: I need current information. My training data may be out of date. I should search.
Action: web_search["latest stable Python release"]
Observation: [1] python.org/downloads – "Download the latest version for..." [2] a news article about a beta release ...
Thought: The snippets do not state the version and date clearly. I should read the official downloads page.
Action: scrape["https://www.python.org/downloads/"]
Observation: (clean Markdown of the page, including the current release number and its release date)
Thought: The official page gives the version and date. I can answer.
Final Answer: The latest stable version is <version from page>, released on <date from page>.The first Observation was not enough, so the model reasoned about the gap and took a second action. A tool like the Olostep Scrapes endpoint returns a page as Markdown, HTML or JSON, which gives the second Observation the full content that search snippets lacked.
Why ReAct Works Better Than Reasoning or Acting Alone
ReAct combines two approaches that each fail on their own. Reasoning without actions has no access to new facts. Actions without reasoning have no plan to track progress or recover from a bad result.
Google Research's ReAct post explains the first problem: "with chain-of-thought prompting, a model is not grounded in the external world and uses its own internal representations to generate reasoning traces." Chain-of-thought (CoT) prompting is when a model reasons step by step before answering, using only what it already knows.
The paper's results were strong but mixed:
| Benchmark | Task type | What the paper reported |
|---|---|---|
| ALFWorld | Text-based household tasks | Best ReAct prompt reached 71% success vs 37% for the BUTLER imitation-learning baseline |
| WebShop | Simulated online shopping | ReAct reached 40.0% success vs 29.1% for imitation learning; human experts reached 59.6% |
| FEVER | Fact verification | ReAct beat CoT (60.9 vs 56.3 accuracy) |
| HotpotQA | Multi-hop question answering | ReAct slightly trailed CoT (27.4 vs 29.4 exact match) |
The authors manually reviewed 200 HotpotQA trajectories (50 correct and 50 incorrect for each method). Hallucination caused 56% of CoT's sampled failures and none of ReAct's.
ReAct still failed in other ways, and the best overall scores came from combining ReAct with CoT self-consistency. ReAct grounds reasoning in evidence, but it does not make an agent correct by default.
The Core Components of a ReAct Agent
A ReAct agent is made of five parts that work together. The model reasons, but the code around it does most of the operational work.
- Language model: Generates each Thought and chooses the next Action.
- Tools: Callable functions such as web search, page scraping, databases or internal APIs, each with a name, a description and an input schema.
- Instructions: The system prompt that defines the task, the available tools and the expected output format.
- Memory: The running history of Thoughts, Actions and Observations, which the model rereads at every step.
- Loop controller: The code that parses each Action, runs the tool, appends the Observation and enforces stop conditions.
That loop controller is often called an agent harness. It decides how many steps are allowed, how tool errors are handled and when the run ends.
Observation Quality Decides Whether the Loop Converges
ReAct tells a model how to use tools, but the quality of what those tools return decides whether the loop reaches a correct answer. A model can only reason over the evidence in its Observations.
The original paper shows this directly: "Non-informative search, which counts for 23% of the error cases, derails the model reasoning and gives it a hard time to recover and reformulate thoughts." When a search returns nothing useful, the agent burns steps reformulating queries or drifts off task.
Observation size also matters. In a chat-style loop like the code example later in this article, the full message history is sent to the model on every step.
A large Observation is therefore processed again on each later step. Olostep's guide to LLM-ready web data formats gives an example where a page's HTML might consume 50,000 tokens while the same content in Markdown uses about 5,000.
Better Observations share a few traits:
- Full content, not snippets: Search snippets help an agent find a page, but answers usually require reading the page itself.
- Clean text: Markdown or plain text removes scripts, navigation and markup that waste context.
- Structured fields when needed: JSON with a defined schema lets the model compare values without parsing prose.
- Source URLs: Links let the agent, or a human reviewer, verify where a fact came from.
- Live data: Current pages answer questions that model memory cannot, such as prices, releases or news.
For a practical walkthrough of search, scraping and crawling as agent tools, see how to give AI agents web access.
ReAct vs Function Calling and Other Agent Patterns
ReAct is a design pattern, not a library or a model feature. It sits among several AI agent architecture patterns, and the right choice depends on how predictable the task is. The table below is our summary of the general trade-offs, not a benchmark result.
| Pattern | How reasoning happens | How actions are expressed | Best fit | Main risk |
|---|---|---|---|---|
| Chain-of-thought | Step-by-step text before one answer | No actions | Reasoning over known facts | Ungrounded or outdated facts |
| Act-only | No explicit reasoning | Tool calls in sequence | Short, predictable tool tasks | No plan to recover from bad results |
| ReAct (text prompt) | Written Thought before each Action | Parsed from text, e.g. Action: search[...] | Learning and prototyping | Parsing errors and fabricated Observations |
| Native tool-calling loop | Visible or hidden model reasoning | Structured tool calls returned by the model API | Most production agents | Cost and errors compound over many steps |
| Plan-and-Execute | A full plan is written up front | Steps executed from the plan | Long tasks with clear subtasks | Plan goes stale when results surprise it |
| Reflexion | Model critiques its own past attempts | Retries informed by the critique | Tasks with clear success checks | Extra runs add cost and latency |
Is ReAct Obsolete?
The text format is mostly obsolete, but the loop is not. Modern frameworks increasingly rely on structured tool calls returned by the model API instead of parsing Thought: and Action: lines out of raw text.
The underlying loop is still how tool-using agents run. Anthropic's agent guide describes agents this way: "They are typically just LLMs using tools based on environmental feedback in a loop." That is the ReAct cycle with a structured Action format.
Frameworks reflect the same shift. According to the LangGraph v1 release notes, "The LangGraph create_react_agent prebuilt has been deprecated in favor of LangChain's create_agent." The LangChain v1 docs describe create_agent as "built on the basic agent loop -- calling a model, letting it choose tools to execute, and then finishing when it calls no more tools".
How to Build a ReAct Agent
You can build a ReAct agent with a model that supports tool calling and a short loop. The steps below assume Python and a web search tool.
- Define tools: Give each tool a clear name, a one-line description and a strict input schema.
- Choose a model: Use a model with native tool calling so Actions arrive as structured data.
- Write the loop: Send the history, run any requested tool, append the result and repeat.
- Set stop conditions: Cap the number of steps and set a token or time budget.
- Log every trace: Store each Thought, Action and Observation so failures can be debugged.
- Test on real tasks: Check answers against known results before shipping.
Here is a minimal loop using the OpenAI Python SDK and Olostep's search endpoint as the tool:
import json, os, requests
from openai import OpenAI
client = OpenAI()
OLOSTEP_KEY = os.environ["OLOSTEP_API_KEY"]
def web_search(query: str) -> str:
r = requests.post(
"https://api.olostep.com/v1/searches",
headers={"Authorization": f"Bearer {OLOSTEP_KEY}"},
json={"query": query, "limit": 5},
timeout=60,
)
links = r.json()["result"]["links"]
return json.dumps([{"url": l["url"], "title": l["title"],
"description": l["description"]} for l in links])
tools = [{
"type": "function",
"function": {
"name": "web_search",
"description": "Search the live web. Returns URLs, titles and descriptions.",
"parameters": {
"type": "object",
"properties": {"query": {"type": "string"}},
"required": ["query"],
},
},
}]
messages = [{"role": "user", "content": "Who won the most recent Nobel Prize in Physics?"}]
for step in range(6): # stop condition: max 6 steps
resp = client.chat.completions.create(model="gpt-4.1", messages=messages, tools=tools)
msg = resp.choices[0].message
messages.append(msg)
if not msg.tool_calls: # no Action requested: final answer
print(msg.content)
break
for call in msg.tool_calls: # Action -> Observation
args = json.loads(call.function.arguments)
messages.append({"role": "tool", "tool_call_id": call.id,
"content": web_search(**args)})For memory, guardrails and tool design in more depth, see how to build an AI agent.
Common ReAct Agent Failure Modes and Fixes
ReAct agents tend to fail in a small set of predictable ways. Each one has a clear symptom and a practical fix.
| Failure | Symptom | Fix |
|---|---|---|
| Repetitive loops | The same Thought and Action repeat | Cap steps and detect repeated tool calls with identical arguments |
| Non-informative search | Queries return nothing useful and the agent drifts | Return full page content, not just snippets, and let the agent refine queries |
| Fabricated Observations | The model writes its own "Observation" text | Use native tool calling so only the runtime can add tool results |
| Parsing errors | The harness cannot read the Action | Use structured tool calls and validate arguments against a schema |
| Context overflow | Runs fail after many steps | Send clean Markdown or JSON, trim old Observations and summarize history |
| Prompt injection | A web page's hidden text changes the agent's behavior | Treat tool output as untrusted, limit tool permissions and require approval for risky actions |
| Runaway cost | Token use grows with each step | Set token budgets and keep Observations small |
Prompt injection deserves special attention for any agent that reads the web. The OWASP Top 10 for LLMs warns that "Indirect prompt injections occur when an LLM accepts input from external sources, such as websites or files." OWASP also notes that no fool-proof prevention method is known.
Survey data points to quality as a production concern. In LangChain's State of Agent Engineering survey of 1,340 respondents (Nov–Dec 2025), "More than half of respondents surveyed (57.3%) now have agents running in production environments," and about one third named quality as their top blocker; respondents were self-selected, so the results are not a representative sample.
Separately, Gartner's June 2025 forecast predicts project cancellations for business reasons rather than technical failure modes: "Over 40% of agentic AI projects will be canceled by the end of 2027, due to escalating costs, unclear business value or inadequate risk controls, according to Gartner, Inc."
FAQ
What Does ReAct Stand for in AI?
ReAct stands for Reasoning + Acting, a pattern where a language model alternates between reasoning and tool use. It is unrelated to React, the JavaScript UI library.
What Is the Difference Between an LLM Agent and a ReAct Agent?
An LLM agent is any system where a language model directs its own steps and tool use. A ReAct agent is one specific way to build it, using a repeating Thought, Action and Observation loop.
Does ReAct Stop Hallucinations?
ReAct reduces ungrounded answers when its tools return relevant, accurate data, but it does not eliminate hallucination. If an Observation is empty, wrong or misleading, the agent can still reach a wrong answer.
How Do You Stop a ReAct Agent From Looping Forever?
Set a maximum number of steps, add a token or time budget and detect repeated tool calls with the same arguments. When a limit is hit, return the best partial answer or hand off to a human.
Can a ReAct Agent Call Several Tools at Once?
The original ReAct format takes one Action per step. Many native tool-calling APIs let a model request several tool calls in one turn, which the harness can run in parallel.
What Tools Does a ReAct Agent Use?
A ReAct agent can use any callable function, such as web search, page scraping, databases, code execution or internal APIs. MCP (Model Context Protocol) servers expose tools in a standard format so one agent can connect to many of them.
