The ReAct Pattern: Reason + Act
ReAct (Reasoning + Acting) is the fundamental loop behind OpenClaw agents. The model alternates between writing a Thought (reasoning about what to do), taking an Action (calling a tool), and processing an Observation (the tool result) — until the task is complete.
Origin of ReAct
The ReAct pattern was introduced in the 2022 paper "ReAct: Synergizing Reasoning and Acting in Language Models" (Yao et al.). The paper showed that interleaving chain-of-thought reasoning with tool use dramatically outperformed both reasoning-only and action-only approaches on knowledge-intensive tasks.
Thought → Action → Observation Cycle
Each step in a ReAct agent run produces one or more of these tagged outputs:
Thought: I need to find the current Python version. I'll search PyPI.
Action: web_search("latest Python stable release 2026")
Observation: Python 3.13.2 was released on January 14, 2026.
Thought: I have the version. Now I'll write it to the output file.
Action: file_writer("python-version.txt", "Python 3.13.2")
Observation: File written successfully.
Thought: Task complete.
Final Answer: The latest stable Python version is 3.13.2.How OpenClaw Implements ReAct
OpenClaw builds the ReAct prompt format automatically. You configure the agent; the loop runs internally:
# agents/my-agent.yaml
name: my-agent
model: gpt-4o
max_steps: 10 # hard limit on loop iterations
temperature: 0.1
tools:
- web_search
- file_writer
verbose: true # print Thought/Action/Observation to stdoutfrom openclaw import Agent
agent = Agent.from_config("agents/my-agent.yaml")
# Enable streaming to observe the ReAct loop live
for step in agent.stream("Find Python 3 version and save it"):
print(f"[{step.type}] {step.content}")Configuring Step Limits and Loop Safety
name: safe-agent
model: gpt-4o-mini
max_steps: 15 # stop after 15 iterations
max_tokens_total: 50000 # total token budget for the run
loop_detection: true # abort if the same action repeats 3x
on_max_steps: "return_partial" # return what we have vs raise exceptionWhen ReAct Works Well vs When It Fails
| ReAct works well | ReAct struggles |
|---|---|
| Multi-step information gathering | Tasks needing precise math (use code executor) |
| Tasks requiring tool results to plan next step | Very long tasks with many steps (context fills up) |
| Open-ended research | Tasks with ambiguous stopping conditions |
| Tasks with clear success criteria | Real-time tasks requiring sub-second responses |
Observing Agent Reasoning Logs
from openclaw import Agent
import json
agent = Agent.from_config("agents/my-agent.yaml")
result = agent.run("Summarise the last 5 Python PEPs", return_trace=True)
# Full reasoning trace
for i, step in enumerate(result.trace):
print(f"Step {i+1}: [{step.type}]")
print(f" {step.content[:200]}")
if step.tool_call:
print(f" Tool: {step.tool_call.name}({step.tool_call.args})")
if step.observation:
print(f" Result: {step.observation[:100]}")- ReAct interleaves Thought (reasoning), Action (tool call), and Observation (result).
- The loop continues until the agent signals completion or the step budget is exhausted.
- OpenClaw implements ReAct transparently — configure max_steps and tools, run the agent.
- Use
return_trace=Trueorverbose=Trueto inspect agent reasoning.
Reading and Debugging ReAct Traces
Understanding the Thought → Action → Observation trace is essential for debugging agents that produce wrong answers or get stuck. Enable verbose output to see each step:
agent = Agent(model="gpt-4o", tools=[search, calculator], verbose=True)
result = agent.run("What is the market cap of the top 3 AI companies?")
# Trace output:
# [Step 1] Thought: I need to identify the top 3 AI companies by market cap.
# [Step 1] Action: search(query="top AI companies by market cap 2026")
# [Step 1] Observation: NVIDIA ($3.2T), Microsoft ($2.9T), Alphabet ($2.1T)
# [Step 2] Thought: I have the data. I can now answer directly.
# [Step 2] Final answer: NVIDIA ($3.2T), Microsoft ($2.9T), Alphabet ($2.1T)
Common ReAct Failure Modes
- Premature termination. The agent returns a final answer after one tool call without verifying the result. Fix: add a verification step prompt or use
min_steps=2. - Tool call loops. The agent calls the same tool repeatedly with the same arguments. Fix: enable
loop_detection=Trueand review whether the tool return value is informative enough. - Hallucinated tool calls. The agent invents a tool name that doesn’t exist. Fix: use strict tool schema validation; log and alert on
ToolNotFoundError. - Context exhaustion. For long-running tasks, the agent’s early observations fall out of context. Fix: use
context_strategy="memory_offload"to store old observations in vector memory.