This guide explains how to customize and extend Auto Code's agent system. You'll learn how to modify agent behavior, create custom agents, and integrate them into your workflow.
- Understanding Agents
- Agent Architecture
- Modifying Agent Prompts
- Creating Custom Agents
- Agent Testing
- Best Practices
- Advanced Patterns
Auto Code uses a multi-agent system where each agent has a specific role in the development process. Agents are powered by the Claude Agent SDK and use system prompts to define their behavior.
| Agent | Prompt File | Role | When Used |
|---|---|---|---|
| Planner | planner.md |
Creates implementation plans | Start of each spec |
| Coder | coder.md |
Implements subtasks | Main development phase |
| Coder Recovery | coder_recovery.md |
Handles stuck states | When coder fails |
| QA Reviewer | qa_reviewer.md |
Validates acceptance criteria | After implementation |
| QA Fixer | qa_fixer.md |
Fixes QA issues | In QA loop |
| Agent | Prompt File | Role | When Used |
|---|---|---|---|
| Spec Gatherer | spec_gatherer.md |
Collects requirements | Spec creation phase |
| Spec Researcher | spec_researcher.md |
Validates external integrations | Research phase |
| Spec Writer | spec_writer.md |
Creates spec documents | Writing phase |
| Spec Critic | spec_critic.md |
Refines specs | Critique phase |
| Complexity Assessor | complexity_assessor.md |
Determines task complexity | Start of spec creation |
| Agent | Prompt File | Role |
|---|---|---|
| Code Improvements | ideation_code_improvements.md |
Suggests code enhancements |
| Code Quality | ideation_code_quality.md |
Improves code quality |
| Performance | ideation_performance.md |
Optimizes performance |
| Security | ideation_security.md |
Finds security issues |
| UI/UX | ideation_ui_ux.md |
Improves user experience |
- Prompt Loading: System prompts are loaded from
apps/backend/prompts/ - Session Creation: Agent creates a Claude SDK session with the prompt
- Tool Access: Agents receive tools based on their role (planner, coder, qa_reviewer, qa_fixer)
- Execution: Agent processes tasks and produces outputs
- Memory Storage: Session insights are stored in Graphiti for future context
apps/backend/
├── prompts/ # System prompts for all agents
│ ├── planner.md
│ ├── coder.md
│ ├── qa_reviewer.md
│ └── ...
├── agents/ # Agent implementations
│ ├── planner.py # Planner agent logic
│ ├── coder.py # Coder agent logic
│ └── session.py # Session management
└── core/
└── client.py # Claude SDK client factory
# Simplified agent execution flow
from core.client import create_client
# 1. Create SDK client with agent-specific configuration
client = create_client(
project_dir=project_dir,
spec_dir=spec_dir,
model="claude-sonnet-4-5-20250929",
agent_type="coder" # Determines tool permissions
)
# 2. Load system prompt
with open("apps/backend/prompts/coder.md") as f:
system_prompt = f.read()
# 3. Create agent session
response = client.create_agent_session(
name="coder-session",
starting_message="Implement the authentication feature"
)
# 4. Process response and update memoryThe simplest way to customize agent behavior is to modify existing system prompts.
All prompts live in apps/backend/prompts/:
# List all agent prompts
ls -la apps/backend/prompts/
# Read a specific prompt
cat apps/backend/prompts/coder.mdEach prompt follows this structure:
## YOUR ROLE - AGENT NAME
Brief description of the agent's purpose.
---
## Core Principles
- Principle 1
- Principle 2
---
## Phase 1: Understanding Context
Instructions for how to read and understand the task...
---
## Phase 2: Execution
Instructions for the main work...
---
## Phase 3: Output
Instructions for how to produce results...File: apps/backend/prompts/coder.md
Add this section after the role definition:
## Coding Standards
**MANDATORY**: All code must follow these standards:
### Python Code
- Follow PEP 8 style guide
- Use type hints for all function parameters
- Add docstrings to all classes and functions
- Maximum line length: 100 characters
### TypeScript/JavaScript Code
- Use TypeScript strict mode
- Avoid `any` types
- Add JSDoc comments to exported functions
- Use ESLint with the project's configuration
### Testing
- Write unit tests for all new functions
- Aim for 80%+ code coverage
- Use descriptive test names that explain what is being tested
### Documentation
- Update README.md for user-facing changes
- Add inline comments for complex logic
- Document API endpoints in OpenAPI/Swagger formatFile: apps/backend/prompts/qa_reviewer.md
Add to the verification checklist:
## Additional Verification Checklist
### Code Quality
- [ ] Code follows project coding standards
- [ ] No TODO or FIXME comments left in production code
- [ ] All functions have descriptive names
- [ ] Error handling is implemented where needed
### Documentation
- [ ] README.md updated if needed
- [ ] API documentation updated for endpoints
- [ ] Database migrations documented
### Performance
- [ ] No N+1 query problems
- [ ] Caching implemented where appropriate
- [ ] Database queries optimizedFile: apps/backend/prompts/planner.md
Add project-specific service detection:
## Project-Specific Service Patterns
When creating implementation plans, follow these patterns:
### Frontend Changes
- Use `src/components/` for React components
- Use `src/services/` for API calls
- Use `src/hooks/` for custom React hooks
- Always create TypeScript interfaces for data structures
### Backend Changes
- Use `apps/backend/api/` for FastAPI endpoints
- Use `apps/backend/models/` for database models
- Use `apps/backend/services/` for business logic
- Always add validation with Pydantic
### Database Changes
- Create migration files in `apps/backend/migrations/`
- Update models in `apps/backend/models/`
- Add seed data in `apps/backend/seeds/`-
Make a backup:
cp apps/backend/prompts/coder.md apps/backend/prompts/coder.md.backup
-
Edit the prompt:
nano apps/backend/prompts/coder.md
-
Test on a simple spec:
cd apps/backend python spec_runner.py --task "Add a simple hello world function" --complexity simple
-
Review the output:
- Check if agents follow your new standards
- Verify code quality meets expectations
- Adjust prompt if needed
-
Restore from backup if issues occur:
cp apps/backend/prompts/coder.md.backup apps/backend/prompts/coder.md
For specialized workflows, you can create entirely new agents.
Consider a custom agent when:
- You need specialized expertise not covered by existing agents
- Your workflow requires multiple custom passes
- You want to integrate external tools or APIs
- You need to enforce project-specific conventions
Create a new prompt file in apps/backend/prompts/:
# Example: Performance optimization specialist
touch apps/backend/prompts/optimizer.mdExample prompt content:
## YOUR ROLE - PERFORMANCE OPTIMIZER AGENT
You are a performance optimization specialist. Your role is to analyze code for performance bottlenecks and implement optimizations while maintaining functionality.
---
## Optimization Principles
1. **Profile Before Optimizing**: Never optimize without measurements
2. **Prioritize User-Facing Improvements**: Focus on what users experience
3. **Document Trade-offs**: Explain why an optimization was chosen
4. **Avoid Premature Optimization**: Optimize only when there's a measured problem
---
## Analysis Process
### 1. Identify Performance Issues
Look for:
- N+1 query problems
- Inefficient database queries
- Unnecessary loops or computations
- Missing caching opportunities
- Large payload transfers
- Unoptimized rendering (for frontend)
### 2. Measure Impact
```bash
# Profile the code
python -m cProfile -o profile.stats your_script.py
python -m pstats profile.stats
# Check query performance
EXPLAIN ANALYZE SELECT ...For each issue, provide:
- Current performance: Baseline measurements
- Proposed optimization: What to change
- Expected improvement: Quantified impact
- Trade-offs: Any downsides (complexity, readability, etc.)
- Add indexes to frequently queried columns
- Use select_related/prefetch_related (Django) or similar
- Implement query result caching
- Optimize complex joins
- Add Redis caching for expensive operations
- Implement HTTP caching headers
- Use memoization for pure functions
- Cache computed results
- Replace O(n²) algorithms with O(n log n)
- Use generators instead of lists for large datasets
- Implement lazy loading
- Optimize hot paths
- Implement virtual scrolling for long lists
- Add pagination to reduce initial load
- Code splitting and lazy loading
- Optimize images and assets
After optimization, provide:
## Performance Report
### Changes Made
1. **Optimization 1**
- **File**: `src/services/user.ts`
- **Change**: Added Redis caching for user queries
- **Impact**: Reduced query time from 500ms to 50ms
- **Trade-off**: Requires Redis infrastructure
2. **Optimization 2**
- **File**: `src/components/UserList.tsx`
- **Change**: Implemented virtual scrolling
- **Impact**: Render time reduced from 2s to 200ms for 10,000 items
- **Trade-off**: Increased component complexity
### Before/After Metrics
| Metric | Before | After | Improvement |
|--------|--------|-------|-------------|
| API response time | 1200ms | 150ms | 87.5% faster |
| Initial page load | 4.5s | 1.2s | 73% faster |
| Memory usage | 450MB | 180MB | 60% reduction |
### Verification
- [ ] All existing tests pass
- [ ] No regressions in functionality
- [ ] Performance improvements verified with benchmarksALWAYS:
- Run tests before and after optimizations
- Use feature flags for risky changes
- Have a rollback plan ready
- Monitor production metrics after deployment
NEVER:
- Optimize code you don't understand
- Make optimizations that break functionality
- Remove error handling for "performance"
- Optimize without measuring first
### Step 2: Create Agent Implementation
Create the Python implementation in `apps/backend/agents/`:
```bash
# Create optimizer agent
touch apps/backend/agents/optimizer.py
Example implementation:
"""
Performance Optimizer Agent
Analyzes code for performance bottlenecks and implements optimizations.
"""
from core.client import create_client
from agents.session import run_agent_session, post_session_processing
import logging
logger = logging.getLogger(__name__)
def run_optimizer_agent(project_dir: str, spec_dir: str, model: str = "claude-sonnet-4-5-20250929"):
"""
Run the performance optimizer agent.
Args:
project_dir: Path to project root
spec_dir: Path to spec directory
model: Model to use for agent
Returns:
Agent session results
"""
logger.info("Starting Performance Optimizer Agent")
# Create SDK client with optimizer-specific configuration
client = create_client(
project_dir=project_dir,
spec_dir=spec_dir,
model=model,
agent_type="optimizer" # Custom agent type
)
# Read system prompt
prompt_path = "apps/backend/prompts/optimizer.md"
with open(prompt_path) as f:
system_prompt = f.read()
# Starting message for the optimizer
starting_message = """
Analyze the current codebase for performance bottlenecks and propose optimizations.
Focus on:
1. Database query performance
2. Caching opportunities
3. Algorithmic complexity
4. Frontend rendering performance
Provide a detailed report with before/after metrics.
"""
# Run the agent session
try:
response = run_agent_session(
client=client,
agent_name="optimizer",
starting_message=starting_message,
system_prompt=system_prompt
)
# Process results and save to memory
post_session_processing(
response=response,
agent_name="optimizer",
spec_dir=spec_dir,
project_dir=project_dir
)
return response
except Exception as e:
logger.error(f"Optimizer agent failed: {e}")
raiseUpdate core/client.py to recognize your custom agent type:
# In core/client.py
# Add your agent type to the permissions mapping
AGENT_TOOL_PERMISSIONS = {
"planner": {
"allowed_tools": ["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
"max_thinking_tokens": 20000
},
"coder": {
"allowed_tools": ["Read", "Write", "Edit", "Bash", "Glob", "Grep"],
"max_thinking_tokens": None
},
"qa_reviewer": {
"allowed_tools": ["Read", "Write", "Edit", "Bash", "Glob", "Grep", "Task"],
"max_thinking_tokens": 16000
},
# Add your custom agent type
"optimizer": {
"allowed_tools": ["Read", "Bash", "Grep"], # Read-only access for analysis
"max_thinking_tokens": 20000
}
}Add your agent to the appropriate workflow:
Option A: Add to main pipeline (run.py)
# In apps/backend/run.py
from agents.optimizer import run_optimizer_agent
def run_optimization_phase(project_dir: str, spec_dir: str):
"""Run performance optimization after QA passes."""
logger.info("Running performance optimization...")
response = run_optimizer_agent(
project_dir=project_dir,
spec_dir=spec_dir
)
return responseOption B: Run as standalone command
# Add to apps/backend/cli.py or create new entry point
@app.command()
def optimize(spec_id: str):
"""Run performance optimization on a spec."""
spec_dir = f".auto-claude/specs/{spec_id}"
project_dir = "."
run_optimizer_agent(project_dir, spec_dir)Option C: Create custom workflow
# Create apps/backend/workflows/optimize.py
from agents.optimizer import run_optimizer_agent
def optimization_workflow(spec_id: str):
"""Run performance optimization workflow."""
# Step 1: Analyze current state
# Step 2: Run optimizer agent
# Step 3: Implement optimizations
# Step 4: Run tests
# Step 5: Generate report
pass# Test the optimizer agent
cd apps/backend
python -c "
from agents.optimizer import run_optimizer_agent
response = run_optimizer_agent('.', '.auto-claude/specs/001-feature')
print(response)
"Testing agent modifications ensures they behave as expected.
# tests/test_custom_agent.py
import pytest
from agents.optimizer import run_optimizer_agent
def test_optimizer_analyzes_code():
"""Test that optimizer analyzes code correctly."""
response = run_optimizer_agent(
project_dir="tests/fixtures/sample_project",
spec_dir="tests/fixtures/sample_spec"
)
assert "performance" in response.lower()
assert "optimization" in response.lower()
def test_optimizer_proposes_solutions():
"""Test that optimizer proposes concrete solutions."""
# ... test implementation# tests/test_agent_integration.py
def test_full_agent_workflow():
"""Test agent in full workflow."""
# 1. Create spec
# 2. Run planner
# 3. Run coder
# 4. Run custom agent
# 5. Verify results# Test prompt syntax and structure
cd apps/backend
# Validate prompt markdown
python -c "
import markdown
import sys
prompt_file = 'prompts/optimizer.md'
with open(prompt_file) as f:
content = f.read()
try:
markdown.markdown(content)
print(f'✓ {prompt_file} is valid markdown')
except Exception as e:
print(f'✗ {prompt_file} has errors: {e}')
sys.exit(1)
"-
Be Specific and Clear
# ❌ Vague Write good code. # ✅ Specific Write Python code following PEP 8 guidelines with type hints and docstrings.
-
Provide Examples
## Example Output Here's what a good response looks like: ```markdown ## Performance Report - Found 3 optimization opportunities - Estimated improvement: 40% faster
-
Structure with Headings
## Phase 1: Analysis ## Phase 2: Planning ## Phase 3: Implementation
-
Include Safety Rules
## Safety - ALWAYS run tests before committing - NEVER delete files without confirmation - ALWAYS backup before refactoring
Only give agents the tools they need:
# ❌ Too permissive
"optimizer": {
"allowed_tools": ["*"] # All tools
}
# ✅ Minimal permissions
"optimizer": {
"allowed_tools": ["Read", "Grep"] # Read-only access
}Allocate thinking tokens based on task complexity:
"planner": {
"max_thinking_tokens": 20000 # Complex planning
},
"coder": {
"max_thinking_tokens": None # Unlimited for coding
},
"qa_reviewer": {
"max_thinking_tokens": 16000 # Moderate for review
}Track prompt changes:
# Commit prompt modifications
git add apps/backend/prompts/coder.md
git commit -m "docs: add TypeScript strict mode to coder prompt"Chain multiple agents together:
def run_analysis_workflow(project_dir: str, spec_dir: str):
"""Run multi-agent analysis workflow."""
# Agent 1: Security analysis
security_response = run_agent_session(
client=create_client(project_dir, spec_dir, agent_type="security"),
agent_name="security_analyzer",
starting_message="Analyze code for security vulnerabilities"
)
# Agent 2: Performance analysis
perf_response = run_agent_session(
client=create_client(project_dir, spec_dir, agent_type="optimizer"),
agent_name="optimizer",
starting_message=f"Optimize code, considering security issues: {security_response}"
)
# Agent 3: Generate combined report
report_response = run_agent_session(
client=create_client(project_dir, spec_dir, agent_type="reporter"),
agent_name="reporter",
starting_message=f"Generate report from:\nSecurity: {security_response}\nPerformance: {perf_response}"
)
return report_responseRun agents based on conditions:
def smart_workflow(project_dir: str, spec_dir: str):
"""Run agents conditionally based on spec analysis."""
# Check if spec involves database changes
spec = load_spec(spec_dir)
has_db_changes = "database" in spec.get("services", [])
if has_db_changes:
# Run database specialist agent
run_db_specialist(project_dir, spec_dir)
else:
logger.info("No database changes, skipping DB specialist")
# Always run QA
run_qa_reviewer(project_dir, spec_dir)Create specialized versions of existing agents:
# Frontend-focused coder
apps/backend/prompts/coder_frontend.md
# Backend-focused coder
apps/backend/prompts/coder_backend.md
# Test-focused coder
apps/backend/prompts/coder_testing.mdThen route to the appropriate agent based on task type:
def run_coder(project_dir: str, spec_dir: str):
"""Run specialized coder based on task."""
spec = load_spec(spec_dir)
services = spec.get("services", [])
if all("frontend" in s for s in services):
prompt_file = "coder_frontend.md"
elif all("backend" in s for s in services):
prompt_file = "coder_backend.md"
else:
prompt_file = "coder.md" # Default
run_agent_with_prompt(project_dir, spec_dir, prompt_file)Problem: Agent ignores your custom prompt modifications.
Solutions:
- Check prompt syntax - invalid markdown can cause issues
- Ensure instructions are clear and unambiguous
- Add examples to prompt
- Increase thinking tokens to allow more reasoning
- Test on simpler tasks first
Problem: Agent can't access needed tools.
Solutions:
- Check
AGENT_TOOL_PERMISSIONSincore/client.py - Verify agent type is registered
- Add required tools to allowed_tools list
- Check if security rules block certain operations
Problem: Custom agent is slow or inefficient.
Solutions:
- Reduce prompt length - focus on essentials
- Add caching for repeated operations
- Use parallel execution for independent tasks
- Set appropriate
max_thinking_tokens
See the following for real-world examples:
- Planner Agent:
apps/backend/prompts/planner.md+apps/backend/agents/planner.py - Coder Agent:
apps/backend/prompts/coder.md+apps/backend/agents/coder.py - QA Agents:
apps/backend/prompts/qa_reviewer.mdandqa_fixer.md
- Advanced Usage Guide - Agent customization overview
- Spec Creation Pipeline - Spec creation agents
- Claude SDK Documentation - SDK reference
- Agent System README - Agent architecture
- Discord Community - Chat with other users
- GitHub Issues - Report bugs
- GitHub Discussions - Ask questions