Designing Your Agent System
Jump to section
Separation of Concerns for AI Agents
The biggest mistake teams make with AI tools is treating every task the same: open Claude Code, describe what you want, and let it figure everything out. This works for small tasks but falls apart on anything complex. The AI tries to plan, implement, test, and review all at once — and the quality of each step suffers.
The solution is the same principle you apply to human teams: separation of concerns. Different agents specialize in different tasks. An architect plans but never writes code. A developer implements but never diagnoses root causes. A runner executes commands but never makes decisions. A reviewer checks quality but never fixes issues directly.
The Four Agent Roles
1. Architect
The architect analyzes requirements, breaks down tickets, decides which repos to touch, and creates implementation plans. It never writes production code — only plans. This is critical: when an AI tries to plan and implement simultaneously, the plan is often incomplete because the AI rushes to start coding.
---
name: Backend Architect
description: |
Plans backend changes for the Django API. Analyzes tickets,
breaks them into implementation steps, identifies affected files,
and writes detailed plans. NEVER implements — only plans.
model: opus
---
# Backend Architect
You are the backend architect for our Django + Ninja API.
## Your Role
- Analyze feature requests and bug reports
- Break tickets into concrete implementation steps
- Identify which files need changes and what changes
- Write implementation plans that a developer agent can follow
- Flag risks, dependencies, and edge cases
## Rules
- NEVER write production code. Your output is ONLY plans.
- NEVER make assumptions about existing code — always read files first.
- Always check for existing patterns before proposing new ones.
- Include test requirements in every plan.
## Output Format
For each implementation step:
1. File to modify (full path)
2. What to change (specific, not vague)
3. Why (reasoning)
4. Test coverage needed2. Developer
The developer takes a plan and implements it. It writes code, creates files, modifies existing code. It follows the plan strictly — if something does not make sense, it stops and asks rather than improvising. The developer never diagnoses problems or changes the plan.
---
name: Backend Developer
description: |
Implements backend changes following architect plans.
Writes Django code, creates endpoints, models, tests.
Follows plans strictly — escalates if plan is unclear.
model: sonnet
---
# Backend Developer
You are the backend developer. You implement changes
following plans created by the architect.
## Your Role
- Implement code changes as specified in the plan
- Write clean, tested code following project conventions
- Run tests after implementation
- Report results back
## Rules
- FOLLOW THE PLAN. Do not deviate.
- If the plan is unclear or seems wrong, STOP and report back.
Do not guess or improvise.
- NEVER diagnose bugs. If tests fail, report the failure.
The architect will analyze and provide a fix plan.
- Always run the test suite after changes.
## Conventions (from AGENTS.md)
- Django apps under apps/
- One file per endpoint group in api/
- Pydantic schemas in api/schemas.py
- Tests mirror app structure in tests/3. Runner
Runners execute specific commands and report output. They are stateless — they do not remember previous runs, do not make decisions, and do not interpret results. They are glorified shell scripts with AI reading the output. Use them for deployments, migrations, environment setup.
---
name: Test Runner
description: |
Runs test suites and reports results. Does not fix failures —
only reports them with full output.
model: sonnet
---
# Test Runner
You run tests and report results. Nothing more.
## Commands
- Backend: cd repos/backend && uv run pytest -x -v
- Frontend: cd repos/frontend && npm test
- Infra: cd repos/infra && terraform validate
## Rules
- Run the requested test suite
- Report: PASS/FAIL, number of tests, failure details
- NEVER fix code. NEVER modify files.
- NEVER interpret why tests failed — just report the output.4. Reviewer
The reviewer examines code changes and checks for quality issues. It looks at the diff, checks for common mistakes, verifies test coverage, and provides feedback. It never fixes issues — it creates a list of findings that go back to the architect for planning.
---
name: Code Reviewer
description: |
Reviews code changes across repos. Checks for bugs,
security issues, missing tests, and convention violations.
Reports findings — never fixes directly.
model: opus
---
# Code Reviewer
You review code changes for quality and correctness.
## Checklist
- [ ] No N+1 queries (check for select_related/prefetch_related)
- [ ] All new endpoints have tests (success + error cases)
- [ ] No hardcoded secrets or credentials
- [ ] Error handling follows project patterns
- [ ] API schemas match between backend and frontend
- [ ] Database migrations are reversible
- [ ] No unused imports or dead code
## Rules
- NEVER fix code. Create a findings list.
- Rate each finding: CRITICAL / WARNING / SUGGESTION
- For each finding: file, line, issue, recommendation
- If everything looks good, say so explicitly.Model Selection Strategy
Not every agent needs the most powerful model. Use Opus (or the strongest available model) for tasks requiring deep reasoning: architecture, review, debugging root cause analysis. Use Sonnet (or mid-tier models) for implementation tasks where the plan is already clear.
- Opus: Architects, Reviewers, Solution Architects — tasks requiring analysis and judgment
- Sonnet: Developers, Runners, Test Writers — tasks following clear plans or executing commands
- Haiku: Simple runners, formatting, data extraction — tasks with no ambiguity
This is not about cost savings (though that helps). Sonnet models are faster than Opus. For implementation tasks where the plan is clear, faster execution means faster feedback loops. Use the right tool for the job.
The Key Discipline: No Role Crossing
The most important rule in the agent system: agents must never cross role boundaries. When a developer encounters a failing test, the instinct is to debug it. But debugging requires diagnosis — understanding why something fails — which is architecture work. If the developer starts diagnosing, it will often apply a surface-level fix that hides the real problem.
The correct flow: developer reports the failure, architect analyzes root cause, architect writes a fix plan, developer implements the fix. This seems slower but produces much better results because each step uses the right model and the right specialization.
# Error Recovery Flow
1. Developer implements feature per plan
2. Tests fail
3. Developer reports: "Tests X, Y, Z failed. Output: [full output]"
4. Architect analyzes: reads test output, reads code, identifies root cause
5. Architect writes fix plan: "Change file A line 42, because..."
6. Developer implements fix
7. Tests pass -> proceed to review
# WRONG flow (common mistake):
1. Developer implements feature
2. Tests fail
3. Developer tries to fix tests
4. Developer introduces new bug while fixing
5. More tests fail
6. Developer is now deep in a debugging rabbit hole
7. Context is polluted, quality dropsAgent Registry in AGENTS.md
Every agent must be registered in AGENTS.md so the workspace knows what is available. The registry includes the agent name, file path, model, and a one-line description of its role.
## Agents
| Agent | File | Model | Role |
|-------|------|-------|------|
| Solution Architect | .claude/agents/solution-architect.md | opus | Cross-repo feature planning |
| Backend Architect | .claude/agents/backend-architect.md | opus | Django API planning |
| Backend Developer | .claude/agents/backend-dev.md | sonnet | Django implementation |
| Frontend Architect | .claude/agents/frontend-architect.md | opus | Next.js planning |
| Frontend Developer | .claude/agents/frontend-dev.md | sonnet | Next.js implementation |
| Infra Engineer | .claude/agents/infra-eng.md | sonnet | Terraform + k8s |
| Test Runner | .claude/agents/test-runner.md | sonnet | Execute test suites |
| Code Reviewer | .claude/agents/reviewer.md | opus | Quality review |
| Deploy Runner | .claude/agents/deploy-runner.md | sonnet | Execute deployments |Agent File Format
Each agent is a Markdown file with YAML frontmatter. The frontmatter provides metadata that tools can parse programmatically. The body provides the system prompt — the instructions the AI follows when acting as that agent.
---
name: Agent Name
description: One paragraph describing what this agent does
model: opus | sonnet | haiku
---
# Agent Name
## Your Role
[What you do and do not do]
## Rules
[Hard constraints — NEVER/ALWAYS]
## Conventions
[Project-specific patterns to follow]
## Output Format
[How to structure responses]Keep agent definitions focused. A common mistake is writing a 500-line agent definition that tries to cover every scenario. Start with 30-50 lines that define the core role, key rules, and output format. Add specifics only when you encounter recurring issues.
Create 4 agent definitions for your team's primary repo: 1. An Architect agent (model: opus) — plans changes, never implements 2. A Developer agent (model: sonnet) — implements plans, never diagnoses 3. A Runner agent (model: sonnet) — executes commands, never decides 4. A Reviewer agent (model: opus) — checks quality, never fixes For each agent, write the YAML frontmatter and the core prompt (role, rules, conventions). Place them in .claude/agents/ in your workspace. Register all four in your AGENTS.md.
Hint
Start with the conventions from your actual codebase: file structure, naming patterns, testing requirements. The more specific the conventions, the better the agent performs.
Open Claude Code and invoke your Developer agent. Give it a task that intentionally has a subtle bug in the plan. For example: 'Implement this endpoint but use the wrong model name.' Watch whether the developer catches the issue and reports it, or silently implements wrong code. Iterate on your agent definition until it reliably stops and reports plan issues instead of blindly implementing.
Hint
Add a specific rule like: 'If any referenced file, model, or function does not exist, STOP and report the discrepancy. Do not create missing entities without architect approval.'
- Four agent roles: Architect (plans), Developer (implements), Runner (executes), Reviewer (checks)
- Agents must never cross role boundaries — developers do not diagnose, architects do not implement
- Use Opus for reasoning tasks (architecture, review), Sonnet for implementation tasks
- Error recovery always flows back through the architect for root cause analysis
- Agent definitions are Markdown files with YAML frontmatter, registered in AGENTS.md
In the next lesson, we dive into Skills and Development Pipelines — a technique that gives you a clear edge. Unlock the full course and continue now.
2/8 complete — keep going!