0PricingLogin
Claude Architect · Lesson

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 your max_tokens limit.
  • 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_sequence

All lessons in this course

  1. The Core Loop
  2. Terminating on stop_reason
  3. Anti-Pattern: Parsing Text for Completion
  4. Anti-Pattern: Arbitrary Iteration Caps
← Back to Claude Architect