How ReAct Agents Combine Reasoning and Tool Use in LLM Apps

Learn how ReAct agents loop through thoughts, tool calls, and observations—and how to ship them safely in production LLM apps.

6 min read

Large language models answer well from memory, but they stumble when a task needs live data, arithmetic you can verify, or actions in another system. ReAct agents (reasoning + acting) address that gap by alternating short reasoning steps with tool calls, then folding observations back into the prompt. Search interest in “react agent” often points here—not the React.js UI library, but the agent pattern from Yao et al.’s work on synergizing reasoning and acting in language models.

What a ReAct agent does in one loop

A ReAct-style loop typically looks like this:

  1. The model receives a goal, tool definitions, and conversation history.
  2. It emits a thought (plan or sub-goal) and an action (which tool to call, with arguments).
  3. Your runtime executes the tool and returns an observation (API JSON, search snippet, DB row, etc.).
  4. Steps 2–3 repeat until the model produces a final answer or hits a step limit.

The pattern is deliberately simple: you are not hiding tools inside opaque function-calling blobs unless you want to. Many teams expose the same structure in plain text (Thought:, Action:, Observation:) because it debugs well in logs and teaches junior engineers how the agent actually “thinks.”

ReAct vs plain tool-calling

ApproachStrengthWeakness
Single-shot function callLow latency, cheapEasy to pick the wrong tool or args with no recovery
ReAct loopRecover from bad calls; chain toolsMore tokens; needs guardrails on max steps
Fixed workflow (DAG)Predictable, testableBrittle when user intent varies

ReAct shines when the correct path is unknown upfront: “Find our Q3 revenue, compare to last year, and draft a Slack summary.” A workflow engine might hard-code three steps; a ReAct agent can discover that revenue lives in Snowflake, last year’s number needs a different filter, and Slack needs a shorter tone.

Minimal architecture

You need four pieces:

  • Policy model — any chat model with reliable instruction-following.
  • Tool registry — name, JSON schema, and an async handler per tool.
  • Executor — validates args, runs handler, truncates huge observations.
  • Stop conditions — max steps, max wall time, duplicate-action detection.

Pseudocode for the executor boundary:

async def run_react_turn(state, model, tools):
    response = await model.complete(state.messages)
    action = parse_action(response)  # tool name + JSON args
    if action is None:
        return finalize(response)
    if action.name not in tools:
        obs = "Error: unknown tool"
    else:
        obs = await tools[action.name](**action.args)
    state.messages.append({"role": "assistant", "content": response})
    state.messages.append({"role": "user", "content": f"Observation: {obs}"})
    return state

Production systems almost always sanitize observations (strip secrets, cap length) before the next model call.

Designing tools that agents can actually use

Bad tools are the main reason ReAct loops fail.

  • One job per tool — search_docs(query) beats run_sql(string) for most models.
  • Structured errors — return {"error": "not_found", "hint": "try sku not name"} instead of stack traces.
  • Idempotency — agents retry; create_ticket should dedupe on a client token.
  • Read before write — expose get_order(id) before refund_order(id).

Document edge cases in the tool description. Models read those descriptions literally.

Prompting patterns that work

  1. Force explicit planning on step one for multi-hop tasks.
  2. Require citations from tool output before factual claims.
  3. Ban hallucinated observations — only your runtime may add Observation: lines (inject via system message).
  4. Few-shot one trajectory — a single worked example cuts malformed actions dramatically.

Temperature around 0–0.3 is common for action selection; you can use a higher temperature only for final user-facing prose if you split “planner” and “writer” roles.

Safety and abuse

ReAct agents inherit every risk of the tools they wield.

  • Run handlers with least-privilege credentials (read-only DB role by default).
  • Add human approval for irreversible actions (payments, mass email).
  • Log full traces for audit, but redact PII in stored prompts.
  • Detect runaway loops (same action repeated with identical args).

Treat the agent as an untrusted client of your internal APIs—same as a mobile app.

