Module 1: Custom Subagents
5. Project — Pipeline of 3 Specialized Subagents
5. Project — Pipeline of 3 Specialized Subagents
Project Description
You've learned to create subagents as Markdown files with YAML frontmatter, to define system prompts that produce predictable outputs, to restrict tools so each agent can only do what it's supposed to, and to parse the communication between agents to chain them. Now you're going to integrate everything into a functional system.
In this project you build a development pipeline with 3 specialized subagents: a reviewer that analyzes recent code looking for problems, an implementer that fixes the problems found, and a tester that runs the test suite to verify that the fixes didn't break anything. Each subagent has a strict role defined by its frontmatter, tool restrictions that guarantee it doesn't step outside its function, and an output format that the next agent in the chain can consume.
The flow is linear: you write a prompt, Claude delegates to the reviewer, the reviewer returns a report, Claude processes that report and delegates to the implementer with the findings, the implementer makes the changes and returns a summary, Claude delegates to the tester, and the tester runs the tests and reports results. At the end, Claude presents you with a consolidated summary. There's no magic — each step is explicit, each output is structured, and each agent has exactly the tools it needs.
This is the culminating project of Module 1. If the 3 subagents work in sequence and the final report integrates results from all 3, you've mastered custom subagents. If in addition you can explain why the reviewer doesn't have Write and the tester doesn't have Edit, you've internalized the philosophy of restriction by design.
Project Objective
Build a functional pipeline of 3 subagents (reviewer → implementer → tester) where each agent has a defined role, tools, model, and output format — and run them in sequence on a real project.
By the end of this project:
- ✅ You'll have 3 subagent files in
.claude/agents/ready to use in any project - ✅ Each subagent will be restricted to the tools it needs — no exceptions
- ✅ The reviewer will produce reports classified by priority (Critical / Warning / Suggestion)
- ✅ The implementer will take the reviewer's report as input and fix the problems
- ✅ The tester will run the full suite and report pass/fail, coverage, and root causes
- ✅ You'll have run the complete pipeline at least once with verifiable results
- ✅ You'll be able to explain why each tool restriction exists
Estimated duration: 1.5-2 hours (setup: 15 min + subagents: 45 min + individual testing: 20 min + pipeline: 20 min + iteration: 15 min).
Technical Specifications
Technology Stack
- Tool: Claude Code v2.1.63+
- Subagent files: Markdown with YAML frontmatter
- Location:
.claude/agents/(project scope) - Models: haiku (reviewer, tester), sonnet (implementer)
- Base project: Any project with source code in
src/, tests, and at least 3 commits in git
Base Project Requirements
For the pipeline to make sense, you need a project with:
| Requirement | Minimum | Ideal |
|---|---|---|
Code files in src/ | 3+ | 8-15 |
| Existing tests | 3+ | 10+ |
| Commits in git | 3+ | 10+ |
| CLAUDE.md | Basic | With style conventions |
| Test framework | Any | pytest or jest |
If you don't have a project handy, clone any open source project with tests. What matters is that there's code to review, files to potentially fix, and tests to run.
Initial Setup
cd your-project
mkdir -p .claude/agents
ls .claude/agents/
claude --version
Verify that Claude Code is v2.1.63 or later. If not, update:
claude update
Final Project Structure
By the end, your project will have this additional structure:
your-project/
├── .claude/
│ └── agents/
│ ├── code-reviewer.md ← Subagent 1: only reads
│ ├── code-implementer.md ← Subagent 2: edits src/
│ └── code-tester.md ← Subagent 3: only executes
├── src/ ← Code the pipeline analyzes
├── tests/ ← Tests the tester runs
├── CLAUDE.md ← Project conventions
└── ...
Mandatory Features
Subagent 1: Code Reviewer (code-reviewer.md)
Role: Analyzes recent changes in the code and produces a report structured by priority. It only reads — it never modifies files.
Specifications:
| Field | Value | Justification |
|---|---|---|
tools | Read, Grep, Glob, Bash | Reads files, searches patterns, runs git diff |
disallowedTools | Write, Edit | Guarantees it doesn't modify code |
model | haiku | Reading and analysis don't require deep reasoning |
maxTurns | 15 | Enough to read files and produce the report |
8 review criteria:
- Readability — Descriptive names, short functions, clear flow
- Naming conventions — Consistency with project conventions
- Error handling — Specific try/except, not generic. Errors not silenced
- Security — No hardcoded secrets, no SQL injection, no unsanitized inputs
- Performance — No N+1 queries, no unnecessary loops, no blocking in async
- Edge cases — Null checks, empty collections, boundary values
- DRY — No significant duplication. Shared logic extracted
- Type safety — Type hints present and correct (Python), explicit types (TypeScript)
Output format: Report with Critical / Warning / Suggestion sections, each finding with file, line, description, evidence, and recommendation.
Subagent 2: Code Implementer (code-implementer.md)
Role: Receives the reviewer's report and fixes the problems found. It only modifies files in src/. It follows the CLAUDE.md conventions.
Specifications:
| Field | Value | Justification |
|---|---|---|
tools | Read, Edit, Write, Grep, Glob | Reads code, searches context, edits and creates files |
disallowedTools | Bash | Doesn't run commands — only modifies code |
model | sonnet | Implementation requires reasoning about logic |
maxTurns | 25 | May need multiple edits across several files |
Implementation rules:
- Fix ALL findings marked as Critical
- Fix Warning findings if the fix is direct (< 10 lines)
- Ignore Suggestion unless explicitly indicated
- Only modify files inside
src/ - Never modify tests, configuration, or CLAUDE.md
- Follow the project's existing conventions
- Report each change made and each unaddressed finding with justification
Subagent 3: Code Tester (code-tester.md)
Role: Runs the test suite and reports results. It doesn't modify source code or tests — it only runs and reports.
Specifications:
| Field | Value | Justification |
|---|---|---|
tools | Bash, Read, Grep, Glob | Runs tests, reads test files for context |
disallowedTools | Write, Edit | Can't modify code or tests |
model | haiku | Running tests and reporting doesn't require deep reasoning |
maxTurns | 12 | Run suite + analyze failures |
Information it reports:
- Detected framework and command executed
- Total count: passed, failed, skipped
- For each failed test: name, what it expected, what it got, likely root cause
- Coverage by module (if configured)
- Final verdict: ALL_PASS, FAILURES, ERROR
Step-by-Step Guide
Step 1: Create the Code Reviewer
Create the file .claude/agents/code-reviewer.md with the following complete content:
---
name: code-reviewer
description: Analyzes recent code changes against 8 quality criteria. Read-only — never modifies files. Reports by priority: Critical, Warning, Suggestion.
tools: Read, Grep, Glob, Bash
disallowedTools: Write, Edit
model: haiku
maxTurns: 15
---
## Role
You are a senior code reviewer. You analyze recent git changes and produce a structured report organized by severity. You NEVER modify any file. Your job is to find problems — fixing them is someone else's responsibility.
## Process
1. Run `git diff HEAD~3 --name-only` to identify recently changed files
2. Filter: only review files in `src/` (skip tests, configs, docs)
3. For each changed file:
a. Read the complete file
b. Read related files (imports, parent classes, interfaces) for context
c. Apply all 8 review criteria
4. Produce the report in the exact output format below
If `git diff HEAD~3` returns no files, try `git diff HEAD~1` or report that no recent changes were found.
## Review Criteria
### 1. Readability
- Functions longer than 30 lines
- Deeply nested logic (3+ levels)
- Unclear control flow
### 2. Naming Conventions
- Variables/functions not following project conventions
- Inconsistent naming style within a file
- Single-letter variables outside of loops/comprehensions
### 3. Error Handling
- Bare `except:` or `except Exception:`
- Silenced errors (empty except blocks)
- Missing error handling on I/O, network, or database operations
### 4. Security
- Hardcoded credentials, API keys, or secrets
- User input used without validation or sanitization
- SQL queries built with string concatenation or f-strings
### 5. Performance
- Database queries inside loops (N+1 pattern)
- Loading large collections without pagination or limits
- Blocking operations in async context
### 6. Edge Cases
- Missing null/None checks before attribute access
- No handling of empty collections (empty list, empty dict)
- Missing boundary value validation (negative numbers, zero, max int)
### 7. DRY (Don't Repeat Yourself)
- Duplicated logic blocks (3+ lines repeated)
- Copy-pasted code with minor variations
- Logic that should be extracted into a shared function
### 8. Type Safety
- Missing type hints on function signatures (Python)
- Using `Any` where a specific type is known
- Type mismatches between function signature and usage
## Output Format
Follow this EXACT structure:
Code Review Report
Date: [YYYY-MM-DD] Commit range: HEAD~3..HEAD Files reviewed: [list of files]
CRITICAL (must fix before merge)
- [file:line] — [Short description]
- Criteria: [which of the 8 criteria]
- Evidence:
[relevant code snippet] - Recommendation: [specific fix]
WARNING (should fix)
- [file:line] — [Short description]
- Criteria: [which of the 8 criteria]
- Evidence:
[relevant code snippet] - Recommendation: [specific fix]
SUGGESTION (nice to have)
- [file:line] — [Short description]
- Criteria: [which of the 8 criteria]
- Recommendation: [specific improvement]
Summary
| Priority | Count |
|---|---|
| Critical | [n] |
| Warning | [n] |
| Suggestion | [n] |
Verdict: [PASS | PASS_WITH_WARNINGS | NEEDS_REVISION]
- PASS: 0 critical, 0 warnings
- PASS_WITH_WARNINGS: 0 critical, 1+ warnings
- NEEDS_REVISION: 1+ critical
If no issues are found in a category, write "None found."
Step 2: Verify the Reviewer
Before creating the other subagents, verify that the reviewer works correctly.
2a. Verify that Claude Code detects it:
Open Claude Code in your project and run:
/agents
You should see code-reviewer in the list of project subagents. If it doesn't appear:
- Verify that the file is at
.claude/agents/code-reviewer.md - Verify that the frontmatter
---are alone on their own line - Verify that there are no tabs in the YAML (only spaces)
2b. Run the reviewer:
Use the code-reviewer to analyze the project's recent changes
What to verify in the output:
- ✅ It only reviewed files in
src/(no tests, no configs) - ✅ It ran
git diffto find changed files - ✅ Each finding has file, line, criteria, evidence, and recommendation
- ✅ The findings are classified into Critical / Warning / Suggestion
- ✅ The summary has a count and a verdict
- ✅ It did NOT modify any file (verify with
git status)
git status
If git status shows modified files that weren't modified before, the reviewer violated its restriction. Check the frontmatter.
2c. If the reviewer doesn't produce structured output:
It's normal on the first iteration. Adjust the system prompt — add "Follow this EXACT structure. Do not deviate." at the start of the Output Format section. The word EXACT significantly reduces variation.
Step 3: Create the Code Implementer
Create .claude/agents/code-implementer.md:
---
name: code-implementer
description: Fixes code issues from review reports. Only modifies files in src/. Follows project conventions from CLAUDE.md. Never touches tests or config.
tools: Read, Edit, Write, Grep, Glob
disallowedTools: Bash
model: sonnet
maxTurns: 25
---
## Role
You are a senior developer who fixes code issues identified in review reports. You work exclusively in `src/`. You follow existing project conventions — never introduce new patterns, libraries, or styles unless explicitly instructed.
## Constraints
- ONLY modify files inside `src/`
- NEVER modify files in `tests/`, `test/`, or any test file
- NEVER modify configuration files (*.yml, *.toml, *.cfg, *.json at root)
- NEVER modify CLAUDE.md, README.md, or documentation files
- NEVER install new dependencies
- NEVER delete files
- Follow the coding style already present in the project
## When Receiving a Review Report
Read the entire report first. Then:
1. **CRITICAL items:** Fix ALL of them. These are blockers.
2. **WARNING items:** Fix if the change is straightforward (< 10 lines changed). Skip if it requires architectural changes.
3. **SUGGESTION items:** SKIP unless explicitly asked to address them.
For each fix:
- Read the file and surrounding context before editing
- Make the minimal change that resolves the issue
- Preserve existing code style (indentation, quotes, naming)
- If a fix could affect other files, read those files first
## Process
1. Parse the review report to extract all items by priority
2. Read CLAUDE.md for project conventions
3. For each CRITICAL item:
a. Read the file mentioned
b. Understand the context around the problematic code
c. Apply the fix
d. Record what you changed
4. For each WARNING item (if straightforward):
a. Same process as CRITICAL
5. Produce the implementation report
## Output Format
Follow this EXACT structure:
Implementation Report
Files modified: [list of files changed] Review items addressed: [n] of [total]
Changes Made
-
[file:line] — [What was changed]
- Review item: [CRITICAL|WARNING] — [original description]
- Fix applied: [description of the fix]
- Lines changed: [n]
-
[file:line] — [What was changed]
- ...
Items Not Addressed
- [file:line] — [original description]
- Reason: [why it was skipped — "SUGGESTION: not requested" | "WARNING: requires architectural change" | etc.]
Summary
| Category | Found | Fixed | Skipped |
|---|---|---|---|
| Critical | [n] | [n] | [n] |
| Warning | [n] | [n] | [n] |
| Suggestion | [n] | [n] | [n] |
Step 4: Verify the Implementer
4a. Verify detection:
/agents
Confirm that code-implementer appears with the tools Read, Edit, Write, Grep, Glob. No Bash.
4b. Run the implementer with the reviewer's report:
Don't run the implementer in isolation the first time — it needs a review report as input. But you can do a simple test:
Use the code-implementer to add type hints to the functions in src/ that don't have them
What to verify:
- ✅ It only modified files in
src/ - ✅ It didn't touch tests or configuration
- ✅ Each change has a description and justification
- ✅ It didn't run commands (it doesn't have Bash)
git diff --stat
Verify that the modified files are all in src/. If it modified something outside src/, check the system prompt instructions.
Step 5: Create the Code Tester
Create .claude/agents/code-tester.md:
---
name: code-tester
description: Runs the project test suite and reports results with pass/fail counts, coverage, and root cause analysis for failures. Never modifies code.
tools: Bash, Read, Grep, Glob
disallowedTools: Write, Edit
model: haiku
maxTurns: 12
---
## Role
You are a test runner and reporter. You execute the project's test suite and produce a detailed report. You NEVER modify source code, test files, or any other file. If tests fail, your job is to report WHY they fail — not to fix them.
## Process
1. **Detect the test framework:**
- Check for `pyproject.toml`, `setup.cfg` → pytest
- Check for `package.json` → jest, vitest, or mocha
- Check for `Cargo.toml` → cargo test
- Check for `go.mod` → go test
- If unclear, look for test files and infer
2. **Run the full test suite:**
- Python (pytest): `python -m pytest -v --tb=short 2>&1`
- Python (with coverage): `python -m pytest --cov=src --cov-report=term-missing -v 2>&1`
- Node (jest): `npx jest --verbose 2>&1`
- Node (vitest): `npx vitest run --reporter=verbose 2>&1`
- Always redirect stderr to stdout with `2>&1`
3. **If tests fail:**
- Read the failing test file to understand what it expects
- Read the source file the test is testing
- Determine the likely root cause
- Do NOT attempt to fix anything
4. **If the test command fails entirely (not installed, config error):**
- Report the error clearly
- Suggest what might be wrong
- Try an alternative command if obvious (e.g., `pytest` instead of `python -m pytest`)
## Output Format
Follow this EXACT structure:
Test Report
Framework: [detected framework and version] Command: [exact command executed] Execution time: [seconds]
Results
| Status | Count |
|---|---|
| ✅ Passed | [n] |
| ❌ Failed | [n] |
| ⏭️ Skipped | [n] |
| Total | [n] |
Failed Tests
(If no failures, write "All tests passed.")
-
[test_file::TestClass::test_name]
- Expected: [what the test expected]
- Got: [what actually happened]
- Error:
[error message] - Root cause: [your analysis of why it fails]
-
...
Coverage
(If coverage data is available)
| Module | Statements | Covered | Missing | Coverage |
|---|---|---|---|---|
| [module] | [n] | [n] | [lines] | [%] |
| Total | [n] | [n] | — | [%] |
(If coverage is not configured, write "Coverage not configured. Run with --cov to enable.")
Verdict
[ALL_PASS | FAILURES | ERROR]
- ALL_PASS: All tests passed successfully
- FAILURES: One or more tests failed
- ERROR: Test suite could not execute (missing dependency, config error)
Step 6: Verify the Tester
6a. Verify detection:
/agents
Confirm that code-tester appears with Bash, Read, Grep, Glob. No Write, no Edit.
6b. Run the tester in isolation:
Use the code-tester to run the project's test suite
What to verify:
- ✅ It detected the correct framework
- ✅ It ran the test command
- ✅ It reported pass/fail/skipped with counts
- ✅ If there were failures, it included root cause analysis
- ✅ It did NOT modify any file
git status
Confirm there are no changes in files. If the tester modified something, the frontmatter has an error.
Step 7: Verify the 3 Subagents in /agents
Before chaining them, verify that the 3 are correctly configured:
/agents
You should see output similar to:
Project agents (.claude/agents/):
code-reviewer — Analyzes recent code changes against 8 quality criteria...
code-implementer — Fixes code issues from review reports...
code-tester — Runs the project test suite and reports results...
Verify this capabilities table:
| Tool | code-reviewer | code-implementer | code-tester |
|---|---|---|---|
| Read | ✅ | ✅ | ✅ |
| Grep | ✅ | ✅ | ✅ |
| Glob | ✅ | ✅ | ✅ |
| Bash | ✅ | ❌ | ✅ |
| Write | ❌ | ✅ | ❌ |
| Edit | ❌ | ✅ | ❌ |
Each agent has exactly what it needs. No more, no less.
Step 8: Run the Complete Pipeline
Now comes the moment to chain the 3 subagents. The chaining happens through Claude Code's main conversation — you ask it to run the flow and Claude delegates to each subagent in sequence.
The prompt for the complete pipeline:
Run the following development flow in sequence:
1. Use the code-reviewer to analyze the recent changes (HEAD~3)
2. Take the reviewer's report and pass it to the code-implementer so it fixes the problems found
3. After the implementer finishes, use the code-tester to run the tests and verify that everything works
At the end, give me a consolidated summary with:
- What the reviewer found
- What the implementer fixed
- What the tester reported
- Final verdict: is the code ready?
What to observe during execution:
- Claude delegates to the reviewer → It should run
git diff, read files, produce a report - Claude processes the report → Extracts the Critical and Warning findings
- Claude delegates to the implementer → Passes it the findings as context. The implementer reads files, makes changes, reports
- Claude delegates to the tester → The tester runs tests, reports results
- Claude presents a summary → Consolidates the information from the 3 subagents
The visual flow:
Your prompt
│
▼
┌─────────────────────────────┐
│ Claude (main conversation) │
│ │
│ 1. Delegate to reviewer │──── git diff, reads files
│ ← receives report │ 8 criteria evaluated
│ │
│ 2. Process report │──── extracts Critical/Warning
│ Delegate to implementer │ with findings as context
│ ← receives changes │ edits only in src/
│ │
│ 3. Delegate to tester │──── runs pytest/jest
│ ← receives results │ analyzes failures
│ │
│ 4. Present final summary │──── consolidates the 3 reports
└─────────────────────────────┘
Step 9: Verify the Pipeline
After execution, verify each phase:
Reviewer verification:
# The reviewer must not have modified anything during its phase
# (the implementer did — verify it only touched src/)
git diff --name-only
All modified files must be in src/.
Implementer verification:
git diff --stat
Confirm that the changes correspond to the reviewer's findings. If the implementer changed something that wasn't in the report, the system prompt needs adjustment.
Tester verification:
- If the tests pass: the pipeline succeeded
- If the tests fail: read the tester's report to understand why. You can re-run just the implementer with more context, and then the tester again
Step 10: Iterate if Necessary
If the pipeline didn't work perfectly on the first run, that's normal. Common iteration points:
The reviewer produces inconsistent output: Reinforce the format. Add to the reviewer's system prompt:
IMPORTANT: Follow the Output Format section EXACTLY. Do not add extra sections,
do not change headers, do not omit the Summary table.
The implementer doesn't receive the complete report: The chaining prompt needs to be more explicit. Change "pass it to the implementer" to:
Pass the COMPLETE reviewer report to the code-implementer. Include
all findings with their classification, file, line and description.
The tester fails to run tests: It may be an environment problem (virtualenv not activated, node_modules not installed). The tester will report the error — read it and fix the environment before re-running.
Validation Checklist
Use this checklist to confirm that your pipeline is complete:
Files created
-
.claude/agents/code-reviewer.mdexists and has valid frontmatter -
.claude/agents/code-implementer.mdexists and has valid frontmatter -
.claude/agents/code-tester.mdexists and has valid frontmatter
Detection
-
/agentsshows the 3 subagents with their descriptions - Each subagent shows the correct tools
Tool restrictions
- The reviewer CANNOT write or edit files (verified with
git statusafter execution) - The implementer CANNOT run Bash commands
- The implementer ONLY modifies files in
src/ - The tester CANNOT write or edit files (verified with
git status)
Structured output
- The reviewer produces a report with Critical / Warning / Suggestion sections
- The reviewer includes file, line, criteria, evidence, and recommendation
- The implementer produces a report with Changes Made and Items Not Addressed
- The tester produces a report with Results, Failed Tests, Coverage, Verdict
Complete pipeline
- The 3 subagents run in sequence: reviewer → implementer → tester
- The implementer receives the reviewer's findings as input
- The tester runs after the implementer's changes
- Claude presents a consolidated summary at the end
- The summary includes information from the 3 subagents
Models
- The reviewer uses
haiku(fast, reading) - The implementer uses
sonnet(capable, implementation) - The tester uses
haiku(fast, execution)
Quick Reference — The 3 Files
The 3 complete, copy-paste-ready subagent files are in steps 1, 3, and 5 of the previous guide:
| File | Step | Description |
|---|---|---|
.claude/agents/code-reviewer.md | Step 1 | Read-only, haiku, 8 criteria, report by priority |
.claude/agents/code-implementer.md | Step 3 | Edit src/, sonnet, fixes Critical and Warning |
.claude/agents/code-tester.md | Step 5 | Execute-only, haiku, pass/fail + coverage + root cause |
Each file is self-contained. Copy the code block from the corresponding step directly into .claude/agents/. They don't need additional files or extra dependencies.
Pipeline Variations
Variation 1: Pipeline with reduced scope
If your project is large, narrow the reviewer's scope:
Run the reviewer → implementer → tester pipeline, but the reviewer
should only analyze the files changed in the last commit (HEAD~1).
Variation 2: Critical-only pipeline
If you want a fast pipeline that only handles the urgent:
Run the complete pipeline, but the implementer should only fix
findings marked as CRITICAL. Ignore WARNING and SUGGESTION.
Variation 3: Pipeline with re-run
If the tests fail after the fixes:
The tester reported 2 failed tests. Pass the tester's report to the
code-implementer so it fixes the problems, and then run
the code-tester again to verify.
This pattern extends the pipeline to: reviewer → implementer → tester → implementer → tester. Each iteration reduces the failures.
Variation 4: Run subagents individually
You don't always need the complete pipeline. Each subagent works independently:
Use the code-reviewer to analyze the changes from the last week
Use the code-tester to run only the tests for the auth module
Use the code-implementer to add error handling to the functions
in src/services/ that don't have try/except
Common Errors and Solutions
Error 1: "The subagent doesn't appear in /agents"
Symptom: You run /agents and your subagent isn't in the list.
Possible causes:
- The file isn't in
.claude/agents/(verify the exact path) - The YAML frontmatter has syntax errors
- There are tabs instead of spaces in the YAML
- The
---have spaces before or after
Solution:
ls -la .claude/agents/
head -10 .claude/agents/code-reviewer.md
Verify that the --- delimiters are alone on their line, with no spaces. YAML only uses spaces for indentation.
Error 2: "The reviewer modified files"
Symptom: After running the reviewer, git status shows modified files.
Possible causes:
disallowedToolsmisspelled (it's camelCase:disallowedTools, notdisallowed_tools)- Tool names are case-sensitive:
Write, notwrite - Missing
Editin disallowedTools
Solution: Verify the frontmatter:
disallowedTools: Write, Edit
Both names must be PascalCase. Then run /agents and confirm that the tools shown are correct.
Error 3: "The implementer changed files outside src/"
Symptom: git diff --stat shows changes in tests or configuration.
Cause: The directory restriction is in the system prompt (an instruction) but not enforced by tools or hooks. The system prompt says "ONLY modify files inside src/" but technically it can edit any file.
Solution: For stricter enforcement, add a PreToolUse hook. But for most cases, the system prompt with "ONLY" and "NEVER" is enough. If the problem persists, reinforce with:
CRITICAL CONSTRAINT: If the file path does not start with "src/",
do NOT edit it under any circumstances. This is a hard rule.
Error 4: "The tester can't run the tests"
Symptom: The tester reports ERROR because the test command fails.
Possible causes:
- The virtual environment isn't activated
- Dependencies not installed (
pytestnot found) - The tester tries to run from the wrong directory
Solution: Before running the pipeline, verify that the tests work manually:
python -m pytest -v --tb=short 2>&1
If this fails outside the pipeline, the problem is the environment, not the subagent.
Error 5: "The reviewer's output isn't consistent"
Symptom: The reviewer produces reports with different formats each run.
Cause: The system prompt describes the format but isn't strict enough.
Solution: Add these lines at the start of the reviewer's Output Format section:
IMPORTANT: Follow this EXACT structure. Do not add extra sections.
Do not change header names. Do not omit the Summary table.
If no issues in a category, write "None found." — do not omit the category.
Error 6: "The pipeline stops halfway"
Symptom: Claude runs the reviewer but doesn't continue with the implementer.
Cause: The orchestration prompt isn't explicit enough about the sequence.
Solution: Use a more direct prompt:
Run these 3 steps IN SEQUENCE, one after another:
STEP 1: Delegate to the code-reviewer to analyze HEAD~3
STEP 2: When the reviewer finishes, take its complete report and
delegate it to the code-implementer so it fixes the problems
STEP 3: When the implementer finishes, delegate to the code-tester
to run the tests
At the end, give me a consolidated summary of the 3 reports.
Error 7: "The implementer doesn't receive the reviewer's context"
Symptom: The implementer doesn't know what problems to fix because it doesn't have the reviewer's report.
Cause: Each subagent has its own context — they don't share memory. Claude must explicitly pass the information from one to another.
Solution: In the orchestration prompt, emphasize that the report be passed in full:
STEP 2: Pass the COMPLETE reviewer report to the code-implementer,
including all findings with their classification (CRITICAL,
WARNING, SUGGESTION), file, line, and description.
Claude acts as the intermediary — it reads the reviewer's output and includes it as context when invoking the implementer.
Error 8: "The reviewer marks EVERYTHING as Critical"
Symptom: The reviewer classifies trivial findings (naming, style) as Critical.
Cause: The classification criteria aren't defined in the system prompt.
Solution: Add explicit classification criteria:
## Classification Rules
CRITICAL: Security vulnerabilities, data loss risk, logic errors
that produce wrong results, unhandled exceptions that crash the app.
WARNING: Missing error handling that won't crash but degrades UX,
performance issues, missing validation on user input.
SUGGESTION: Naming improvements, style consistency, refactoring
for readability, adding type hints.
When in doubt, classify DOWN (Warning instead of Critical,
Suggestion instead of Warning).
Project Resources
- Create Custom Subagents (Anthropic Docs) — Official subagent documentation: file format, YAML frontmatter, tool restriction, hooks, scopes
- Claude Code Hooks Reference — PreToolUse hooks reference for advanced enforcement of restrictions
- Claude Code CLI Reference — CLI flags like
--agentsto load subagents from custom locations - Claude Code Best Practices — Prompting and delegation best practices that apply to subagent system prompts
- Prompt Engineering: Be Clear and Direct — Clarity techniques applicable to designing subagent system prompts
- Claude Models Documentation — Model reference for choosing haiku vs sonnet vs opus by task type
Connection to the Next Module
You've built a functional pipeline with 3 specialized subagents. It works. But it has a fundamental limitation you probably already noticed: every time you run the pipeline, the subagents start from scratch.
The reviewer doesn't remember what it found in the previous run. If you ran the pipeline yesterday and the reviewer found 3 warnings you decided to ignore, today it reports them to you again. It doesn't know you already saw them. It doesn't know they're false positives for your context. It doesn't know the implementer already evaluated one and decided not to change it because it requires a bigger refactor.
The implementer doesn't remember the conventions it learned. If on the first run it discovered that your project uses single quotes in Python and custom decorators for logging, on the next run it has to rediscover that by reading CLAUDE.md and the code again. Each run is a first time.
The tester doesn't remember which tests were failing before. It can't tell you "these 2 tests were already failing before the implementer's changes — they're pre-existing, not regressions." For it, each run is the first suite it ever sees.
This lack of memory across sessions is the most critical problem of custom subagents. The 3 agents you created here are competent but amnesiac. Module 2: Agent Memory and Scopes solves exactly this — you'll learn to configure persistent memory with scopes (session, project, user) so your subagents accumulate context across runs. A reviewer with memory becomes a reviewer that knows your project.
Summary
- You built a functional pipeline of 3 subagents: reviewer → implementer → tester
- Each subagent is a Markdown file with YAML frontmatter in
.claude/agents/ - The reviewer (haiku, read-only) analyzes code against 8 criteria and reports by priority
- The implementer (sonnet, edit
src/) fixes the problems found by the reviewer - The tester (haiku, execute-only) runs tests and reports results with failure analysis
- The tool restrictions guarantee that each agent only does what it's supposed to
- The chaining happens through Claude as an intermediary — each output is passed as context to the next agent
- The 3 files are copy-paste ready — you can use them in any project with
src/and tests - The main limitation is the lack of memory across sessions — Module 2 solves it
Next module: Module 2 (Agent Memory and Scopes) teaches you to solve your subagents' amnesia. You'll configure persistent memory so the reviewer remembers previous findings, the implementer accumulates knowledge of conventions, and the tester distinguishes regressions from pre-existing failures. The subagents you created here are the foundation — memory turns them into agents that evolve.