Terminating on stop_reason
Let end_turn end the loop, not your string matching.
The Loop Needs an Exit
An agentic loop is simple: you send a request, Claude responds, and you decide whether to keep going. The hard question is when to stop.
Every API response carries a stop_reason field. This is the model's own signal about why it stopped generating. Your loop should listen to that signal — not guess by reading the words in the reply.
This lesson teaches one rule that separates robust agents from fragile ones: let end_turn end the loop, not your string matching.
The Four Stop Reasons
Claude returns one of four stop_reason values on every turn:
end_turn— the model finished its response naturally. The task turn is complete.tool_use— the model wants to call a tool. Run it, append the result, and continue.max_tokens— output was truncated by yourmax_tokenslimit.stop_sequence— a custom stop sequence you configured was hit.
These four values are a complete, reliable contract. Your control flow should branch on them directly.
resp = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
tools=tools,
messages=messages,
)
print(resp.stop_reason) # end_turn | tool_use | max_tokens | stop_sequenceAll lessons in this course
- The Core Loop
- Terminating on stop_reason
- Anti-Pattern: Parsing Text for Completion
- Anti-Pattern: Arbitrary Iteration Caps