react recipe
The ReAct pattern: reason-then-act with tool calling
A reusable ReAct (reason + act) loop for tool-calling agents. Includes the prebuilt create_react_agent helper plus a hand-rolled StateGraph version in 5 languages.
4 min read · Published May 1, 2026 · Languages: python, typescript, rust, go, java
The pattern
ReAct (Reasoning + Acting) is the simplest useful agent loop: the model thinks, calls a tool, observes the result, and decides whether to keep going. It’s the basis of almost every “AI agent” you’ve used.
ReAct in one line: The model alternates between thought tokens and tool calls, ending when it emits a final answer. The framework owns the loop; the model owns the decisions.
Prebuilt (recommended)
from agentmatic.prebuilt import create_react_agent
from agentmatic import OpenAI, tool
@tool
def search(query: str) -> str: ...
@tool
def calculator(expression: str) -> str: ...
agent = create_react_agent(
llm=OpenAI("gpt-4o"),
tools=[search, calculator],
max_iterations=12,
)
result = agent.invoke("What is the GDP of Vietnam in 2024 divided by India's?")
Hand-rolled (for control)
When you need to customize the loop — extra observations, custom termination, parallel tool calls:
from agentmatic import StateGraph, START, END
graph = StateGraph(AgentState)
graph.add_node("reason", reason_node) # LLM call
graph.add_node("act", act_node) # tool dispatch
graph.add_conditional_edges("reason", route, {
"tools": "act",
"done": END,
})
graph.add_edge("act", "reason") # always loop back
graph.add_edge(START, "reason")
agent = graph.compile()
TypeScript
import { createReactAgent, OpenAI, defineTool } from '@agentmatic/core';
const agent = createReactAgent({
llm: new OpenAI('gpt-4o'),
tools: [search, calculator],
maxIterations: 12,
});
When to use it
- Single-purpose agents that need 1–N tool calls in sequence.
- Exploratory queries (“look this up, then do math on it”).
- Tool-rich but flow-simple workloads.
When NOT to use it
- Multi-step workflows with distinct phases — use Supervisor.
- Pure retrieval — use RAG, no loop needed.
- Parallel fan-out — use Map.