November 15, 2026 · 13 min read
Claude Code Subagents Workflow: What a Helper Carries When It Starts

Claude Code subagents workflow: what does a helper carry when it starts? Most guides show how to create one. Almost none show what it brings with it.
I made a video about the mistake I made with subagents, and the three fixes I use now. This article has what the video has no room for: what the official docs say a subagent receives at startup, the table that compares a fork with a fresh helper, the numbers from my own logs and how sure I am of each, the brief and the settings you can copy, a way to test it yourself, and what I did not test.

The short version
- A subagent starts with a fresh, isolated context window. It does not see your conversation history. The exception is a fork, which inherits the whole conversation.
- A fork can start big. In my own logs, a fork from my chats started near 250,000 tokens, and a fresh helper near 120,000.
- Fix 1: do not fork. Start each helper fresh with a three-line brief: the folder, the job, and where its rules are.
- Fix 2: load the rules by stage, so a helper reads only what its stage needs.
- Fix 3: a check at the door that refuses work without a receipt that the rules were read.
- The docs also say a fork can cost less than a fresh subagent when the job needs the same context. So a fork is a tool, not a mistake. Mine was using it for everything.
I have run my own company for 22 years. Every day I hand real work to dozens of Claude Code chats, each with its own job. My videos go through four stages: the script, the screen, the carousel posts, and the publishing. Each stage has its own helper, and often several at once, so I send out helpers all day. The docs I quote below are the official subagents page, which I saved on November 8, 2026.
What a subagent is


Think of Claude as a manager at a desk. When a job needs a lot of digging, the manager does not read everything personally. It sends a helper into another room. The helper reads the files, runs the searches and does the messy work. Then it walks back with one short note. From here on I call a subagent a helper.


The docs say: "Use one when a side task would flood your main conversation with search results, logs, or file contents you won't reference again: the subagent does that work in its own context and returns only the summary." They also say: "It also sends its own requests, which count toward the same usage limits as your main conversation." The second sentence is the one I had not thought about. The helper keeps your main chat clean. It does not make its own work free.

What a helper receives when it starts

The docs, under "What loads at startup": "Each subagent starts with a fresh, isolated context window. It doesn't see your conversation history, the skills you've already invoked, or the files Claude has already read. Claude composes a delegation message that summarizes the task, and the subagent works from there. The exception is a fork, which inherits the parent conversation instead of starting fresh." So a helper is not empty. This is what a non-fork helper starts with, as the same page lists it.
| What a non-fork subagent starts with | Notes from the docs |
|---|---|
| Its own system prompt | Not the Claude Code system prompt. Plus environment details Claude Code appends |
| The task message | The delegation prompt Claude writes when it hands off the work |
| CLAUDE.md files | Every level of the hierarchy the main chat loads. Explore and Plan skip them. A custom subagent skips them with omitClaudeMd: true |
| Git status | A snapshot taken when it starts. Explore and Plan skip it |
| Preloaded skills | Only the skills named in its skills field |
| Sibling roster | Only if it has SendMessage and another agent has a name |
One line in that list matters for the rest of this article. CLAUDE.md is loaded into a non-fork helper too, at every level. The docs say the main chat still has your full CLAUDE.md when it reads the helper's result, so most rules do not need to reach the helper. If one must, restate it in the delegation prompt. That is the opposite of what I was doing. I loaded long rule files into every helper.
The exception: a fork

