Every well-built subagent climbs the same ladder: it starts with a clear role, moves through the numbered steps and reaches a output format that any orchestrator can read. What separates a weak agent from a reliable specialist is this progression.
🎭 Role: "you are a senior…"
The first line of the body defines the identity from the agent. This isn't vanity — it's a signal of expertise. The model calibrates vocabulary, depth, and tone based on this statement. A well-written role sentence is worth more than ten paragraphs of vague instructions.
Anatomy of an effective role
A complete role has three parts: level (senior / staff / principal), domain (security engineer / code reviewer / technical writer) and operational context (working in a production codebase / reviewing PRs / writing for developers).
✓ Effective role
- ✓ "You are a senior security engineer reviewing production Python code for OWASP vulnerabilities."
- ✓ "You are a staff technical writer creating developer documentation for a REST API."
- ✓ Includes the specific domain + usage context
✗ Weak role
- ✗ "You are a helpful assistant." — too generic, no domain cues
- ✗ "You are an expert." — without specifying what in
- ✗ Omit the role entirely
Tip: test your role by asking "what vocabulary would a [your role] use?" — if the answer changes between "helpful assistant" and "senior security engineer", the role is doing real work.
🔢 Numbered steps: "when invoked: 1…"
After the role come the execution steps — the exact sequence the agent should follow every time it’s invoked. Numbered steps turn emergent (unpredictable) behavior into reproducible.
Why number them?
The model tends to follow numbered lists more faithfully than paragraphs of instructions. Numbering creates a explicit execution contract — skipping a step becomes visible to whoever reviews the output.
📄 Output format
The orchestrator will read what the subagent returns. If the format varies, the orchestrator needs extra logic to parse it. A declared output format in the agent's body eliminates this variation and makes integration trivial.
Section ## Output Format in the body
Explicitly state the format in a separate section from the body. Use Markdown for structure
and code fences to show the exact expected schema.
Respond with a Markdown document containing:
- **Summary**: 1–2 sentences
- **Findings**: numbered list, each with severity (HIGH/MED/LOW)
- **Recommendation**: one actionable fix per finding
Do not include any other sections.
✓ Structured format
- ✓ Dedicated section
## Output Format - ✓ Named fields with types (string, number, list)
- ✓ JSON schema when the orchestrator will parse it automatically
✗ Free-form format
- ✗ No format declaration — output varies with each invocation
- ✗ "Respond in prose" for automated integrations
- ✗ Optional fields with no declared default value
Tip: when the subagent will return data for another agent to process, prefer JSON over Markdown — it’s easier to parse programmatically. Use Markdown when the output is for people to read directly.
🚫 What NOT to do
Declaring explicit constraints is just as important as stating what to do. The model knows more than you want it to use—the section on not doing sets the scope and prevents the agent from "overhelping" outside its role.
Section ## Constraints
Use a section ## Constraints or
## Do not to list
prohibited behaviors. Each restriction should be actionable — not vague.
- Do not fix code — only report findings
- Do not comment on style — focus on security only
- Do not escalate to the user — return results to orchestrator
- Do not hallucinate CVE numbers — say "unverified" if unsure
⚠️ Empty restrictions don't work
"Do not do anything harmful" is not an actionable constraint—the model already has guardrails for that. Useful constraints are specific to the agent’s domain: "do not suggest architectural changes" (for a code reviewer), "do not translate content" (for a qa-checker).
⚡ One agent, one task
The biggest mistake in an agent’s body isn’t what’s there — it’s what’s more. Agents that do multiple things don’t do any of them well. The test is simple: if you can put a "and also" in the agent's role, it needs to be split up.
The "and also" test
Review the code for bugs,
and also suggest improvements,
and also update the docs,
and also check security.
security-reviewer: OWASP checks
doc-writer: update docs
refactor-advisor: suggest improvements
Practical tip: when an agent takes too long, produces large, hard-to-parse outputs, or gets "confused" between operating modes — it’s a sign it’s trying to do too much. Split at the "and also" point.
🔧 The body invokes skills
A subagent can use skills registered in the system — it invokes them by name, with a command in the body. This allows the agent to delegate parts of the work to specialized skills without having to reimplement behaviors that already exist.
How to declare in the body
1. Read the target file(s) fully.
2. Use the `impeccable` skill to check prose quality.
3. Apply findings to the output.
4. Return a diff-style summary.
The skill’s usage instructions go in the numbered steps—not in the role. The role defines who the agent is; the steps define what it uses.
✓ Correct delegation
- ✓ Skill invoked at a specific, numbered step
- ✓ Skill result integrated into the final output
- ✓ Skill does one thing; agent orchestrates the workflow
✗ Common problems
- ✗ Invoke a skill without using the result (token waste)
- ✗ Call a skill that does exactly what the agent already does
- ✗ Invoke multiple skills without an ordering criterion
🔁 Iterate with feedback
An agent’s body doesn’t come ready-made. The first version works 70% of the time — the other 30% reveals what’s missing or wrong. Iterate with real feedback is what separates an agent that "works sometimes" from one that is "reliable in production."
Practical rule: if you had to explain it to the orchestrator "the agent returned X, but you should ignore part Y", that’s a sign the fix should be in the agent’s body, not in the orchestrator’s logic.
Real example: security-reviewer.md
Below is a complete security review subagent body. Each section demonstrates one of this module’s concepts applied together.
Why this body works
- → Specific role: seniority + domain + scope (Python/TS, production)
- → Checklist steps: 5 steps that cover the entire workflow without ambiguity
- → Declared format: 3 named sections with an exact structure
- → Actionable restrictions: 5 security-domain-specific prohibitions
Detailed content
Use when you already have a documented process and want to turn it into an agent.
Use it to review agents that “almost work” and identify what’s missing.
Use when an agent does everything but does nothing well.
Simulated screen: invoking the security-reviewer
The orchestrator invoked the security-reviewer
in an authentication file. See how the structured body produces consistent, parseable output.
Exercise: split up a do-it-all agent
Apply what you learned in this module.
The problematic agent
Your task
- 1 List all separate responsibilities of this agent (apply the “and also” test)
- 2 Suggest 3 specialized agents (name + one-line role for each)
- 3 Write the full body of one of the agents: role + numbered steps + output format + constraints
Completion criterion
- ✓ You identified ≥4 separate responsibilities in the original agent
- ✓ Each proposed agent passes the “and also” test — zero overlap in responsibilities
- ✓ The body you wrote has a specific role (level + domain + context)
- ✓ The numbered steps cover the complete workflow without “and also”
- ✓ The output format is declared and could be parsed by another agent
- ✓ The constraints are domain-specific — not generic