Claude Agent Tutorial: Build Reliable Agentic Loops
This claude agent tutorial walks through agentic loop design, tool integration, context management, and human handoff patterns for production-grade Claude agents.
By Solomon Udoh · AI Architect & Certification Lead

This claude agent tutorial is for engineers who want working code and principled design, not framework hype. We cover the agentic loop mechanics, tool integration, context management, and the human-oversight patterns that the CCA-F exam tests directly. Domain 1 (Agentic Architecture and Orchestration) carries 27% of the exam weight, the single largest slice, so getting these fundamentals right matters both in production and on the day.
What exactly is a Claude agent?
A Claude agent is a process in which the model drives its own next action by reading tool results, deciding what to do next, and calling tools again until a stopping condition is met. The loop is not magic: it is a while loop in your code that keeps calling the Messages API until stop_reason equals "end_turn" or your own guard fires.
The minimal anatomy is:
- A system prompt that defines the agent's goal and constraints.
- A set of tools the model may call.
- A host process that appends tool results and re-calls the API.
- A termination condition that is explicit, not assumed.
That last point is where most first implementations fail. We cover agentic loop anti-patterns in depth elsewhere; here we build the correct version from the start.
How does the agentic loop work in code?
The loop centres on inspecting stop_reason after every API call. When the value is "tool_use", you execute the requested tool and append the result. When it is "end_turn", you exit. Anything else is an error path.
import anthropicimport jsonclient = anthropic.Anthropic()def run_agent(system: str, tools: list[dict], initial_message: str) -> str:messages = [{"role": "user", "content": initial_message}]max_iterations = 20 # hard guard against runaway loopsfor _ in range(max_iterations):response = client.messages.create(model="claude-opus-4-5",max_tokens=4096,system=system,tools=tools,messages=messages,)# Append the assistant turnmessages.append({"role": "assistant", "content": response.content})if response.stop_reason == "end_turn":# Extract the final text blockfor block in response.content:if block.type == "text":return block.textreturn ""if response.stop_reason != "tool_use":raise RuntimeError(f"Unexpected stop_reason: {response.stop_reason}")# Execute every tool call in this turntool_results = []for block in response.content:if block.type == "tool_use":result = dispatch_tool(block.name, block.input)tool_results.append({"type": "tool_result","tool_use_id": block.id,"content": json.dumps(result),})messages.append({"role": "user", "content": tool_results})raise RuntimeError("Agent exceeded max_iterations without reaching end_turn")
The max_iterations guard is non-negotiable. Without it, a confused model can loop indefinitely, burning tokens and potentially taking unintended actions. Per Anthropic's guidance on agentic systems, prefer minimal footprint: request only necessary permissions and err on the side of doing less when uncertain.
Prefer reversible over irreversible actions, and err on the side of doing less and confirming with users when uncertain about intended scope in order to preserve human oversight and avoid making hard-to-fix mistakes.
Understanding stop_reason field inspection and tool result appending are two of the 30 task statements the CCA-F exam tests. The code above encodes both correctly.
How do you design tools that agents actually use correctly?
Tool descriptions are the primary selection mechanism. The model reads your description, not your implementation. A vague description produces misrouting; a precise one produces correct calls on the first attempt.
A minimal but effective tool definition looks like this:
{"name": "search_knowledge_base","description": "Full-text search over the internal product knowledge base. Use this when the user asks about product features, pricing, or support policies. Do NOT use for general web search or code execution.","input_schema": {"type": "object","properties": {"query": {"type": "string","description": "The search query, written as a natural-language question."},"max_results": {"type": "integer","description": "Maximum number of results to return. Default 5, max 20.","default": 5}},"required": ["query"]}}
Three rules that pay off immediately:
- State what the tool is for. Lead with the use-case, not the implementation.
- State what it is NOT for. Explicit exclusions prevent the model from reaching for the wrong tool when two tools overlap.
- Constrain the schema tightly. Enums, min/max values, and required fields reduce hallucinated inputs.
When you have too many tools in a single context, the model's accuracy drops. The tool overload problem is real: empirically, performance degrades as the available tool count grows. Scope tools to roles, not to the entire agent surface.
| Tool design mistake | Consequence | Fix |
|---|---|---|
| Vague description | Model picks the wrong tool | Add use-case and exclusion clauses |
| Overlapping names | Inconsistent routing | Split into narrower, named tools |
| Too many tools in one context | Accuracy degrades | Scope tools per subagent role |
| No schema constraints | Hallucinated inputs | Add enums, required fields, min/max |
| Missing error semantics | Silent failures | Return structured error with isError flag |
How should you manage context in a long-running agent?
Context is the resource most engineers underestimate. Every tool result you append grows the context window. After enough turns, two problems emerge: cost rises linearly, and the model's effective attention on early content weakens (the attention dilution problem).
The practical strategies, in order of preference:
1. Trim tool results before appending. If a tool returns 10,000 tokens of raw data and the agent needs three fields, extract those fields in your dispatch_tool function before appending. Never pass raw API responses verbatim.
2. Use summary injection for fresh sessions. When a task spans multiple sessions, end each session by asking the model to produce a structured summary, then inject that summary as the first user message of the next session. This is the summary injection for fresh sessions pattern.
SUMMARY_PROMPT = """Before we end this session, produce a JSON summary of:- completed_steps: list of actions taken and their outcomes- pending_steps: list of steps not yet completed- key_findings: facts discovered that the next session will need- open_questions: anything that needs human clarificationRespond with only the JSON object, no prose."""
3. Fork sessions for divergent exploration. When the agent needs to explore two incompatible hypotheses, fork the conversation rather than letting both branches pollute a single context. See fork_session for divergent exploration for the mechanics.
4. Set a context budget and monitor it. Track usage.input_tokens in every response. When you approach 80% of the model's context limit, trigger a compaction step rather than waiting for a context error.
CONTEXT_BUDGET = 180_000 # tokens, for claude-opus-4-5def should_compact(response) -> bool:return response.usage.input_tokens > CONTEXT_BUDGET * 0.8
When should a human step in?
Autonomous agents are not appropriate for every action. The CCA-F exam consistently rewards answers that apply proportionate human oversight: more autonomy for reversible, low-stakes actions; mandatory human approval for irreversible or high-stakes ones.
The structured handoff to human agents pattern formalises this. Rather than silently failing or guessing, the agent produces a structured handoff object and pauses.
HANDOFF_SCHEMA = {"type": "object","properties": {"reason": {"type": "string"},"action_proposed": {"type": "string"},"reversible": {"type": "boolean"},"data_needed_from_human": {"type": "array", "items": {"type": "string"}},"urgency": {"type": "string", "enum": ["low", "medium", "high"]}},"required": ["reason", "action_proposed", "reversible", "data_needed_from_human"]}
Three triggers that should always pause the agent and surface a handoff:
- The proposed action is irreversible (deleting records, sending external communications, deploying to production).
- The agent has reached a decision point not covered by its instructions.
- Confidence in the next action is low and the cost of a wrong action is high.
Two triggers that are tempting but unreliable: the model "feeling uncertain" (models can be confidently wrong) and elapsed time (time alone does not indicate a problem). Root the decision in action type and stakes, not in model-reported confidence.
How do you structure a multi-agent system?
Single agents handle single-concern tasks well. When a task has multiple concerns, a hub-and-spoke architecture separates coordination from execution cleanly.
The coordinator receives the user request, decomposes it into subtasks, dispatches subagents, and synthesises results. Each subagent receives only the context it needs (subagent context isolation keeps costs down and reduces cross-contamination of reasoning).
The coordinator's system prompt should be goal-based, not step-based. Tell it what a good outcome looks like, not which subagents to call in which order. Goal-based vs step-based prompts is a tested concept: step-based prompts break when the environment deviates from the assumed sequence; goal-based prompts adapt.
As of 3 June 2026, more than 10,000 individuals have earned the CCA-F certification, and Domain 1 (which covers all of the above) carries the highest exam weight at 27%. Investing time in these patterns pays off both in production systems and on the exam.
What does a production-ready agent checklist look like?
Before shipping any agent to production, verify each of the following:
| Check | Why it matters | Exam domain |
|---|---|---|
| Hard iteration cap in the loop | Prevents runaway cost and unintended actions | Domain 1 (27%) |
stop_reason inspection on every turn | Catches unexpected terminations early | Domain 1 (27%) |
| Tool results trimmed before appending | Controls context growth | Domain 5 (15%) |
| Structured error returns from all tools | Enables graceful recovery | Domain 2 (18%) |
| Human handoff for irreversible actions | Preserves oversight | Domain 1 (27%) |
| Context budget monitoring | Prevents silent context overflow | Domain 5 (15%) |
| Goal-based coordinator prompt | Resilience to environmental deviation | Domain 4 (20%) |
| Subagent context isolation | Cost control and reasoning clarity | Domain 1 (27%) |
In agentic contexts, Claude must apply particularly careful judgment about when to proceed versus when to pause and verify with the operator or user, since mistakes may be difficult to reverse, and could have downstream consequences within the same pipeline.
Our concept library at /concepts maps all 174 atomic concepts to the five exam domains and 30 task statements. If any of the patterns above feel unfamiliar, that is the right place to drill before sitting the CCA-F.
Where do you go from here?
The patterns in this tutorial cover the core of Domain 1 and touch Domains 2, 4, and 5. The next logical steps are:
- Tool design depth: Read the Tool Design and MCP Integration domain to understand MCP scoping, error propagation, and tool distribution strategy.
- Prompt engineering for agents: The Prompt Engineering and Structured Output domain covers how to write system prompts that produce reliable, parseable outputs from your agents.
- Context management advanced patterns: The Context Management and Reliability domain covers stale context, progressive summarisation traps, and session management scenario analysis.
The CCA-F exam launched on 12 March 2026 and costs $99 per attempt. It is scored on a 100-to-1000 scale with a passing mark of 720. The patterns in this tutorial are not exam trivia: they are the engineering decisions the exam's scenario-based questions are designed to probe.
Frequently asked questions
How do I stop a Claude agent from running forever?
What model should I use for a Claude agent?
How many tools can I give a Claude agent before performance drops?
Do I need a framework like LangChain or AutoGen to build a Claude agent?
How do I pass context between agent sessions without hitting the context limit?
Does building Claude agents help with the CCA-F exam?
People also ask
How do Claude agents work?
What is the difference between a Claude agent and a Claude chatbot?
How do I give a Claude agent access to tools?
How do Claude agents handle errors?
Can Claude agents run without human supervision?
About the author
AI Architect & Certification Lead
Solomon Udoh is an AI Architect who designs and ships production agent systems on the Claude API and Claude Code. He built AI Skill Certs' adaptive engine and authored its 174-concept knowledge graph, mapping every Claude Certified Architect - Foundations objective to hands-on, exam-aligned practice.
- Designs production multi-agent systems on the Claude API and Agent SDK
- Author of the AI Skill Certs knowledge graph (174 mapped exam concepts)
- Builds with MCP, Claude Code, structured outputs, and agentic loops daily
- Reviews every concept page against the official Anthropic exam guide
You might also like
Ready to put it into practice?
Study every exam concept with an adaptive tutor.