Agentic Architecture
Agent loops, Agent SDK, multi-agent patterns, task decomposition, and production architectures
Agent loops, Agent SDK, multi-agent patterns, task decomposition, and production architectures
An AI agent is fundamentally different from a chatbot or assistant. While a chatbot responds to messages, an agent thinks, acts, observes, and repeats until a task is complete. Agents have three defining properties that set them apart:
At its core, every agent runs a single-threaded master loop. This is the architecture behind Claude Code and the Claude Agent SDK. The loop is deceptively simple:
while True:
response = model.generate(messages)
if response.has_tool_calls():
for tool_call in response.tool_calls:
result = execute_tool(tool_call)
messages.append(tool_result(result))
else:
# Plain text response = task complete
return response.textEach iteration of the while loop is one "turn." The loop continues as long as the model returns tool calls. When the model returns plain text with no tool calls, it signals the task is done and the loop terminates.
THE AGENT LOOP
The Claude Agent SDK (available in Python and TypeScript) gives you the same agent loop, tool infrastructure, and context management that powers Claude Code. Key concepts:
from claude_code_sdk import Agent, Tool
# Define a tool
search_tool = Tool(
name="search_codebase",
description="Search for patterns in the codebase",
input_schema={"type": "object", "properties": {
"query": {"type": "string"}
}},
handler=search_handler
)
# Create and run the agent
agent = Agent(
system_prompt="You are a code review agent. Analyze code for bugs and suggest fixes.",
tools=[search_tool],
max_turns=20 # safety limit
)
result = await agent.run("Review the authentication module for security issues")Real-world tasks often exceed what a single agent can handle in one context window. Multi-agent architectures decompose work across specialized agents. The CCA exam tests all four patterns below.
The primary pattern tested on the CCA exam. A parent orchestrator agent decomposes a complex task, spawns focused subagents (each with fresh context and narrow tool access), and synthesizes their results into a final output.
ORCHESTRATOR-WORKER (HUB-AND-SPOKE)
# Orchestrator decomposes a code review task
subtasks = [
{"agent": "security_reviewer", "tools": ["Read", "Grep"], "scope": "auth/*.ts"},
{"agent": "perf_reviewer", "tools": ["Read", "Grep"], "scope": "api/*.ts"},
{"agent": "test_reviewer", "tools": ["Read", "Glob"], "scope": "tests/**"},
]
# Each subagent gets:
# 1. Fresh context (no shared state)
# 2. Restricted tool set (principle of least privilege)
# 3. Narrow scope (specific files/concerns)
results = await asyncio.gather(*[
spawn_subagent(task) for task in subtasks
])
# Orchestrator synthesizes
final_review = await orchestrator.synthesize(results)Sequential agents where each one processes the output of the previous. Each stage has a single responsibility and its own context. Use when your workflow has ordered dependencies.
PIPELINE PATTERN
Example: code generation โ code review โ test writing โ deployment validation
Multiple agents work simultaneously on independent tasks. Results are collected and merged by a coordinator. No inter-agent communication during execution.
When to use: Embarrassingly parallel work where subtasks have zero dependencies.
Example: Batch processing 50 files: each agent handles a subset independently, results merged at the end.
A generator agent produces output, then an evaluator agent scores and critiques it. The loop repeats until a quality threshold is met or max iterations are reached. The generator and evaluator are separate agents to prevent self-bias.
When to use: Quality-sensitive outputs where self-evaluation is insufficient.
Example: The RALPH pattern: generate code, run tests, review results, iterate until all tests pass.
for attempt in range(max_iterations):
output = await generator_agent.run(task + previous_feedback)
evaluation = await evaluator_agent.run(f"Score this output: {output}")
if evaluation.score >= quality_threshold:
return output # meets quality bar
previous_feedback = evaluation.critique
raise QualityError("Max iterations reached without meeting threshold")Decomposition is the art of breaking a complex task into agent-sized units. Good decomposition is the difference between a system that works and one that collapses under its own complexity.
Too granular: Spawning an agent per function/line creates massive overhead. Each agent spawn has latency and token cost. Group related work.
Too broad: A single agent handling the entire task defeats the purpose. Context overflow causes quality degradation. Split when context exceeds ~50% of the window.
Decision framework:If the subtask needs <2 tool calls, it is too small. If it needs >20 tool calls or >50k tokens of context, it is too large.
This is one of the most tested concepts on the CCA exam. When an orchestrator spawns a subagent, that subagent does notinherit the parent's conversation history. It starts with a clean slate: only the system prompt and the specific task description provided by the parent.
Why fresh context?
Implication: The parent must provide complete contextin the subagent prompt. You cannot assume the subagent "knows" anything from the parent conversation.
Since subagents have isolated contexts, communication must be explicit. There are four primary patterns:
Simplest pattern. Subagent returns a string/object to the orchestrator. The orchestrator reads the result and decides what to do next. Works for small-to-medium outputs.
Agents read/write to agreed-upon file paths. Useful for large artifacts (generated code, data files). Requires clear naming conventions to avoid conflicts.
A shared TODO list or task queue. Agents claim tasks, mark completion, and write results. Good for coordinated work where order matters.
Direct inter-agent messaging via tools like SendMessage in Claude Code. Enables real-time coordination but adds complexity. Use when agents need to negotiate.
Agents reason about when and how to use tools based on tool descriptions. Well-described tools are critical. Poorly described tools lead to misuse or non-use.
TOOL PROFILES BY AGENT ROLE
| Agent Role | Allowed Tools | Rationale |
|---|---|---|
| Read-only Analyst | Read, Grep, Glob | Cannot modify anything. Safe for untrusted analysis tasks. |
| Write Agent | Read, Write, Edit, Bash | Full file manipulation. Use for code generation and modification. |
| Research Agent | Read, Grep, Glob, WebFetch, WebSearch | Broad information gathering without write access. |
| CI/CD Agent | Bash, Read | Runs commands and reads output. Cannot directly edit source files. |
The allowedTools field is not a suggestion or naming convention. It is a physical restriction enforced by the runtime. If a tool is not in the allowed list, the agent literally cannot call it, regardless of what the system prompt says. This is the primary mechanism for implementing least-privilege in multi-agent systems.
Agents fail. Tools throw exceptions, context windows overflow, and loops run forever if unchecked. Robust error handling separates production agents from demos.
async def reliable_agent_call(agent, task, max_retries=3):
for attempt in range(max_retries):
try:
result = await agent.run(task, max_turns=25)
return result
except ToolExecutionError as e:
wait = 2 ** attempt # 1s, 2s, 4s
await asyncio.sleep(wait)
task += f"\nPrevious attempt failed: {e}. Try a different approach."
# Graceful degradation
return FallbackResult(error="Agent failed after retries", partial=last_result)Well-designed agents signal uncertainty. Instead of silently producing low-quality output, they should include confidence metadata in their responses: "I found 3 definite bugs and 2 possible issues that need human review." This enables the orchestrator to make informed decisions about whether to accept, retry, or escalate.
Handoffs occur when work transitions between agents, or between an agent and a human. Poorly managed handoffs lose context and degrade quality.
When handing off to another agent, include a structured summary: what was attempted, what succeeded, what failed, and what remains. Raw conversation history is too noisy; distill it.
Insert approval gates at critical decision points. The agent proposes an action, pauses, and waits for human confirmation before proceeding. Essential for destructive or irreversible operations.
Agents should detect when they are out of their depth (repeated failures, low confidence, ambiguous requirements) and escalate to supervised mode. This is a sign of good design, not failure.
Long-running agent tasks need session persistence. Without it, a network hiccup or terminal close loses all progress.
Effective agents do not jump straight to execution. They plan first, then execute against that plan. This is the difference between a brittle script and an intelligent agent.
The agent first reads the codebase (explore), designs an approach, presents the plan for approval, then executes. This prevents wasted work on wrong approaches.
For multi-step work, agents maintain a TODO list. Each step is checked off as completed. This provides progress visibility and ensures nothing is skipped.
The model reasons step-by-step before deciding on an action. This is implicit in most agent systems but can be made explicit with prompting strategies.
For high-stakes decisions (architecture changes, security-sensitive code), invoke extended thinking to give the model more compute budget for reasoning before acting.
Agents that can execute arbitrary tools on your machine need robust safety mechanisms. This is not optional โ it is a core architectural concern.
The CCA exam presents real-world scenarios and asks you to select the right architecture, tool set, and error handling strategy. Here are the key patterns:
Architecture: Single agent with tool access to knowledge base, ticket system, and escalation API
Tools: SearchKB, ReadTicket, UpdateTicket, EscalateToHuman
Error handling: If confidence < threshold, escalate to human. Never auto-resolve ambiguous issues. Log all actions for audit.
Architecture: Orchestrator-Worker: parent decomposes research question into sub-queries, each handled by a specialist agent
Tools: Orchestrator: spawn_agent. Workers: WebSearch, WebFetch, Read, Summarize
Error handling: Workers return partial results on failure. Orchestrator synthesizes available data and notes gaps.
Architecture: Pipeline: plan -> generate -> test -> review. Or Hub-and-spoke for large codebases.
Tools: Read, Write, Edit, Bash, Glob, Grep
Error handling: Build/test failures trigger retry loop. Max 3 attempts before requesting human guidance.
Architecture: Single agent with broad tool access, operating in supervised mode with human approval gates
Tools: Read, Write, Edit, Bash, Grep, Glob, Git operations
Error handling: Destructive operations (force push, file deletion) require explicit approval. Session resume for long tasks.
Hub-and-spoke is the primary multi-agent pattern. The orchestrator-worker model is the most commonly tested pattern. Know how the orchestrator decomposes tasks, how subagents receive context, and how results are synthesized.
Context isolation is a core principle.Each subagent starts with fresh context. It does NOT inherit the parent's conversation. The parent must explicitly provide all necessary context in the subagent prompt.
Tool restrictions are PHYSICAL constraints. TheallowedTools field is enforced by the runtime, not the prompt. An agent physically cannot call a tool not in its allowed list. This is the mechanism for least-privilege.
Know all 4 multi-agent patterns. Orchestrator-Worker, Pipeline, Parallel Fan-Out, and Evaluator-Optimizer. For each, know when to use it, its strengths, and its failure modes.
Error propagation in multi-agent chains. When a subagent fails, how does the orchestrator handle it? Retry, skip, escalate? The exam tests your understanding of fault tolerance in distributed agent systems.
The agent loop terminates on plain text. The while loop continues while tool_use blocks are returned. Plain text with no tool calls signals completion. This is fundamental to how every agent works.
max_turns is the primary safety mechanism. Without it, a confused agent loops forever. Always set a reasonable limit. For most tasks, 20-50 turns is sufficient.
Agentic Architecture & Orchestration is 27% of the CCA exam โ the largest domain. Master the agent loop, multi-agent patterns (especially orchestrator-worker), context isolation, tool restrictions, and error handling. These concepts appear in nearly every exam scenario.