The ReAct Agent Pattern: Implementing Reason + Act Loops with Tool Execution
The ReAct (Reason + Act) design pattern combines chain-of-thought reasoning with real-world tool execution, creating an iterative loop where the AI reasons about what to do next, executes an external tool, observes the output, and iterates until the goal is solved.
Overview #
The ReAct (Reason + Act) design pattern combines chain-of-thought reasoning with real-world tool execution, creating an iterative loop where the AI reasons about what to do next, executes an external tool, observes the output, and iterates until the goal is solved.
Why Pure Reasoning or Pure Acting Fails #
Pure reasoning models hallucinate missing facts because they cannot observe current state. Pure action models execute tools blindly without planning or error recovery. ReAct interleaves verbal reasoning traces ('Thought:') with concrete tool invocations ('Action:'), followed by reading the execution output ('Observation:'). This mirrors human problem solving.
The ReAct Execution Loop #
- Thought: Model reflects on current state and plans the next step ('I need to check the inventory database for item #592').
- Action: Model emits a structured tool call (e.g.
check_inventory(item_id=592)). - Observation: The host environment executes the action and appends the result into the message history ('Quantity: 0; Expected Restock: Friday').
- Thought: Model reflects on the new observation ('The item is out of stock until Friday. I should notify the user and offer alternatives.').
- Final Answer: The model synthesizes the completed response.
Loop Guardrails: Preventing Infinite Recursion #
Without guardrails, agents can fall into infinite retry loops when a tool repeatedly errors. Production implementations enforce strict max_iterations (e.g. max 6 turns), token budgets, and timeout limits.
Code Example: Clean Python Implementation of a ReAct Loop #
from openai import OpenAI
client = OpenAI(base_url="https://api.apihundred.com/v1", api_key="your_key")
def run_react_agent(task_prompt, max_turns=5):
messages = [
{"role": "system", "content": "You are an agent. Use tools to find facts. Never guess."},
{"role": "user", "content": task_prompt}
]
for turn in range(max_turns):
response = client.chat.completions.create(
model="gpt-4o",
messages=messages,
tools=[{"type": "function", "function": {"name": "get_weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}}}}]
)
msg = response.choices[0].message
messages.append(msg)
if not msg.tool_calls:
# Model has reached final answer
return msg.content
for tool_call in msg.tool_calls:
# Execute tool and append observation
observation = "Current Weather in Tokyo: 18°C, Clear skies."
messages.append({"role": "tool", "tool_call_id": tool_call.id, "content": observation})
return "Max iterations reached without resolution."
Frequently Asked Questions #
Q: What does ReAct stand for?
ReAct stands for 'Reasoning and Acting', published in a landmark 2022 research paper by Princeton and Google.
Q: How do ReAct agents differ from fine-tuned models?
ReAct is an architectural prompting and tool-loop pattern, not a training method. It can be used with any foundation model that supports function calling.
Q: Which models excel at ReAct agent workflows?
Claude 3.5 Sonnet, GPT-4o, and DeepSeek-V3 demonstrate superior planning and recovery from erroneous tool observations.
Build with API100
Access 100+ AI models through one lightning-fast OpenAI-compatible API with sub-50ms routing overhead and zero markup on cached tokens.

