the minimal agent loop

state = {"goal": user_goal, "history": []}

while not done(state):
    action = model.decide_next_action(state)   # a tool call, or "finish"
    if action.type == "finish":
        return action.result
    result = execute(action)                    # your code runs it -- see Tool Calling
    state["history"].append((action, result))
This is the exact same request/execute/feed-back-in loop from Function & Tool Calling, run repeatedly with a termination condition, instead of stopping after one round trip.

ReAct: interleaving reasoning and action

ReAct prompts the model to explicitly alternate between a reasoning step ("Thought: ...") and an action step ("Action: call tool X with args Y"), observing the result before the next thought. Making the reasoning explicit and visible in the transcript, rather than implicit, measurably improves an agent's ability to recover from a tool call that returned something unexpected — the model has a place to notice and reason about the surprise before deciding what to do next.

Thought: I need the current weather before I can recommend clothing.
Action: get_weather(city="Austin")
Observation: {"temp_f": 98, "condition": "sunny"}
Thought: That's hot -- I should recommend light clothing and hydration.
Action: finish("It's 98°F and sunny in Austin — wear light, breathable clothing...")

planning vs. reactive agents

Reactive (decide one step at a time)Plan-then-execute
Upfront costLower — no separate planning callHigher — a dedicated planning step before execution starts
Good fit forShort tasks, or tasks where later steps genuinely depend on earlier resultsLonger multi-step tasks where seeing the whole plan upfront catches ordering mistakes early
Failure modeCan wander/loop without a global view of the goalA plan made with stale information can go wrong if the situation changes mid-execution

when multi-agent earns its complexity

A single agent with a well-scoped tool set and a well-formed prompt handles most tasks; splitting into multiple cooperating agents (e.g. a planner, a researcher, a critic) adds coordination overhead, more places for context to be lost between agents, and more total tokens spent. It tends to genuinely pay off when a task has clearly separable sub-roles that benefit from different tool access, different context, or a distinct "critic" pass reviewing another agent's output — not as a default architecture for tasks a single well-prompted agent could already handle.

where to go from here

Function & Tool Calling — the loop primitive agents are built from.
Agents & Subagents — this exact pattern as implemented in Claude Code.
Evaluating LLM Applications — measuring whether an agent is actually completing tasks correctly.