Sub-agents have teeth. They can read your files, search your codebase, run commands, write output, and report back. But they only bite as hard as the instruction you give them. And most people write instructions that pull every tooth out before the agent even starts.

I learned this the hard way. I have watched sub-agents produce five versions of the same task and every single one of them was wrong in a different way. The first version argued the wrong thesis. The second version exposed things that should have stayed private. The third version sounded wise but was hollow on inspection. The fourth version had the right structure but the wrong voice. The fifth version was practically useful but read like documentation instead of earned insight.

The model was not the problem. The model was the same every time. The problem was the instruction. Every time I fixed the instruction instead of the output, the next version got better. Every time I rewrote the output without fixing the instruction, the next version made the same mistake in a new way.

That is the thing nobody tells you about sub-agents. The instruction is the asset. The agent is just the executor.

KEY TAKEAWAYS
  • A one-sentence goal fails. The sub-agent has no definition of good, so it guesses. Every wrong guess costs tokens.
  • A step-by-step procedure fails. You solved the whole problem before delegating. The sub-agent added nothing.
  • A protocol works. Give the sub-agent a template for the output, hard rules it cannot break, a self-check it runs before submitting, and fences around what it can touch.
  • Iterate the instruction, not the output. When the sub-agent gets something wrong, add a rule. When it misses an edge case, tighten a fence. The instruction gets better. The agent stays the same.

The Two Failure Modes

Here is what most people write when they spawn their first sub-agent:

// FAILS: NO STRUCTURE Fix the null input bug in auth. Thanks.

The sub-agent searches for "null" and gets three hundred matches across forty files. It tries five approaches. It comes back with a fix that touches eleven files and breaks the login flow because it did not know that two of those null checks were intentional.

Here is what the same person writes after getting burned:

// FAILS: NO ROOM Read src/auth/validate.ts. Go to line 142. The function validateSession takes a token parameter. If token is null, the function crashes. Add a null guard at line 142 that returns an AuthError with code NULL_TOKEN. Import AuthError from src/errors/auth.ts. Do not modify any other functions. Do not touch the test file. After making the change, run npm run typecheck and confirm it passes.

They spent six minutes writing instructions for a twenty-second task they could have done themselves. The sub-agent was not an agent. It was a macro that cost tokens.

The first prompt gives the sub-agent teeth and no jaw. The second prompt pulls every tooth out and asks the sub-agent to gum the problem to death.

What Actually Works

Here is the same task written as a protocol. Took about ninety seconds. The sub-agent found the bug, discovered a second caller with the same issue, fixed both, and reported what it did.

// WORKS: A PROTOCOL Bug: validateSession crashes on null token input. Scope: Only touch files in src/auth/. Do not modify tests. Do not change any function signatures that other modules depend on. Before implementing: 1. Search src/auth/ for all callers of validateSession. Understand what types of input it actually receives, not what the type signature says. 2. Check if there are existing null-guard patterns in the auth module that establish a convention for how these are handled. 3. Read src/errors/ to find the error type that matches the existing error-handling style. Implementation: - Add a null guard at the top of validateSession. - Return an error type consistent with the rest of the module. - Match the code style of the surrounding file, including any existing early-return patterns. Before submitting, self-check: - [ ] Type checking passes - [ ] The fix compiles without errors Report back: - Files changed - Error type used and why - Whether any callers of validateSession needed updating

The procedure told the sub-agent what to type. The protocol told the sub-agent what good looks like, what failure looks like, where the fences are, and how to check its own work before you ever see it. One treats the sub-agent like a script. The other treats it like a tool that can find things you did not know were there.

Four Parts Every Instruction Needs

Every sub-agent instruction that actually works has these four things. You can adapt them to any domain — code, content, data analysis, research.

1. A template for the output. Show the sub-agent what done looks like. Not "write a report." A skeleton. "Report back: files changed, error type used, callers updated." The sub-agent fills in the values. You check the values against the categories instead of reading raw output and trying to figure out what matters.

2. Hard rules. Things the sub-agent can never do. "Do not modify tests." "Do not change public API signatures." "Never fabricate statistics." The sub-agent checks every rule before submitting. If a rule is violated, it reports the violation instead of silently submitting bad output.

3. A self-check. The sub-agent validates its own output before you see it. A checkbox list at the end of the instruction. "Type checking passes. Fix compiles. All rules verified." The sub-agent is its own QA department. You review the exceptions, not the baseline.

4. Fences. What the sub-agent can touch and what it cannot. "Only src/auth/." "Read anywhere in the repo, write only to the output file." "The registry is append-only." The sub-agent explores freely inside the fences. It cannot cross them because the instruction explicitly says it cannot.

Use AI to Write the Instruction

The best way to build a good sub-agent instruction is to ask the AI to help you build it. You know your codebase. The AI knows how to structure instructions. Combine the two and you get something better than either of you could produce alone.

Here is a prompt you can use. Give it to the same model you are about to spawn the sub-agent from.

// PROMPT: ASK AI TO DRAFT A SUB-AGENT INSTRUCTION I need to delegate a task to a sub-agent that has file search, grep, bash, read, and write tools. The task: [describe your task in one sentence] Key context the sub-agent needs: - [file paths or modules involved] - [known constraints or edge cases] - [examples of similar work done correctly] - [things the sub-agent must NOT do or touch] The output I want back: [describe what you want the sub-agent to return] Produce an instruction that includes: 1. A clear outcome statement 2. Scope boundaries (what to touch, what to leave alone) 3. Things to investigate before implementing 4. Implementation guidelines 5. A self-check the sub-agent runs before submitting 6. The exact output format expected Keep it under 300 words. Specific enough to prevent predictable failures but not so detailed the sub-agent cannot add value through its own exploration.

Run this once. You get a draft instruction. Tweak it with what you know about your codebase — the assumptions nobody documented, the module the contractor wrote six months ago, the edge case that burned you last time. The AI cannot know those things. You can. Put them in the rules and the fences.

Iterate the Instruction

The first version of any sub-agent instruction will have gaps. The sub-agent will hit something you did not think of. It will make an assumption you forgot to forbid. It will miss an edge case that did not occur to you when you wrote the instruction.

That is fine. That is how instructions get better.

When the sub-agent comes back with something wrong, do not throw away the instruction and write a new one. Do not rewrite the output and hope the next attempt is different. Add the missing rule. Tighten the fence. Clarify the output template. Store the updated version. The next time you delegate a similar task, you start from the improved instruction, not from zero.

Over time, your sub-agent instructions become the most valuable documentation in your project. They encode your understanding of the codebase. They list every gotcha, every edge case, every unspoken assumption. A new developer on your team does not need to learn these things from experience. They load the instruction file and the gotchas are already documented as rules.

The sub-agent is not the asset. The instruction is.

What This Looks Like at Scale

The real advantage of instruction files over one-off prompts is what happens when you have more than one sub-agent running.

A one-off prompt costs you the same amount of thinking whether you delegate to one agent or ten. You write the prompt. You review the output. You fix the mistakes. You do the whole thing again on the next task because you threw away the prompt.

An instruction file costs more up front. You spend the time to think through the template, the rules, the self-check, the fences. But then you can hand that file to ten sub-agents at once, each executing independently inside the same boundaries. You do not supervise any of them. You review the exception reports and sign off.

The bottleneck moves from your attention to the compute. That is the whole game.

Write better instructions. Let the sub-agent do the fast part. Keep the thinking for yourself. And when the instruction breaks, fix the instruction, not the output.