
Ship a Read-Only Code Reviewer as a Claude Sub-Agent in 15 Lines
Chris Harper
3 min read
Jun 29, 2026 · 04:05 UTC
TL;DR: A 15-line markdown file in .claude/agents/ creates a reusable named sub-agent with its own tool restrictions, system prompt, and model — and Claude auto-delegates to it without being told.
Every time you write > review the diff for bugs or > search the codebase for usages of X, you're manually orchestrating a throwaway sub-agent. If you repeat that instruction more than twice a week, bake it into a reusable agent definition instead. Here's how.
The format
A sub-agent is a Markdown file in .claude/agents/ (project scope, checked into your repo) or ~/.claude/agents/ (user scope, all your projects):
---
name: code-reviewer
description: Use when asked to review code for bugs, performance, or style issues. Reads files and returns findings — does not write anything.
tools: Read, Grep, Glob, Bash
model: claude-haiku-4-5-20251001
---
You are a strict code reviewer. Given a list of changed files, identify:
1. Bugs — logic errors, edge cases, null dereferences
2. Performance problems — N+1 queries, unnecessary allocations
3. Style violations — dead code, overly complex conditionals
Return findings as a numbered list: file path + line range, problem, minimal fix. Do not modify any files.
That is it. Drop it into .claude/agents/code-reviewer.md and Claude will start delegating code review tasks to it automatically.
Why the description field drives everything
Claude reads description: to decide when to delegate. A vague description ("use for reviewing code") leads to under-delegation. Write it as a precise delegation trigger: "Use when asked to review code for bugs, performance, or style issues." The more exact the trigger, the more reliably Claude reaches for it.
Restrict tools to match the job
The tools: field is a comma-separated list of tool names (Read, Edit, Write, Bash, Grep, Glob, Agent). Omitting Edit and Write from a reviewer keeps it read-only even when the parent session has full edit permissions. This is the right default for any sub-agent that should not mutate state.
Route cheap tasks to a cheaper model
Set model: to claude-haiku-4-5-20251001 for fast, low-cost passes — summaries, linting, pattern searches, test generation. Leave it at the default (Sonnet or Opus) only for tasks requiring deep reasoning. On high-volume workflows, this alone can cut sub-agent costs dramatically.
Project vs user scope
| Location | Scope | When to use |
|---|---|---|
.claude/agents/ | This repo only | Team-shared agents; check in to the repo |
~/.claude/agents/ | All your projects | Personal agents for your own workflows |
Project-level agents get checked into the repo so the whole team benefits from the same reusable workers. The blog-editor and frontend-reviewer in this blog's own .claude/agents/ directory are live examples of exactly this pattern.
Sources: Create custom subagents — Claude Code Docs · Configure permissions — Claude Agent SDK