Agent Architecture/Single-Agent Patterns
Intermediate14 min

ReAct: The Core Pattern

The foundational agent loop: decide when ReAct earns its cost over simpler patterns, understand the token math behind each iteration, learn the five ways it fails in production, and ship it with create_agent, cost controls, and eval.

Quick Reference

  • ReAct = the LLM alternates between reasoning (what should I do next?) and acting (tool calls) until it has enough information to respond — the LLM decides when to stop
  • LangGraph implements ReAct as a cycle: agent node (LLM) → tool node → agent node → ... → END, gated by tools_condition
  • Each loop iteration re-sends the full message history — a 5-tool-call chain sends 6x the system prompt in cumulative tokens
  • Tool descriptions are the LLM's only guide for tool selection — ambiguous descriptions cause wrong tool calls, not failed tool calls
  • Default recursion_limit is 25 (node visits, not tool calls) — at 2 nodes per tool call that's roughly 12 tool calls
  • create_agent (langchain.agents) is the production API — it adds middleware, checkpointing, and ToolRuntime over hand-built StateGraph
  • The three ways ReAct fails in production: infinite loops (no progress), wrong tool selection (plausible but incorrect results), and context overflow (too many tool results fill the window)

Should I Use ReAct?

Is the taskdynamic?NoDeterministicworkflowYesDoes it needexternal tools?NoPrompt chainwith gatesYesIs the step countunknown at design time?NoFixed toolpipelineYesUse ReActDynamic · Tools · Unknown steps

ReAct earns its cost only when all three conditions hold

Most articles open with the mechanics. Start one step earlier: is ReAct the right pattern for this task? ReAct adds a loop, variable cost, and non-deterministic behavior. Half the time, a prompt chain or a deterministic workflow is cheaper and more reliable.

Definition

ReAct (Reason + Act) is the foundational agent pattern: the LLM generates a thought about what to do next, executes a tool action, observes the result, and repeats until it has enough information to respond.

SituationWhy ReAct underperformsUse this instead
Task steps are always the sameYou're paying for dynamic routing through a fixed pathPrompt chaining
Only one tool, always calledThe loop adds latency without adding decision valueSingle LLM call with tool bound
Deterministic branching (if/else on inputs)LLM is deciding what code could decide for freeConditional edges without agent loop
Task requires delegation to specialistsReAct is single-agent — it can't hand off workSupervisor or Orchestrator-Worker
PatternLLM callsCost shapeStep countBest for
Prompt chainFixed NPredictableKnownSequential generation with gates
Router1 + routedLow, fixed1–2Classifying and dispatching inputs
ReActVariableSuper-linearUnknownDynamic tool use with unknown steps
Orchestrator-Worker1 + N workersHigh, parallel1 + parallelDelegating subtasks to specialized agents
The one-line test

ReAct earns its keep when the number of steps and which tools to call are genuinely unknown at design time. If you can write a checklist of the steps before the agent runs, use a chain.