The agentic loop and stop_reason
Every agent you build on the Messages API is the same four-step loop, and one response field drives it.
5 min read · Lesson 1 of 12 in this domain
An agent is not a special API. It is an ordinary loop you write around the same POST /v1/messages endpoint you would use for a single question. What makes it agentic is that you keep going: you send a request, and if Claude asks for a tool you run it, hand back the result, and send again — as many times as it takes. The API is stateless, so nothing carries over between requests except the message history you resend. That is why the loop is yours to write, and why getting its exit condition right is the whole game.
- The loop is: send request → check
stop_reason→ execute the requested tool → return the result → repeat. Nothing else controls continuation. - Continue looping while
stop_reasonistool_use. Stop onend_turn. - Append the full
response.contentto your message history, not just the text. Dropping thetool_useblocks breaks the pairing the API requires on the next turn. - Each
tool_resultmust carry thetool_use_idof the block it answers. - Bound the loop with a maximum-iteration counter. An agentic loop with no ceiling is an unbounded cost risk.
| stop_reason | Meaning | What you do |
|---|---|---|
| end_turn | Claude finished naturally | Exit the loop |
| tool_use | Claude wants a tool run | Execute it, return tool_result, loop |
| max_tokens | Hit the output cap | Raise max_tokens or stream |
| stop_sequence | Hit a custom stop sequence | Handle per your design |
| pause_turn | Server-side tool loop paused | Re-send to resume (see next lesson) |
| refusal | Declined for safety | Handle explicitly — content may be empty |
What one turn actually looks like. You ask "what is the weather in Paris?" and pass a get_weather tool. Claude replies with stop_reason: "tool_use" and a tool_use block containing {"location":"Paris"} and an id like toolu_01A. Your code calls the real weather API, then sends the whole conversation again: original question, Claude's assistant turn including that tool_use block, and a user turn holding a tool_result with tool_use_id: "toolu_01A". Claude now has the data and replies with prose and stop_reason: "end_turn". Loop exits. Two API calls, one answer.
Distractors offer text-block presence or token counts as the control signal. Only stop_reason is.
Which response field decides whether the agent loop continues?
Only stop_reason carries control meaning. Loop while it is tool_use; exit on end_turn.
What must you append to the message history after a tool_use turn?
Dropping the tool_use blocks breaks the tool_use_id pairing the next request requires.
Practise this domain with 27%%-weighted questions in the study app.
Open in study appSource: Claude Docs — Tool use overview · Independent study aid, not affiliated with or endorsed by Anthropic.