← Blog

ReAct Agent: The Reason-and-Act Loop Explained

August 13, 2026

First, a disambiguation: a ReAct agent has nothing to do with React the JavaScript library. ReAct stands for Reasoning and Acting, and it's the loop most AI agents run on today.

The pattern is one idea: instead of making the model answer in one shot, you let it alternate between thinking and doing. It reasons about what it needs, calls a tool, reads the result, and reasons again — until it has enough to answer.

The loop has three moves that repeat:

  1. Thought — the model reasons about what to do next in plain language
  2. Action — it calls a tool (search, database query, API call, code execution)
  3. Observation — the tool result comes back and joins the context

Then it thinks again. That's the whole pattern. It came out of ReAct: Synergizing Reasoning and Acting in Language Models by Yao et al., published in 2022 and presented at ICLR 2023, and it's now the default shape for agent frameworks.

Why interleaving beats doing either one alone

Before ReAct, two approaches existed separately, and each had a specific failure.

Chain-of-thought reasoning made models think step by step, which improved logic considerably. But the reasoning happened entirely inside the model's own knowledge. If it needed a fact it didn't have, it produced a confident, well-structured, wrong answer — the reasoning chain made the error more persuasive, not less.

Tool-calling without reasoning let models fetch real information, but with no plan behind the calls. The model retrieves something, then retrieves something else, with no explicit sense of whether it's getting closer.

ReAct's contribution is that the two fix each other. Reasoning decides which action to take (reason to act), and the observation from that action grounds the next round of reasoning (act to reason). A model that can look things up mid-thought hallucinates noticeably less, because it can check instead of guess.

Chain-of-thoughtTool calls onlyReAct
Can look up factsNoYesYes
Plans its next stepYesNoYes
Recovers from a bad stepRarelyNoOften
Main failure modeConfident hallucinationAimless retrievalLooping
Cost per taskLowLowVariable

What a ReAct loop actually looks like

Concretely, for "which of our enterprise customers renewed last quarter but hasn't logged in since?":

Thought: I need the renewal list first, then login activity for those accounts. Action: query_db("SELECT account_id FROM renewals WHERE quarter = 'Q2-2026' AND tier = 'enterprise'") Observation: 47 account IDs returned. Thought: Now I need last login per account. 47 is small enough to query directly. Action: query_db("SELECT account_id, MAX(login_at) FROM sessions WHERE account_id IN (...) GROUP BY account_id") Observation: 47 rows with timestamps. Thought: Twelve have no login since the renewal date. That answers it.

Note what the second thought does — it makes a decision (47 is small enough to query directly) that depends on information from the first observation. That's the part you can't write in advance, and it's the reason the loop exists at all.

Implementing one: create_agent (formerly create_react_agent)

You rarely build this by hand. The long-standing implementation was create_react_agent, a prebuilt factory in LangGraph's langgraph.prebuilt package. LangGraph v1 deprecated it — new code should use create_agent from langchain.agents, which runs on LangGraph and does the same job: it constructs the whole graph — model node, tool node, and the conditional routing between them — from a model and a list of tools, so you don't assemble a StateGraph yourself. If you're migrating, prompt= is now system_prompt=; the old function still runs and is scheduled for removal in v2.

The shape is roughly: pass a model, pass tools, get back a runnable agent that loops until the model stops requesting tool calls. LangChain maintains a reference template repo if you want a working starting point rather than a snippet.

What you still have to decide yourself:

  • Tool descriptions. These are the agent's entire understanding of what it can do. A vague description is the single most common cause of an agent picking the wrong tool.
  • A recursion limit. Without one, a confused agent loops until something else stops it. Set it low while developing.
  • What goes in state. Everything accumulating in context costs tokens on every subsequent turn.

Under the hood this rides on the model's native tool-calling — Anthropic's tool use and OpenAI's function calling both return structured tool requests, so the modern loop parses JSON rather than scraping "Thought:" and "Action:" out of free text the way the original paper's prompting did.

Where ReAct agents go wrong

Looping. The classic failure. The agent calls a tool, doesn't like the result, calls it again with a nearly identical argument, and repeats. Usually it means the tool isn't returning what the description promised. Cap iterations and log every action — the log makes the cause obvious in a way the final output never does.

Context bloat. Every observation stays in context. Twenty tool calls into a task, most of the window is stale intermediate results and the model starts losing the thread. Summarize or drop old observations rather than accumulating everything.

Too many tools. Past roughly a dozen, selection accuracy drops. If you have thirty, group them behind a router rather than presenting all thirty at once.

Using it when you didn't need to. This is the expensive one. If you can write the steps down in advance, write them down — a fixed pipeline is cheaper, faster, and testable. The ReAct loop earns its cost only when the next step genuinely depends on what the last one found. That boundary is the same one described in agentic workflows, and most tasks land on the fixed-pipeline side of it.

ReAct vs the other agent patterns

ReAct is one architecture among several, and it isn't always the right one:

  • Plan-and-execute writes the full plan up front, then runs it. Cheaper and more predictable than ReAct, worse at adapting mid-task.
  • Reflexion adds a self-critique step after attempts, so the agent evaluates its own output and retries. Better quality, more tokens.
  • Orchestrator-worker has a coordinating model dispatch subtasks to specialized workers. Useful when subtasks are genuinely independent.

In practice these get combined — a ReAct loop with a reflection step, or a planner that spawns ReAct workers. Start with plain ReAct, because it's the easiest to debug when something goes sideways.

For the broader vocabulary around all of this, what defines an agent covers where the line actually sits, and AI agent builder walks through the no-code side for people who'd rather not write the loop at all.

Running someone else's agent without rebuilding it

The frustrating part of this space isn't the concept. It's that every working agent you find lives in a repo with its own dependency list, environment variables, and API key setup — and reproducing somebody's environment takes longer than understanding their idea did.

If that's your bottleneck, Taku mirrors a working AI setup into a desktop workspace and runs it, so you can use a power user's configuration without reproducing their environment first. It's in Beta.

FAQ

What does ReAct stand for in AI?

Reasoning and Acting. It describes an agent that alternates between reasoning about a task in natural language and taking actions through tools, using each to inform the other.

Is a ReAct agent the same as an AI agent?

ReAct is one architecture for building an AI agent, and currently the most common one. "AI agent" is the general category; ReAct is a specific loop shape within it.

What is create_react_agent?

A prebuilt function in LangGraph's langgraph.prebuilt package that builds a complete ReAct agent graph from a model and a set of tools — the model call, the tool execution node, and the conditional routing between them. LangGraph v1 deprecated it in favor of create_agent from langchain.agents, which does the same thing and is where new code should start. The old function still runs and is scheduled for removal in v2.

Do I need a ReAct agent framework, or can I write the loop myself?

The loop is genuinely simple — call the model, check for tool requests, execute them, append results, repeat. Writing it yourself is a good way to understand it. Frameworks earn their place once you need streaming, checkpointing, human-in-the-loop interrupts, and persistence, which is where the fiddly parts live.

Why does my ReAct agent keep looping?

Almost always a tool problem rather than a model problem. Either a tool returns something that doesn't match its description, or an error comes back as a string the model reads as a normal result and retries. Read the action log: the repeated call and its argument usually identify the culprit immediately.

Is ReAct still current, or has it been superseded?

The core loop is still what most agents run. What changed is the plumbing — native tool-calling APIs replaced the original text-parsing prompt format, and the pattern now usually appears wrapped in a framework rather than hand-rolled. The thought-action-observation cycle itself is unchanged.