All posts
Fundamentals

What ReAct actually is

The loop we built a few posts ago has a name. The pattern is called ReAct, short for reason and act, and it sits underneath most agents you will meet.

The idea is small. Instead of answering everything at once, an agent alternates between reasoning about what it needs and taking an action to get it.

How you would answer the question yourself

Take our running question: how many staff-hours would routing routine tickets to an agent free, and does the saving cover the model calls?

You would not answer in one breath. You would think "I need the ticket counts first", go and read the export, think "now I need the current token price", look that up, then do the arithmetic. Reason, act, observe what came back, reason again.

ReAct is that cycle, written down.

The cycle, traced

Here is a ReAct agent working the question, with every step made explicit.

Thought:  I need the routine ticket counts for last quarter.
Action:   read_tickets(quarter="2026-Q2")
Observe:  password_reset: 118 tickets, 6.2 min avg; billing: 74; ...

Thought:  Now I need the current price per million input tokens.
Action:   search_web(query="input token price per million current")
Observe:  Pricing page: <rate> per 1M input tokens

Thought:  I have both. Time to work out the hours.
Action:   calculate(expression="118 * 6.2 / 60")
Observe:  12.19

Thought:  I have enough to answer.
Answer:   Password resets alone freed about 12 staff-hours last quarter...

Read the shape rather than the numbers. Each step states a thought, takes one concrete action, and reads the result before deciding the next move.

Reason, act, observe, repeat. The loop continues until the agent has enough to answer.Reason, act, observe, repeat. The loop continues until the agent has enough to answer.

The power is in the third column. When the first search comes back unhelpful, the agent reasons about that and tries a different query. When a number looks wrong, it can check it. A fixed script breaks the moment something unexpected happens; a ReAct agent reads what actually came back and adjusts. That is the same way a person works a multi-step problem, and it is why the pattern generalises so well.

The part that changed

Early ReAct agents had a fragile job to do. The model had to print its steps in an exact text format, something like Action: search["query"], and your code parsed that text to find the tool call.

Thought: I need the ticket counts
Action: read_tickets["2026-Q2"]

A missing bracket broke it. An extra space broke it. A slightly reworded keyword broke it. People spent real effort writing prompts that begged the model to format perfectly, and it still failed often, because you were parsing free text and free text varies.

Tool calling removed that whole class of problem. Instead of printing text you parse, the model emits a structured tool call, and the format is guaranteed by the API rather than hoped for.

# what the model returns now, structured, not text to parse
reply.tool_calls[0]      # name="read_tickets", arguments={"quarter": "2026-Q2"}

Old ReAct printed text you had to parse. Tool calling makes the call structured and reliable.Old ReAct printed text you had to parse. Tool calling makes the call structured and reliable.

If the "Thought" line is gone, is it still ReAct?

Yes, and the reason is worth holding onto.

The reasoning did not disappear. It moved inside the model. As covered earlier in this series, models are trained on large numbers of tool-calling examples, so choosing a tool and filling its arguments is the reasoning step, done internally. When the model picks read_tickets and supplies the quarter, it has already reasoned about what it needs.

So the visible Thought: text is gone, and the cycle is unchanged: reason about what is needed, act to get it, observe the result, repeat. Agents built on tool calling are still called ReAct agents across every major framework, because the principle is the same.

Text-based ReActTool-calling ReAct
How the model asks for a toolPrints Action: tool["args"] as textEmits a structured tool call
Who guarantees the formatNobody; you parse and hopeThe API
What breaks itA bracket, a space, a synonymMuch less
Where the reasoning livesAn explicit Thought: lineInside the model, in the tool choice
Still ReAct?YesYes

What to take from this

  • ReAct is reason, act, observe, repeat. Most agents are an implementation of it.
  • The loop from earlier in this series already does this. ReAct is the name for what it does.
  • Modern agents dropped the parsed Thought: text because tool calling made it unnecessary, not because the reasoning went away. It moved inside the model.

The loop we have is deliberately small. Turning it into something you would actually run, debug and extend needs a few more parts, and the first is somewhere to keep everything that happens during a run.