DeepDojo.AIPublished 2026-11-12中文
A Read-Only Code Review Subagent for Claude Code
Every time you ask a subagent to review code, you repeat the same paragraph: read-only, don't edit files; give a file and line for every finding; don't pad the list with style preferences; if nothing turns up, say what you checked. By the fifth time, you start wondering whether those requirements could become a fixed review role you can call on whenever you need it.
Claude Code supports exactly that. Drop a Markdown file into .claude/agents/, use frontmatter at the top to limit its tools, model, and permissions, and write its working method in the body. The format is easy; the boundaries are where people slip. A few common misunderstandings:
- leaving out
toolsand assuming it'll only read, when it actually inherits all of the main session's tools; - writing
permissionMode: plan, then watching it switch along with the main session the moment that session moves toacceptEdits; - turning on persistent memory and quietly giving a read-only role the ability to write files.
Defining a reliable role takes two things: frontmatter that limits capability with the fewest tools and a suitable model, and a body that spells out inputs, method, evidence, and output format. Every time you add a capability, go back and check tools and permissions. We'll build a code-reviewer from scratch.
01 When a Role Is Worth Defining
For a one-off investigation, a temporary subagent is fine. Once you keep needing the same kind of review and keep restating the role, tools, and output format, save those stable requirements as a custom agent. Fixed-standard auth reviews, failure analysis, read-only database queries, and screenshot acceptance are all candidates once they recur.
Project agents go in .claude/agents/. They fit the current repository and can be committed to Git for the team to maintain together. Personal agents for use across projects go in ~/.claude/agents/.
When agents share a name, sources are chosen roughly in this order:
Managed → --agents temporary definitions → project → user → pluginWithin a project, Claude Code searches from the current directory up to the repository root, and the nearest definition with that name wins. The name in frontmatter is the agent's identity, and it should be unique within its scope: the Claude Code subagents documentation explains that if two files in the same .claude/agents/ directory declare the same name, only one loads, chosen by filesystem read order rather than a documented precedence. /doctor can check for this.
02 A Complete Read-Only Reviewer Definition
For a read-only reviewer, start by deciding what material it needs. Here the main session supplies the diff text or files, and the agent uses read tools to inspect related implementation and tests. Put that input agreement and the role's limits into a Markdown file with YAML frontmatter:
---
name: code-reviewer
description: Review changed code for correctness, security, and regression risk. Use proactively after code changes.
tools: Read, Grep, Glob
model: sonnet
permissionMode: plan
maxTurns: 12
color: blue
---
You are a read-only code reviewer. Do not modify any files.
First confirm the scope and diff supplied by the main session, then read related implementation and tests.
If no diff is supplied, report the missing input. Do not treat unreviewed work as having passed.
Report evidence-backed issues; do not add style preferences simply to increase the finding count.
Each finding must include:
1. Severity.
2. File and line.
3. Trigger and actual impact.
4. Evidence supporting the judgment.
5. The smallest viable fix.
If no issue is found, state the checked scope and remaining unverified risks.Frontmatter limits capability; the body explains the method, evidence, and result. Edit .claude/agents/ directly or have Claude create the file from clear requirements. Claude Code watches existing agent directories and picks up changes within seconds; if the directory didn't exist when the session started and you've just created the first agent file in it, restart to load it.
03 Field by Field: Where the Boundaries Are
Look at the fields one at a time:
| Field | What It Controls |
|---|---|
name | Unique identifier, in lowercase letters and hyphens |
description | Tells the main session when to delegate |
tools | Available tools |
model | A model alias, full ID, or inherit |
permissionMode | The mode you'd like it to use; the main session may override it, so tools still need restricting |
maxTurns | The maximum number of turns; at the limit it returns output marked as partial |
color | Display color in the list; doesn't change capability |
Only name and description are required. Leave out tools and the agent inherits the main session's tools. Listing the fewest tools the role needs makes its capabilities easy to see. The Claude Code best practices put it plainly: give a custom subagent in .claude/agents/ only tools: Read, Grep, Glob, and it becomes a reviewer that can't edit anything, with that limit enforced by Claude Code rather than requested in a prompt.
tools lists allowed capabilities explicitly; disallowedTools removes a few tools from what's inherited, such as Edit and Write. When both are set, disallowed tools are removed first, and then the allowlist is applied. The docs also note that an entry with a specifier in disallowedTools, like Bash(git push *), still removes the whole tool.
For a read-only role, exclude Edit and Write first. If it needs Bash, restrict the actual commands with permissions, the sandbox, or a Hook. permissionMode: plan alone isn't enough: the subagents documentation explains that when the main session is in auto, acceptEdits, or bypassPermissions, the subagent follows that mode and ignores the value you set. The differences between modes are covered in how to choose a Claude Code permission mode.
A description should cover the task type, when to delegate, and the boundaries, so the main session delegates in the right situations:
description: Review changed authentication and authorization code for correctness, security, and regression risk. Use proactively after relevant changes; do not modify files.The body should fill in inputs, required material, the order of judgment, constraints, result structure, and what to report when nothing is found. "You're a senior expert, please be careful" carries none of that and can't make up for missing background from the main session.
04 Pick a Model for the Task, Preload Skills as Needed
Choose a model by task complexity and the capability it needs:
| Task | Model Approach |
|---|---|
| Locating files, simple extraction, format checks | Consider Haiku first |
| Routine review, debugging, and code comprehension | Consider Sonnet first |
| High-risk architecture decisions, complex root-cause analysis | Use Opus when needed |
| Closely tied to the main session, and you're unsure | Use inherit |
When picking a model, first confirm it can do the job, then compare speed and cost. A model that falls short and needs rework costs money too. A light model is a good fit for simple extraction; for complex judgment, choose based on what the task actually requires.
skills preloads specialist knowledge when the agent starts:
skills:
- api-conventions
- security-reviewPreloading puts each Skill's full text into the agent's starting context; the docs specify that the whole skill body goes in, beyond its description. Add only the methods the task needs so unrelated material doesn't take up space and attention.
05 Three Ways to Invoke It
Choose an entry point by how much control you need:
| Need | Invocation and Boundary |
|---|---|
| Everyday delegation | Say "use code-reviewer to review the auth changes"; the main session still decides |
| Make sure a specific agent runs | Pick it with @ in the input box, such as @"code-reviewer (agent)" |
| Use one role for the whole session | Start with claude --agent code-reviewer, making its system prompt, tools, and model the main thread's identity |
In everyday delegation, the message you hand it still has to be self-contained; see briefing a subagent and checking its findings.
06 After Turning On Persistent Memory
A new ordinary subagent doesn't carry over the last conversation; only explicitly resuming an existing instance continues its history. To build up project patterns, debugging experience, or architecture decisions across sessions, set a memory scope:
memory: projectThe three scopes are:
| Scope | Location | Good For |
|---|---|---|
user | ~/.claude/agent-memory/<agent-name>/ | Personal lessons that apply across projects |
project | .claude/agent-memory/<agent-name>/ | Project-specific knowledge that can be shared with the team |
local | .claude/agent-memory-local/<agent-name>/ | Project-specific personal notes that shouldn't be committed |
Once enabled, the agent's system prompt includes the first 200 lines or 25KB of MEMORY.md in its memory directory, whichever comes first. Keep the entry as a short index and put details in topic files.
Save stable constraints, recurring failures, and verified paths that will still shape judgments next time. Leave full test output, temporary branch state, and guesses in the current task. Note the version, scope, and where to recheck each lesson. An old "logout misses token revocation" shouldn't be recorded as a permanent defect; update it when the code changes.
Turning on memory adds read and write tools for maintaining notes. The docs state that with memory enabled, Read, Write, and Edit are automatically enabled so the subagent can manage its memory files. A role that used to be read-only has gained write access, so recheck its tools and permissions; if it should only maintain memory, limit writes to the memory directory.
The paragraph you used to repeat every time now lives in code-reviewer.md: three read tools, and a body that spells out evidence and output format. Each time you give it something new, like memory, Bash, or another Skill, take a moment to check that it's still the read-only reviewer you meant it to be.