The agentic loop — the foundation of every Agent SDK app
The agentic loop is the four-step cycle that turns a stateless LLM call into a system that takes actions in the world.
The loop:
- Send the conversation history (plus the tools available) to Claude.
- Look at the response's
stop_reasonfield. - If
stop_reason === "tool_use"— execute the requested tools and append their results to history. - If
stop_reason === "end_turn"— the loop is done. Return the final response.
That's it. Every Agent SDK app — single-agent or multi-agent — is built on this.
stop_reason is the single most important field on the response. It is the canonical signal for loop control.
| Value | What it means | Loop action |
|---|---|---|
"tool_use" | Claude wants to call one or more tools before continuing | Execute the tools, append tool_result blocks, loop again |
"end_turn" | Claude has finished its turn | Exit the loop |
You'll see exam questions suggesting other ways to detect completion — checking the assistant's text content, counting iterations, sentiment analysis. All wrong. The right answer is always: inspect stop_reason.
Why "model-driven" matters. A naive engineer might write:
if (userMessage.includes("refund")) callTool("process_refund");
This is not an agentic system. The decision has been pulled out of Claude and into your code. Every new edge case becomes a new if branch.
Agentic systems push decision-making into Claude:
- Give it good tool descriptions
- Give it relevant context
- Trust it to pick the next action
Your code's job is the loop infrastructure — sending requests, executing tools, handling errors. Not the decisions themselves.
Anti-patterns to memorise:
- ❌ Parsing assistant text to decide when to stop
- ❌ Using an iteration cap as your primary stopping mechanism (it's a safety belt, not a brake)
- ❌ Treating "any text content" as a completion signal — Claude can emit text and tool calls in the same response
- ❌ Pre-classifying input before Claude sees it (routing logic that runs before the model)
If a question shows you a system doing any of these, the right answer is almost always "fix it by leaning on stop_reason and the model's judgment."