The ReAct Pattern
Reason, Act, Observe: the loop that turns Claude into an autonomous problem-solver.
- Why agents differ fundamentally from chatbots
- The four phases: Reason, Act, Observe, Repeat
- How to implement the agentic loop correctly
- Why thought traces improve accuracy by 10-40%
- The correct stop condition and two anti-patterns
- Manual loop vs. Agent SDK - what each handles
What You'll Learn
Tap any concept to jump directly to it.
Chatbot vs. Agent
A chatbot responds to one message and stops. An agent receives a goal and works through multiple steps - reasoning, calling tools, observing results, and looping - until the goal is achieved.
The difference is not the model. The difference is the loop. A chatbot is a single API call. An agent is a while loop that keeps calling the API until the task is done.
Help Desk vs. Project Manager
Before: a help desk where every operator reads from a single script. You call to ask if your order was shipped - they look up one field, read it back, and the call ends.
The pain: if your order needs rerouting and the new tracking number needs emailing, the operator says "I can't help - call three separate departments." Each one has a one-answer script.
The mapping: a chatbot is that operator - one message in, one response out. An agent is a project manager: it gets your request, decides what steps to take, calls the right departments in sequence, and comes back with the complete solution. That ability to loop across multiple steps is what ReAct gives Claude.
When to Use Each
| Dimension | Chatbot | Agent |
|---|---|---|
| API calls | 1 per turn | Many per task |
| Tools | None | Search, code, APIs |
| Memory | Current turn only | History grows each turn |
| Stops when | After one response | stop_reason = "end_turn" |
| Best for | Q&A, summaries, generation | Research, multi-step tasks |
- Use chatbot when one response fully answers the question
- Use agent when the answer requires gathering info from multiple places
- Use agent when steps depend on each other (step 3 needs step 2's result)
- Agents cost more - don't use them when a chatbot suffices
Chatbot or Agent?
Common Wrong Beliefs
What Is ReAct?
ReAct (Reasoning + Acting) is a pattern where the model alternates between writing explicit reasoning ("Thought: ...") and calling tools ("Act: ..."). The thought step is not decoration - it's the mechanism that makes multi-step reasoning accurate.
Before ReAct, two approaches existed: pure chain-of-thought (all reasoning, no tools - hallucinated facts) and silent tool use (calls tools without reasoning - picked the wrong ones). ReAct fuses both: reason about which action fills the gap, then act, then observe the result.
The Detective's Case Notes
Before: a detective who interviews witnesses and reads documents but takes no notes. By the third witness, they've forgotten what the first one said.
The pain: the final report is either a copy of the last interview or disconnected fragments. The detective can't connect clue A to clue B because A was never recorded.
The mapping: ReAct's "Thought:" is the detective's case notes. Every reasoning step is written out, stays in the case file, and informs the next step. The agent's thought traces are why it can synthesize a coherent answer after five tool calls - it's been leaving notes for itself the whole time.
Why Explicit Reasoning Helps
- Grounds each action: "Thought: I need pricing data - the benchmark search didn't include it." The thought identifies exactly what gap the next tool fills.
- Prevents wrong tool selection: Without a reasoning step, the model may call a tool by keyword matching. With a thought, it selects based on logical need.
- Creates working memory: Each thought accumulates in conversation history. Turn 5 can reference Turn 2's insight because it's written in the transcript.
- Audit trail: In production, you can see why every tool was called. Essential for debugging and compliance.
- Better synthesis: The final answer is grounded in all intermediate reasoning, not just the last tool result.
ReAct Pattern Structure
Common Wrong Beliefs
The ReAct Loop
The loop has four named phases: Reason (Claude writes a Thought), Act (Claude calls a tool), Observe (your code appends the tool result), and Repeat or stop. One full cycle is one "turn."
Critical clarification: Claude does not run the tools. Claude requests a tool call and pauses. Your code reads that request, executes the tool, and sends the result back. Claude reads the result in the next turn - that's the "Observe" phase. The loop is a collaboration between the model and your code.
The Research Loop
Before: researching a complex topic with a strict rule - you can only read one source at a time, and between each source you must write a note on what you learned and what you still need.
The pain: without the notes, you'd read one paper, give a partial answer, and miss all the context from subsequent sources.
The mapping: the ReAct loop is that process. Each iteration: write a note (Reason), read a source (Act), update your understanding (Observe), decide if you need more (Repeat or Done). The conversation history is the stack of notes that makes the final answer coherent.
The Four Phases
- Reason: Claude writes "Thought: ..." describing what it knows, what's missing, and why the next tool fills the gap. This becomes part of the conversation history.
- Act: Claude produces a tool_use block: tool name plus inputs. Claude then pauses - it does not execute the tool itself.
- Observe: Your code reads the tool_use block, runs the actual function, and appends the result to the conversation as a tool_result message.
- Repeat or Stop: Check stop_reason. If "tool_use" - loop again. If "end_turn" - Claude finished and produced a text answer.
The Loop
Common Wrong Beliefs
Implementing ReAct
ReAct implementation has three pieces: tool definitions (what Claude can call), the agent loop (the while loop that runs until stop_reason = "end_turn"), and tool execution (your code that runs each tool and returns results).
The conversation history array is the agent's stateful memory. Because the Messages API is stateless, you maintain the history yourself - every tool request and result gets appended before the next API call. Claude "remembers" because everything it's said is passed back to it each turn.
The Amnesiac Consultant
Before: imagine calling a brilliant consultant who has total amnesia between phone calls. Each call starts fresh - they remember nothing from the previous conversation.
The pain: they give great answers within a single call, but any follow-up starts from zero. "As I mentioned last time..." gets a blank stare every time.
The mapping: Claude is that consultant - each API call starts fresh. Your messages array is the transcript you read back at the start of every call: "Here's what we discussed so far..." You maintain the state; Claude provides the intelligence.
Three Building Blocks
- Tool definitions: JSON objects with name, description, and input schema. The description is critical - Claude uses it to decide when to call the tool. Vague descriptions cause wrong selections.
- The loop: a while loop calling client.messages.create() with the growing messages array. Each iteration appends Claude's response and the tool results.
- Tool dispatch: code that reads each tool_use block, routes to the right function, and returns results. Always return structured errors on failure - never raise exceptions that crash the loop.
- Stop check: after each API call, check response.stop_reason. "end_turn" means extract and return final text. "tool_use" means continue the loop.
Tool Definitions + Loop
Common Wrong Beliefs
Thought Traces
Thought traces are the "Thought: ..." paragraphs Claude writes before each tool call. They serve two purposes: working memory (each thought accumulates in context so Claude stays oriented across many turns) and audit trail (every tool call has a recorded "why" immediately before it).
You enable thought traces by instructing Claude in the system prompt: "Before every tool call, write a Thought: explaining what you know, what's missing, and why this specific tool call fills that gap." No special API flag is needed - just the system prompt instruction.
The Researcher's Notebook
Before: a researcher opens Paper 1, reads a paragraph, closes it, opens Paper 2, reads, closes - with no notes. By Paper 3 they've forgotten what Paper 1 said.
The pain: the final report either copies the last thing read or strings together disconnected fragments. No synthesis is possible without connections between the papers.
The mapping: thought traces are the notebook. "After Paper 1: my understanding is X, I still need Y." That note travels into every subsequent step. The agent can synthesize a coherent answer because it's been annotating the whole time - and every annotation is in the conversation context.
What Thought Traces Do
- Anchor to intent: each thought reconnects the current step to the original goal, preventing the agent from drifting after several tool calls.
- Improve tool selection: the explicit reasoning step prevents surface-level keyword matching. Claude picks the right tool because it must justify the choice in writing first.
- Enable debugging: when the agent gives a wrong answer, the thought traces show exactly where reasoning went off - wrong search query? Misread result?
- Compliance records: in regulated domains you can show auditors why every action was taken. The thought trace is the contemporaneous record.
- Better synthesis: the final answer references insights from multiple previous turns because they're all in the thought traces and in context.
System Prompt for Thought Traces
Common Wrong Beliefs
Stop Conditions
The correct way to stop a ReAct loop is to check stop_reason in the API response. When Claude is done, it sets stop_reason = "end_turn" and produces a text response. When it wants more tool calls, it sets stop_reason = "tool_use".
An iteration cap (max_turns) should exist as a safety net only - not as the primary stopping mechanism. If you're hitting the cap regularly, your agent has a design problem. Let Claude decide when it's done.
Navigation vs. Fuel Gauge
Before: driving to a destination with a rule: stop after exactly 10 turns, regardless of whether you've arrived. Sometimes you're there by turn 3 and drive circles for 7 more. Sometimes you need 15 turns and get stranded 5 short.
The pain: an arbitrary turn count produces both wasted effort (stopping too late) and incomplete results (stopping too early) - and you never know which failure mode you hit.
The mapping: stop_reason = "end_turn" is the GPS saying "you have arrived." The turn cap is the fuel gauge - a safety measure against driving forever, not the thing that determines when you're done. Stop when you arrive, not when the gauge hits a number.
Two Anti-Patterns, One Correct Pattern
Check if Claude's response contains "I'm done" or "task complete." Fails because Claude phrases completion differently every run, and the phrase may appear inside a thought trace mid-task.
Using "if turns >= 10: break" as main logic. Too few for complex tasks (stops before done); too many for simple ones (wastes turns and money).
Primary stop: stop_reason = "end_turn". Safety cap (20-50 turns): handles runaway loops. Handle cap-exceeded explicitly - log it, tell the user, never silently return partial results.
Stop Condition Logic
Common Wrong Beliefs
Manual Loop vs. Agent SDK
M12 is a Tier 2 module: you learn both the manual implementation (raw Messages API while loop) and the Agent SDK (@tool decorator + query() function). The goal is to understand what the SDK hides so you can debug it when something breaks.
The SDK handles: the loop, history management, tool dispatch, and stop-reason checking. You still control: tool implementations, system prompt, model selection, error handling inside tools, and the max-turns safety cap.
SQL vs. the ORM
Before: developers who only know ORMs and never learned SQL. They use the ORM fine until a complex query produces wrong results - and they have no idea what SQL the ORM generated or why it's wrong.
The pain: they can use the abstraction but can't debug or optimize it because they don't understand what's underneath.
The mapping: learning the manual ReAct loop first, then the SDK, is like learning SQL before the ORM. When the SDK produces unexpected behavior - wrong stop, missing tool call, strange output - you can look under the hood because you know what the loop is supposed to do at each step.
What the SDK Abstracts
| Piece | Manual | Agent SDK |
|---|---|---|
| Loop | You write while loop | SDK runs it |
| History | You append to messages[] | SDK manages it |
| Tool dispatch | You route tool_use blocks | SDK routes to @tool functions |
| Stop check | You check stop_reason | SDK checks it |
| Tool logic | You implement | You implement (in @tool) |
| System prompt | You write | You write |
Manual vs. SDK
Common Wrong Beliefs
Test Your Understanding
Tap each question to reveal the answer.
stop_reason == "end_turn" in the API response. This is the only reliable signal. Don't parse Claude's text for phrases like "I'm done," and don't use an iteration count as the primary stopping logic.Ready to Build?
You've covered all 7 core concepts. The desktop module has the complete hands-on lab where you build a working ReAct research agent with full runnable code, step-by-step instructions, and a Tier 2 SDK comparison.
Open the Full Module
Complete code - Hands-on lab - SDK comparison - 6-question quiz with detailed feedback
Open M12 on Desktop