Task Statement 1.1 — how an agent actually runs, and the three loop-control mistakes the exam loves.
An "agent" is not magic. It is a loop wrapped around a single stateless API call. Master the loop and half of Domain 1 collapses into common sense.
stop_reason on the response.stop_reason == "tool_use": execute the requested tool(s), then append the tool result(s) to the message history and go back to step 1.stop_reason == "end_turn": the model is done — stop and surface the final text.stop_reason is the loop's control signal. Continue on "tool_use", terminate on "end_turn". Everything else is a distractor.The API is stateless — each call only knows what you send it. When a tool returns (say lookup_order → status, dates, amount), you append that result as a message. On the next iteration Claude reads it and reasons about what to do next. Drop it, and the model is blind to its own tool's output.
This is also model-driven decision-making: Claude picks the next tool from accumulated context. That is different from a hard-coded decision tree or fixed tool sequence — and the exam treats model-driven flexibility as the default agentic pattern (you only override it with enforcement when you need a guarantee — Lesson 3).
while True:
resp = claude.create(messages=history, tools=TOOLS)
if resp.stop_reason == "tool_use":
for call in resp.tool_calls:
result = run(call) # execute
history.append(tool_result(result)) # feed back
continue # loop
else: # "end_turn"
return resp.text # done
The exam builds distractors out of "reasonable-sounding" loop controls that are actually wrong:
| Anti-pattern | Why it's wrong |
|---|---|
| Parsing natural-language signals ("looks like Claude is finished") to end the loop | Brittle and non-deterministic; the structured stop_reason already tells you exactly. |
| Using an arbitrary iteration cap as the primary stopping mechanism | A cap is a safety backstop, not the control signal. It truncates legitimate work or masks a stuck loop. |
| Checking for assistant text content as a completion indicator | Claude can emit text and still request a tool. Text presence ≠ done. |
stop_reason.stop_reason equals "end_turn"; continue otherwisestop_reason == "end_turn" is the only reliable signal that Claude is finished; "tool_use" means keep going. The other three are the canonical anti-patterns: text-presence (Claude can emit text and request a tool), iteration caps (a backstop, not a control signal), and prose "completion detection" (non-deterministic).tool_choice are unrelated to whether the model sees prior tool output.stop_reason. State persistence = append tool results. Next-action choice = model-driven (default), unless a guarantee forces enforcement.max_tokens interacts with stop_reason ("max_tokens" is a third value)? Ask and I'll go deeper before we move on.