Agents
Agents are the building blocks of agentful - specialized AI workers, each with a specific domain of expertise, well-defined responsibilities, and clear boundaries. They don't just "write code" - they follow patterns, enforce standards, and collaborate through the orchestrator.
What Are Agents?
An agent is defined by:
- Name - Unique identifier (e.g.,
backend,frontend,tester) - Description - What it does, what it doesn't do
- Model - Which AI model powers it (Sonnet for specialists, Opus for coordinators)
- Tools - What it can access (Read, Write, Edit, Bash, Task, etc.)
- Scope - What it's responsible for
- Patterns - How it implements features
Here's a typical agent definition:
---
name: backend
description: Implements backend services, repositories, controllers, APIs. Never modifies frontend code.
model: sonnet
tools: Read, Write, Edit, Glob, Grep, Bash
---
# Backend Agent
You are the **Backend Agent**. You implement server-side code using clean architecture patterns.
## Your Scope
- API Routes & Controllers
- Service Layer
- Repository Layer
- Database schemas
- Authentication
## NOT Your Scope
- UI components → @frontend
- Tests → @tester
- Code review → @reviewerWhy Multiple Agents?
The Problem with "Do Everything" AI
A single AI agent that tries to do everything suffers from:
- Context confusion - Frontend patterns mixed with backend patterns
- Quality inconsistency - Different standards for different domains
- Validation complexity - Hard to enforce domain-specific rules
- Scalability limits - Can't specialize in every framework
The agentful Solution
Specialization = QualityEach agent:
- Knows its domain deeply
- Follows consistent patterns
- Enforces domain-specific rules
- Stays within its boundaries
The Seven Core Agents
1. Orchestrator Agent
The conductor that never plays an instrumentRole: Coordinate all work
Model: Opus (most capable)
Tools: Read, Write, Edit, Glob, Grep, Task, AskUserQuestion, TodoWrite- Read
PRODUCT.mdto understand what we're building - Track progress in
.agentful/completion.json - Read state from
.agentful/state.json - Delegate ALL implementation to specialist agents
- Ensure validation happens after every change
- Block on user decisions when needed
- Write code directly
- Skip validation
- Make assumptions about user preferences
Task("backend", "Implement JWT authentication service per PRODUCT.md section 3")
Task("reviewer", "Review all authentication changes")
Task("tester", "Write tests for authentication module")2. Architect Agent
The tech stack analystRole: Analyze tech stack and generate specialized agents
Model: Opus
Tools: Read, Write, Edit, Glob, Grep, Task- Read
PRODUCT.mdto identify the tech stack - Generate specialized agents for languages/frameworks
- Update existing agents with tech-specific patterns
- Create
.agentful/architecture.jsondocumenting decisions
{
"detected_stack": {
"frontend": {
"framework": "Next.js",
"version": "14",
"language": "TypeScript"
},
"database": {
"provider": "PostgreSQL",
"orm": "Prisma"
}
},
"generated_agents": [
"nextjs-agent",
"prisma-agent"
]
}3. Backend Agent
Server-side specialistRole: Implement services, repositories, APIs, databases
Model: Sonnet
Tools: Read, Write, Edit, Glob, Grep, Bash- API Routes & Controllers
- Service Layer (business logic)
- Repository Layer (data access)
- Database schemas and migrations
- Authentication (JWT, sessions, OAuth)
- Input validation with Zod
- Error handling
- UI components →
@frontend - Tests →
@tester - Code review →
@reviewer
// Repository Layer
export class UserRepository {
async findById(id: string): Promise<User | null> {
return db.user.findUnique({ where: { id } });
}
}
// Service Layer
export class UserService {
constructor(private repo: UserRepository) {}
async registerUser(input: RegisterInput): Promise<User> {
const existing = await this.repo.findByEmail(input.email);
if (existing) throw new ConflictError('User already exists');
return this.repo.create(input);
}
}
// Controller/Route
export async function POST(req: Request) {
const body = await req.json();
const service = new UserService(new UserRepository());
const user = await service.registerUser(body);
return Response.json(user, { status: 201 });
}4. Frontend Agent
UI and client-side specialistRole: Implement components, pages, hooks, styling
Model: Sonnet
Tools: Read, Write, Edit, Glob, Grep, Bash- UI Components (reusable component library)
- Pages (route pages and views)
- Custom React hooks
- State management (Context, Zustand, Redux)
- Form handling and validation
- Styling (Tailwind, CSS Modules, styled-components)
- Client-side logic and interactions
- Backend API routes →
@backend - Database operations →
@backend - Tests →
@tester
// Component
export interface ButtonProps {
variant?: 'primary' | 'secondary' | 'danger';
size?: 'sm' | 'md' | 'lg';
isLoading?: boolean;
}
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
({ children, variant = 'primary', size = 'md', isLoading, ...props }, ref) => {
const baseStyles = 'rounded-lg font-medium transition-colors';
const variants = {
primary: 'bg-blue-600 text-white hover:bg-blue-700',
secondary: 'bg-gray-200 text-gray-900 hover:bg-gray-300',
};
return (
<button
ref={ref}
disabled={isLoading}
className={`${baseStyles} ${variants[variant]}`}
{...props}
>
{isLoading ? 'Loading...' : children}
</button>
);
}
);
// Custom Hook
export function useAuth() {
const [user, setUser] = useState<User | null>(null);
const [isLoading, setIsLoading] = useState(true);
useEffect(() => {
fetch('/api/auth/me')
.then(res => res.json())
.then(data => setUser(data.user))
.finally(() => setIsLoading(false));
}, []);
return { user, isLoading };
}5. Tester Agent
Quality assurance specialistRole: Write comprehensive unit, integration, and E2E tests
Model: Sonnet
Tools: Read, Write, Edit, Glob, Grep, Bash- Unit Tests (functions, components, services)
- Integration Tests (module interactions)
- E2E Tests (full user flows)
- Test fixtures (setup, teardown, mocks)
- Coverage reports and improvement
Target: 80% coverage threshold
Implementation pattern:describe('UserService', () => {
let service: UserService;
let mockRepo: UserRepository;
beforeEach(() => {
mockRepo = {
findByEmail: vi.fn(),
create: vi.fn(),
} as any;
service = new UserService(mockRepo);
});
it('should create a new user with hashed password', async () => {
const input = {
email: 'test@example.com',
password: 'password123',
};
mockRepo.findByEmail = vi.fn().mockResolvedValue(null);
mockRepo.create = vi.fn().mockResolvedValue({
id: '1',
email: input.email,
});
const result = await service.registerUser(input);
expect(mockRepo.findByEmail).toHaveBeenCalledWith(input.email);
expect(result.email).toBe(input.email);
});
it('should throw error if user already exists', async () => {
mockRepo.findByEmail = vi.fn().mockResolvedValue({ id: '1' });
await expect(service.registerUser(input)).rejects.toThrow('User already exists');
});
});6. Reviewer Agent
Code quality enforcerRole: Review code, find dead code, validate production readiness
Model: Sonnet
Tools: Read, Glob, Grep, Bash, Write, Edit- TypeScript Check -
npx tsc --noEmit - Lint Check -
npm run lint - Dead Code Detection - Find unused exports, files, imports
- Test Check -
npm test - Coverage Check - Verify ≥ 80% coverage
- Security Check - Scan for secrets, vulnerabilities, debug logs
- Manual Code Review - Error handling, patterns, best practices
- Console Log Check - Find debug statements
{
"passed": false,
"checks": {
"typescript": { "passed": true },
"lint": { "passed": true },
"deadCode": {
"passed": false,
"issues": [
"Unused export: formatDate in src/utils/date.ts",
"Unused file: src/components/OldWidget.tsx"
]
},
"tests": { "passed": true },
"coverage": {
"passed": false,
"actual": 72,
"required": 80
},
"security": {
"passed": false,
"issues": [
"console.log in src/auth/login.ts:45"
]
}
},
"mustFix": [
"Remove unused export formatDate from src/utils/date.ts",
"Delete unused file src/components/OldWidget.tsx",
"Add tests to reach 80% coverage (currently at 72%)",
"Remove console.log from src/auth/login.ts:45"
]
}7. Fixer Agent
Auto-fixer for validation failuresRole: Automatically fix validation failures identified by reviewer
Model: Sonnet
Tools: Read, Write, Edit, Glob, Grep, Bash- Dead code (unused exports, files, imports)
- Missing tests (adds tests to reach 80%)
- Console.log statements
- Hardcoded secrets
- Type errors
- Lint errors
- Comment out code (removes it)
- Add
@ts-ignoreto silence errors - Leave
// TODO: fix thiscomments - Make partial fixes
// Before (dead code)
export function formatDate(date: Date): string { // ❌ Unused
return date.toISOString();
}
export function parseDate(str: string): Date { // ✅ Used
return new Date(str);
}
// After - Fixer deletes unused function entirely
export function parseDate(str: string): Date {
return new Date(str);
}Agent Collaboration
How Agents Work Together
┌─────────────────────────────────────────────────────────────┐
│ User │
│ "Build auth" │
└────────────────────────┬────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Orchestrator │
│ "I'll coordinate, not implement" │
└─────────┬───────────────────────────────────────────────────┘
│
├──► Architect: "Analyze tech stack"
│ └──► Generates nextjs-agent, prisma-agent
│
├──► Backend: "Implement JWT service"
│ └──► Creates auth.service.ts
│
├──► Frontend: "Create login page"
│ └──► Creates login-form.tsx
│
├──► Tester: "Write auth tests"
│ └──► Creates auth.test.ts (target: 80%)
│
├──► Reviewer: "Check everything"
│ └──► Finds: console.log, unused import
│
└──► Fixer: "Fix the issues"
└──► Removes console.log, unused import
└──► Reviewer: "All checks passed ✅"
└──► Orchestrator: "Update completion.json"Communication Protocol
Agents never communicate directly. All communication flows through:
- State files -
.agentful/state.json,.agentful/completion.json - The orchestrator - Delegates via Task tool
- Artifacts - Code, tests, documentation
Example:
// Orchestrator delegates to backend
Task("backend", "Implement JWT authentication per PRODUCT.md")
// Backend completes and reports
// "Created auth.service.ts, login route, user repository"
// Orchestrator then delegates to reviewer
Task("reviewer", "Review all authentication changes")
// Reviewer reports issues to state file
// .agentful/last-review.json
// Orchestrator delegates to fixer
Task("fixer", "Fix issues from last-review.json")Agent Boundaries
Clear Scope Separation
Each agent has explicit boundaries:
// Backend Agent - What it DOES
export class UserService {
// ✅ Service layer logic
async registerUser(input: RegisterInput): Promise<User> {
const existing = await this.repo.findByEmail(input.email);
if (existing) throw new ConflictError('User already exists');
return this.repo.create(input);
}
}
// Backend Agent - What it NEVER does
// ❌ Don't create UI components
// export function LoginForm() { ... }
// ❌ Don't write tests
// describe('UserService', () => { ... });
// ❌ Don't review code
// npx tsc --noEmitBoundary Enforcement
Boundaries are enforced by:
- Agent instructions - Explicitly stated in agent definition
- Orchestrator delegation - Right agent for right task
- Reviewer validation - Checks for scope violations
- Tool limitations - Frontend agent doesn't get Bash for API routes
Why This Architecture Works
1. Focus = Quality
Each agent focuses on one domain:
- Backend agent knows backend patterns deeply
- Frontend agent knows UI patterns deeply
- Tester agent knows testing strategies deeply
2. Parallel Work
Multiple agents can work simultaneously:
Orchestrator → Backend: "Build user API"
→ Frontend: "Build user profile UI"
→ Tester: "Write tests for previous feature"3. Easy Debugging
When something goes wrong:
- Know exactly which agent was responsible
- Check agent's specific rules and patterns
- Fix that agent without affecting others
4. Scalability
Need support for a new framework?
- Architect generates a new specialized agent
- Existing agents continue unchanged
- Orchestrator can delegate to new agent
Creating Custom Agents
You can add your own agents in .claude/agents/:
---
name: mobile
description: Implements React Native mobile components and navigation
model: sonnet
tools: Read, Write, Edit, Glob, Grep, Bash
---
# Mobile Agent
You are the **Mobile Agent**. You implement React Native applications.
## Your Scope
- React Native components
- Navigation (React Navigation)
- Native modules
- Mobile-specific patterns
## NOT Your Scope
- Web UI → @frontend
- Backend APIs → @backendThe orchestrator will automatically discover and use your custom agent.
Summary
Agents are agentful's fundamental building blocks:
- Specialized - Each has a specific domain
- Collaborative - Work together through orchestrator
- Boundaried - Clear scopes and responsibilities
- Scalable - Easy to add new agents
- Quality-focused - Enforce patterns and standards