What Makes a System Agentic
Autonomy, tool use and iterative decision-making.
What Makes a System Agentic is a free Claude Architect lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Claude Architect learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What Is an Agentic System?
A normal program follows a fixed script. An agentic system is different: you give it a goal, and the model decides the steps to reach it.
Three properties make a system agentic:
- Autonomy — the model chooses what to do next, not your code.
- Tool use — it can act on the world (search, read files, call APIs).
- Iteration — it loops: act, observe the result, decide again.
In the Claude Certified Architect track, these three ideas sit at the center of Agent Architecture & Orchestration, the largest exam domain (27%).
The Model Keeps No State
Each call to the Claude API is stateless. The model remembers nothing between turns. You must send the full message history every turn.
A request carries these fields:
model— which Claude model to use.max_tokens— the output cap.system— instructions and role.messages— the entire conversation so far.tools— what the model is allowed to call.
Because there is no hidden memory, you own the loop that grows messages over time. That loop is what turns a single answer into agentic behavior.
import anthropic
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Check today's open orders."}]
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
system="You are an operations assistant.",
messages=messages, # the FULL history, every single turn
tools=TOOLS,
)Autonomy: Decisions Are Model-Driven
The heart of autonomy is simple: the model decides, your code executes.
You do not hard-code 'first search, then summarize, then reply.' You describe the goal and the available tools, and Claude works out the path — including when it has gathered enough to answer.
Reserve hard-coded logic for things you must guarantee (a refund limit, an identity check). Everything else is a model decision. Over-scripting the path defeats the purpose of building an agent at all.
Tool Use: Acting on the World
Autonomy is useless if the model can only talk. Tools let Claude take real actions: look up a customer, read a file, run a query.
You declare each tool with a name, a description, and an input_schema. The description is the primary selection mechanism — Claude reads it to decide when the tool applies. Names matter far less.
A good description states purpose, return values, input formats, and edge cases. Keep each agent focused: 4-5 tools per agent is optimal; past about 18 tools, selection reliability degrades.
TOOLS = [{
"name": "lookup_order",
"description": (
"Fetch an order by its ID. Use when the user references a "
"specific order. Returns status, items, and total. "
"order_id format: 'ORD-' followed by 6 digits, e.g. ORD-001234. "
"Returns an empty result if the order does not exist."
),
"input_schema": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
},
}]The stop_reason Signal
After every request, Claude returns a stop_reason. This is how the model tells you what it wants to happen next:
end_turn— Claude is finished. The task is complete.tool_use— Claude wants to run one or more tools, then continue.max_tokens— the output was truncated by your cap.stop_sequence— a custom stop string was hit.
The agentic loop is built entirely around inspecting this field. You never guess what the model meant — it tells you directly.
The Agentic Loop
Put the pieces together and you get the agentic loop:
- Send the request.
- Inspect
stop_reason. - If it is
tool_use: run the tools, append the results tomessages, and loop again. - If it is
end_turn: stop — the task is done.
This is iterative decision-making in action. Each pass, the model sees the new tool results and chooses its next move. The conversation history grows until Claude decides it is finished.
while True:
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=messages,
tools=TOOLS,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason == "end_turn":
break # the model says it is done
if response.stop_reason == "tool_use":
results = run_requested_tools(response.content)
messages.append({"role": "user", "content": results})Terminate on stop_reason, Not on Text
This is one of the most tested decisions on the exam. You terminate the loop on stop_reason — never by scanning the model's text for words like 'done', 'complete', or 'finished'.
Why? Text parsing is fragile: the model might say 'I'm not done yet' or 'almost finished', and a naive keyword match would stop early or loop forever. The stop_reason field is the model's explicit, structured signal — it is unambiguous.
Parsing text for completion signals is a classic anti-pattern. If you see it in an answer choice, it is almost always wrong.
Iteration Caps Are a Safety Net
It is wise to cap the number of loop iterations — but understand its role. An iteration cap is a safety net that catches runaway loops. It is not the primary way the loop ends.
The primary stop mechanism is always stop_reason == "end_turn". The cap only fires if something goes wrong and the model never converges.
Treating an arbitrary cap (say, 'always stop after 3 turns') as your main control flow is an anti-pattern. Let the model drive; keep the cap as a backstop.
MAX_TURNS = 10 # safety net, not the primary exit
for turn in range(MAX_TURNS):
response = client.messages.create(
model="claude-opus-4-8", max_tokens=1024,
messages=messages, tools=TOOLS,
)
messages.append({"role": "assistant", "content": response.content})
if response.stop_reason == "end_turn":
break # PRIMARY exit — the model decided
handle_tool_use(response)
else:
escalate("Loop hit the safety cap without converging.")Guarantees Belong in Code
Model decisions are powerful but probabilistic — roughly 90% reliable when steered by a prompt. For anything with financial, legal, or safety consequences, that is not enough.
When you need a 100% guarantee, use deterministic code, not prompt instructions:
- A hook can block a policy-violating action before it runs (e.g. a refund over $500).
- A programmatic precondition can require that a customer's identity is verified before any refund tool runs.
Prompts guide; code guarantees. Knowing which to reach for is core architect judgment.
def process_refund(order_id, amount, verified_customer_id):
# Deterministic precondition — a prompt cannot guarantee this
if verified_customer_id is None:
raise PermissionError("Identity must be verified before refunds.")
if amount > 500:
return escalate_to_human(order_id, amount) # hook-style hard rule
return issue_refund(order_id, amount)Tool Choice Shapes Autonomy
You can tune how much freedom the model has on any given request with tool_choice:
"auto"— Claude decides whether to answer in text or call a tool. This is the default and the most agentic."any"— Claude must call some tool. Useful when you want guaranteed structured output.{"type": "tool", "name": "X"}— force one specific tool.
An agentic system normally runs on "auto": the model needs the freedom to decide when to act and when it is done. Forcing tools every turn would break the natural end_turn signal.
response = client.messages.create(
model="claude-opus-4-8",
max_tokens=1024,
messages=messages,
tools=TOOLS,
tool_choice={"type": "auto"}, # let the model choose to act or finish
)From One Agent to Many
Once a single agentic loop works, the same ideas scale up. A multi-agent system uses a hub-and-spoke shape: a coordinator decomposes the task, delegates to subagents, and aggregates their results.
One rule is critical for the exam: subagents do not inherit the coordinator's conversation history. Each subagent's context must be passed explicitly in its prompt. There is no shared memory between them.
Each subagent still runs its own autonomous, tool-using, iterative loop — the building block you just learned, composed at a larger scale.
Quick Check: Ending the Loop
An architect is building a Claude agent that calls tools to resolve support tickets. How should the loop decide when the agent is finished with a request?
Recap: The Agentic Building Blocks
You now have the foundation of every Claude agent:
- Autonomy — the model decides the path; your code executes. Reserve hard code for guarantees.
- Tool use — descriptions drive selection; keep 4-5 focused tools per agent.
- Iteration — the loop runs request → inspect
stop_reason→ run tools → repeat. - Terminate on
stop_reason(end_turn), never by parsing text. Iteration caps are a safety net only. - State is yours — the model keeps none; send the full history every turn.
Master these and you can reason about any agent on the exam — single-agent or hub-and-spoke multi-agent.
Frequently asked questions
Is the “What Makes a System Agentic” lesson free?
Yes — the full text of “What Makes a System Agentic” is free to read here on the web, and the Claude Architect course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Claude Architect course, upgrade to CoddyKit PRO.
What will I learn in “What Makes a System Agentic”?
Autonomy, tool use and iterative decision-making. You practise Claude Architect with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Claude Architect?
No prior experience is required. Claude Architect on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “What Makes a System Agentic” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Claude Architect lesson?
Yes. Every Claude Architect lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- What Makes a System Agentic
- Model-Driven vs Hard-Coded Decisions
- When to Use an Agent
- The Agentic Loop Overview