Testing and evaluation

Unit-test tools without the model. Integration-test with frozen trajectories: given a sequence of fake observations, assert the next action.

For quality metrics, track:

  • Task success rate on a fixed eval set
  • Average steps to completion
  • Tool error rate
  • Cost per successful task

Regression when you change tool descriptions is real; version them like API schemas.

When not to use ReAct

Skip the loop if:

  • The task is a single deterministic API call.
  • Latency budget is sub-second.
  • Compliance requires a fully auditable predefined workflow.

In those cases, a state machine or compiled agent graph (LangGraph, Temporal, custom) is usually clearer.

FAQ

Is ReAct the same as OpenAI function calling?
Function calling is one encoding of actions. ReAct is the loop that may use function calling—or plain text actions—between observations.

Does this relate to React.js?
No. The collision in search results is unfortunate; context usually disambiguates (LLM, tools, agents).

How many steps are enough?
Start with 5–8 for research tasks; increase only with monitoring. Most failures are infinite retry, not too few steps.

Can small models run ReAct?
Yes, with fewer tools and stricter schemas. Large models tolerate ambiguous tool docs; small ones need examples.

Observability: what to log per step

Production ReAct systems generate rich traces if you plan for them. At minimum, persist:

  • Correlation ID per user request
  • Model version and prompt template hash
  • Each thought/action/observation triple with timestamps
  • Token usage per step (input vs output)

Dashboards that matter to product teams: success rate by intent, median steps, and top failing tools. Dashboards that matter to security: tools invoked per role, blocked actions, and PII redaction counts.

When debugging a bad run, replay with the same observations but a newer model—if behavior fixes without changing tools, your issue was policy, not infrastructure.

Cost controls

Each loop multiplies tokens. Tactics that actually move the bill:

  • Compress observations (JSON → bullet summary by a cheap model or rule)
  • Cache read-only tool results keyed by args hash
  • Route simple queries to a smaller model; escalate only after a failed tool attempt
  • Cap observation size (first 2 KB + “truncated” flag)

Set a per-user daily step budget for consumer products; B2B agents can use per-tenant quotas tied to contract tier.

Framework landscape (without picking winners)

Most agent SDKs implement the same loop with different ergonomics:

  • Text-based ReAct parsers vs native function-calling APIs
  • Graph compilers that compile loops into state machines after prototyping
  • Hosted agent runtimes that manage memory and checkpoints

Choose based on who owns the runtime (your VPC vs vendor SaaS) and testability, not buzzwords. The pattern predates any single open-source package.

A realistic customer-support example

Goal: “Where is order 8842?”

  1. Thought: Need order status from OMS.
  2. Action: get_order(order_id=8842)
  3. Observation: { "status": "shipped", "carrier": "UPS", "eta": "2026-10-23" }
  4. Thought: User may want tracking link.
  5. Action: tracking_url(carrier="UPS", tracking_id="…")
  6. Observation: URL string
  7. Final answer to user with ETA and link.

If step 2 returns not_found, a good agent tries search_orders(email=…) only when policy allows—another reason tools should encode business rules in error payloads.

ReAct agents are not magic—they are disciplined control flow around a model. Get the tool surface right, keep observations honest, and the loop becomes a practical way to ship agents that do real work instead of guessing.

More in artificial-intelligence

Cubed

Write about the technologies shaping the future.

For developers, founders, and curious minds exploring AI, crypto, Web3, and emerging tech—signal over noise.

One free account across In Plain English, Stackademic, Venture, and Cubed.

How it works
  • AI, crypto & Web3
  • Software & emerging technologies
  • Analysis & practical resources
  • Thoughtful voices, not hype
1

Sign in

Google or GitHub

2

Complete profile

Takes a few minutes

3

Get approved & publish

Start sharing

Why write for Cubed?

The future deserves thoughtful voices, not just louder headlines.

Comments

Loading comments…

Posts Across the Network