The docs: "A fork is a subagent that inherits the entire conversation so far instead of starting fresh. This drops the input isolation that subagents otherwise provide: a fork sees the same system prompt, tools, model, and message history as the main session, so you can hand it a side task without re-explaining the situation." Here is the comparison table from the same page.
| Fork | Non-fork subagent | |
|---|---|---|
| Context | Full conversation history | Fresh context with the prompt you pass |
| System prompt and tools | Same as main session | From the subagent's definition file |
| Model | Same as main session | From the subagent's model field |
| Prompt cache | Shared with main session | Separate cache |
Two more facts from that page. First, Claude can start a fork on its own while fork mode is on, and fork mode is on by default (from Claude Code v2.1.302, and in an interactive terminal session from v2.1.232). Second, the page says: "Because of that reuse, a fork costs less than a fresh subagent for tasks that need the same context." The reuse it means is the parent's prompt cache. I will come back to that, because it changes how I read my own numbers.
My mistake, and the numbers
My mistake was simple. I forked everything. It felt smart. A forked helper already knows the whole story, so I never had to explain the job. But a helper that knows everything also carries everything, and I never looked at what that cost. So I went to my own conversation records. In my records, each helper's conversation is saved as its own file, under a subagents folder inside the session's folder.

| What I counted | Number | How sure I am |
|---|---|---|
| Answers from my main chats and their helpers in one day | about 12,000 | Counted from my own conversation records. Not re-measured since |
| A fresh helper, before its first action | about 120,000 tokens | Same count |
| A helper forked from my chats on this channel, before its first action | about 250,000 tokens | Same count. More than double the fresh one |
| Four rule documents loaded by every chat and every helper | about 70,000 tokens in total | From my own notes on how the files were loaded |
The 12,000, the 120,000 and the 250,000 come from one day of records. I have not re-measured them since, and I say so in the video. The 70,000 is the size of four long rule documents (my strategy notes, design guide, checklists and past insights) that every chat and every helper read at the start. Most of it was never needed for the job at hand. A helper writing a script does not need the rules for posting.

And a helper does not read its starting load once. The Claude Code docs say it sends your full conversation with every request, so every answer reads it again. That is why the starting size matters. It is the base that every answer pays on.
Fix 1: a three-line brief, and no fork

I stopped forking. I start each helper fresh with a brief of three lines: the folder to work in, the job to do, and where the rules for this job are. I also say what to send back: the path of the finished file and one line. Nothing else.

Why one line back? Everything a helper returns lands in my main chat, and a long report would refill the space I am trying to protect. This is a brief from my own work, for the script stage:

FOLDER: this_episode/
JOB: write the script
RULES: run rules.py script first
RETURN: file path + one line
You can reuse the shape. This is the prompt I put in the video description. It is the same as the one under the video.

Create a helper for this job. Do not fork. Give it a brief with three lines:
FOLDER: <the folder it works in>
JOB: <what it must do>
RULES: <where its rules are, for this stage only>
Ask it to return a file path and one line, nothing more.
Does a fresh helper make more mistakes, since it knows less? That is exactly why the brief points to the rules, and why Fix 3 exists.
Fix 2: load the rules by stage

I wrote a small program called rules.py. When a helper starts the script stage, it runs the program with the stage name, and the program prints only the rules for scripts. The screen stage and the posting stage work the same way. Each helper reads only what its stage needs, instead of all four documents. The program also leaves a small receipt file in the episode folder, as proof that the rules were read.

episode/
lines.json
timeline.json
.rules-script.json <- the receipt: written when the stage rules were printed
video.json
When I made this change, I told each of my three lead chats the same two things. Never fork a helper. And save a handoff note at every natural break.
Fix 3: a check that refuses work without a receipt
When a helper registers its work for my review, a small program looks for the receipt. If there is no receipt, or the rules were changed after they were read, the registration is refused. I built it this way because a helper that skips the rules gives me work I have to redo, and redoing costs more tokens than anything else. The receipt in Fix 2 and the check in Fix 3 are what make the short brief safe.
The settings that control all of this
These are in the official subagents page. I read them and did not test each one.
| What you want | Setting, as the docs describe it |
|---|---|
| Stop Claude from starting forks, keep everything else | "Agent(fork)" in permissions.deny |
| Turn fork mode off | CLAUDE_CODE_FORK_SUBAGENT set to 0. Claude can then wait for a subagent in an interactive session |
| Limit how deep helpers can start helpers | CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH. The default is three layers below the main chat. 1 turns nesting off |
| Limit how many run at once | CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS. The default is 20 running at once |
| Keep CLAUDE.md out of one subagent | omitClaudeMd: true in its definition |
| Limit what one subagent can touch | A tools list in its definition |
| Run a light job on a lighter model | A model field, for example haiku |
{
"env": {
"CLAUDE_CODE_FORK_SUBAGENT": "0",
"CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH": "2",
"CLAUDE_CODE_MAX_CONCURRENT_SUBAGENTS": "8"
},
"permissions": {
"deny": ["Agent(fork)"]
}
}
One more caution from the page. Turning fork mode off is also how Claude can wait for a subagent in an interactive session. If you only want to stop forks, the permissions.deny line is the narrower switch.
The docs also say the combined descriptions of your custom subagents can use context: past 15,000 tokens, Claude Code shows a warning at startup. Keep descriptions short and put detail in the subagent's system prompt, which loads only when it runs.
Here is a helper definition for a job like mine. I wrote it for this article, so it is an example, not a file from my machine.
---
name: script-writer
description: Writes the script file for one episode. Use for the script stage only.
tools: Read, Write, Grep, Glob
model: sonnet
omitClaudeMd: true
---
Read only the folder and the rules named in the brief.
Return the file path and one line. Do not paste the file.
When a fork is the right choice
Yes, a fork is sometimes right. The docs say to use one "when any other subagent would need too much background to be useful, or when you want to try several approaches in parallel from the same starting point." For a job like "try the other approach we just discussed", a fork saves you from retyping the whole discussion. And because a fork reuses the parent's prompt cache, the docs say it costs less than a fresh subagent when the job needs that same context. For a job I can describe in three lines, a fork is only baggage.
The main chat needs care too. The longer it runs, the more any fork has to carry. So at a natural break, such as after one video is finished, I save a handoff note and compact the chat. This is the prompt I paste for it. I wrote it for this article.
Before I compact this chat, write a short handoff note.
Keep it under 15 lines. Include only:
- What we finished
- What is left to do, in order
- File paths and commands the next chat needs
Save it to handoff.md.
Test it yourself
- Pick one job you can describe in three lines.
- Run it once as a fork, and once as a fresh helper with the three-line brief.
- For each, open the helper's saved conversation and look at the token counts recorded on its first answer.
- Compare the two starting sizes.
- Then compare the results. If the fresh one needs a lot of re-explaining, the job may be a fork's job.
What I did not test
- I have not re-measured the 12,000, the 120,000 and the 250,000. They are from one day of my own records and are as I said them in the video.
- Those numbers are the size at the start. They are not the share of my usage limit. Because a fork reuses the parent's cache, its starting size and what it costs against the limit are not the same thing, and I did not measure the second.
- So I cannot say how much of my limit the fork habit used, or how much the three fixes saved. The claim I will make is only about the starting size: the fresh helper starts at less than half of the fork.
- I did not test the settings in the table, and I did not run the helper definition above. They are from the docs, and the definition is an example.
- I did not test how much the stage rules and the receipt check save by themselves. I changed all three fixes together.
- I did not check whether fresh helpers make more mistakes than forks over a long run. The check in Fix 3 exists because I worried about it.
Who this is not for
- If you never start helpers, there is nothing here to fix.
- If you want a token count for a plan or a limit, this article cannot give one.
- If your helpers all need the same long context, a fork may be the cheaper choice, as the docs say. Measure before you change.

A helper that knows everything is a helper that carries everything. Give it a short brief, and let it travel light.
Sources:
- Claude Code Docs, create custom subagents (code.claude.com/docs/en/sub-agents), saved November 8, 2026
- Claude Code Docs, costs page (code.claude.com/docs/en/costs), quoted from my notes of November 11, 2026
- My own conversation records and my own rule-loading notes, November 2026