Back to blog

Use Subagents to Keep Your Context Window Small and Relevant

July 6, 20267 min readBy Will Ness
Share:

Your coding agent performs best when its context window stays small and relevant. Each token of irrelevant context added to your context window reduces the odds of good output from the LLM, so the real skill of driving an agent is context engineering: deciding what gets into the window and what stays out.

Subagents are one of the most efficient ways to keep irrelevant context out of your window. Often, where you might reach for a skill, a subagent does the same job and hands back only the result. This article builds the mental models you need to use them well: what a context window actually is, how skills and subagents each change it.

A context window is a stack

Picture the context window as a vertical stack. Each thing the agent sees is one entry, added top to bottom in the order it happened:

  • System prompt: the agent's standing instructions
  • User message: what you asked for
  • Tool call: the agent does something, like reading a file or running a command
  • Tool output: what that call returned
  • (more user messages, assistant messages, tool calls and outputs as the work continues)
  • Assistant message: the agent's final reply back to you
Chat view
what you see
What testing framework does this project use?
Let me check package.json.
Calling Read
This project uses Vitest for its tests.
Context window
what the model sees

Click any entry on the right to expand it and see the raw JSON the model actually sees: each one is a real message from the Anthropic Messages API.

Two properties of this context window "stack" drive everything else:

  • It only grows. Entries are added, never removed, until you clear or compact the conversation.
  • The LLM re-reads the entire stack on every turn. More entries means more noise, and noise reduces the odds of high-quality output.

I've written before about why a fuller context window means lower-quality output (see clearing context between tasks); here I'll take that as given.

A pattern I use constantly: give your agent the gh CLI

For the rest of this article I'll lean on one running example: letting an agent use the gh CLI to explore your organization's code. This is a pattern I reach for all the time, and it has become a core part of how I use agents while working on a team.

The idea is simple: with the gh CLI, an agent can look into any repo in your organization to figure out how things fit together. Without it, your agent is constantly guessing about your other repos, unless you stop and explain each one, or clone them down locally.

A skill adds entries

When people want to get their agent to do something, they often reach for a skill. A skill is a block of content the agent pulls into the stack on demand: the instructions, examples, and rules written in a skill file. When the skill runs, it lands in the window as a tool call followed by a tool output, and that output is the skill's body. The agent then follows those instructions, and every tool call and tool result it produces along the way lands in the window too. From then on all of it lives in the window like any other entry, visible on every future turn.

SKILL.md
the file on disk
.claude/skills/org-github-explore/SKILL.md
---
name: org-github-explore
description: Answer questions about the org's codebase with the gh CLI.
---

Use the gh CLI to explore the organization's repositories.

## Examples
- gh search code "<term>" --owner acme --match path
- gh api repos/{repo}/contents/{path} \
    -H "Accept: application/vnd.github.raw"

## Notes
- Prefer --match path to find files by name.
- Read the source of truth in full before answering.
Context window
after the skill runs

When that content stays relevant, adding it is exactly what you want. When it doesn't, you have just parked noise in the window for the rest of the conversation. Which case you are in is the whole question, and we will come back to it.

A subagent keeps entries out

A subagent, from your main agent's point of view, is also just a tool call: one call that produces one output. The difference is what happens when that call fires. Spawning a subagent spins up a brand new, separate context window with its own system prompt and the prompt your main agent sent it. Inside that window the subagent does the work: it generates tool calls, runs them, reads the outputs, and keeps going until it finishes with a single final assistant message. None of those tool calls or outputs land in your main agent's stack. Only two entries ever cross back into your window: the prompt your main agent sent in, and the one final message the subagent returns.

Just like a skill, a subagent is a file on disk. Its body becomes the system prompt of a brand new, separate context window:

Main agent
what it keeps
org-github-explore.md
the subagent file
.claude/agents/org-github-explore.md
---
name: org-github-explore
description: Explore the org's GitHub codebase and return only the answer.
tools: Bash, Read
model: haiku
---

You are an org codebase explorer with access to the gh CLI.
Answer the calling agent's question about the organization's
repositories.

- Search: gh search code "<term>" --owner acme --match path
- Read:   gh api repos/{repo}/contents/{path}

Return ONLY the values you were asked for. Never paste search
results or full file contents.
Subagent
its own window
The only context kept is the prompt and the final message.

So from your main agent's seat a skill and a subagent look almost identical: a single tool call, a single output. Underneath, they differ on two axes:

  • What they do. A skill only loads content. A subagent goes and performs a task.
  • What happens to the context window. With a skill, all of it stays in your window: the skill's body, plus every tool call and result the work produces. With a subagent, all of that stays in its own window instead, and only the final result comes back to yours.

Subagents keep the process out of your context window, while keeping the result of the process in your context window.

The same task, both ways

Here is a task where the choice has teeth. You are spinning up a new web app and you want it themed like the rest of your org's apps. You have already spec'd the app with your agent, so your window is full of useful context: the requirements, the decisions, the plan. The one thing your agent is missing is your org's theme (colors, typography, spacing, and so on), which lives in several other repos.

You know this information lives somewhere else in your GitHub organization, so the fastest way to get it is to have your agent search for and read the relevant files: a few gh CLI commands to list the theme files across the org, then read their contents. Here is what that work adds to a context window.

Chat view
what you see
Find our org's theme tokens by searching our repos with the gh CLI.
I'll find the org's theme source on GitHub.
Calling Bash · gh search
Calling Bash · gh api
Context window
finding the theme

Done in your main window, that work leaves all of this behind for the rest of the session:

  • that tailwind.config.ts exists in acme/design-system
  • that theme.ts exists in acme/web-app
  • that tokens.css exists in acme/ui-kit
  • ~210 lines from tailwind.config.ts
  • ~120 lines from theme.ts
  • ~80 lines from tokens.css
  • both gh commands

The agent needed exactly three values out of that pile: primary is #1f6feb, secondary is #8957e5, the font is Inter. Everything else is residue. It is never used again, and it doesn't leave until you clear or compact the conversation.

This is a decision you control. Before your agent takes on the next problem, picture the work it is about to do, then ask one thing: does that intermediate context belong in your main window? The agent has to do the work regardless. What you get to decide is whether the work itself becomes part of your context window going forward.

Without a subagent, all of that stays. Your agent runs the search and the fetches in your window, lands on the values, and the residue above sits there for the rest of the build, never referenced again.

With a subagent, you hand the job off, with a prompt as simple as "Launch a subagent to find our org's theme tokens." It runs the same search and fetches in its own window and returns one message. Your context window only gains:

  • the prompt telling the subagent to find the primary color, secondary color, and font from existing repos
  • the theme: primary color, secondary color, font

Now that we know what this work adds to a context window, let's look at what happens to your main window in each case: with a subagent, and without one.

Same task: “find our org's design tokens”
Without a subagent
the work runs in your window
With a subagent
the work runs in its own window

This is exactly the kind of task I reach for a subagent for. My main agent does not care about those three files, whether they exist, what is in them, or how to drive the gh CLI. It only cares about the answer.

When to reach for a subagent

The theme search was one instance of a broader move: reach for a subagent whenever the work is better off in a separate context than your main one. It shows up in three common forms.

The process is only needed for this one task. Some work is worth doing but not worth keeping around. Say you and your agent just built a feature, and before you open the PR you want screenshots of it for the description. Getting them means driving a headless browser: clicking through the feature, finding the right elements, capturing each screen. You want the screenshots, not a window full of Playwright calls and button ids, especially since that window still has work to do: a PR description to write, a Linear ticket to update, and the next task after that. So you hand it to a subagent. It does the clicking in its own window and hands back just the images.

The signal is buried in noise. Some valuable context exists somewhere, but you are not sure where, so the agent has to wade through a large amount of mostly-irrelevant material to find it: searching the file system, an MCP server, or any external source, like digging through Stack Overflow for a code reference to a niche problem. The answer you want is small, but finding it drags in a pile of context that is not the answer: the instructions for how to use the tool in the first place (say, a Google Drive MCP server), the tool calls themselves, and everything they return, from search results to file listings to full file contents. A subagent does the sifting in its own window and hands back only what survived. You get the two or three references that matter without the hundred you read to find them.

You want a fresh perspective. An agent reviewing its own work is grading its own homework: it is anchored to the choices it just made, so it tends to wave them through. A subagent that never saw your reasoning comes in cold and catches what the first pass missed. It is why I run subagents for code review, for adversarial "try to break this" passes, and for testing as a specific persona: a security auditor, a first-time user, a performance engineer. Same work, fresh eyes.

When to reach for a skill instead

Skills are for the opposite case, when the content itself is what you want to keep, because you will lean on it again and again.

Rules are the clearest example, and the best rules apply no matter what your agent is doing. "Communicate with me concisely" is a good one: it is relevant on every single turn, so you want it in the window the entire time. That is exactly the kind of content worth adding.

Other rules are task-shaped. If your agent is writing code, you want your code-style conventions loaded; if it is designing a feature, you want your architecture guardrails; if it is poking at production with the AWS CLI, you want the rules that keep it from breaking something. Those belong in the window too, just while that task is in front of it. Either way the test is the same: it is context you will keep leaning on, so a skill is how you add it. This is the case we left open earlier, the content that stays relevant.

Engineer your context window

To make it more complicated: subagents can use skills, and depending on the harness subagents can even call other subagents.

Because of all this, there is no clean flowchart for when to reach for a prompt, a skill, or a subagent. It depends on the task, your harness, and the context window you want to end up with.

The main takeaway here is: start visualizing your context window. Before you kick off a task, think through the tool calls your agent will have to make to finish it, then engineer your prompt to result in the most optimal context window. A few I reach for constantly:

  • Run a subagent to <x>, then once it returns do <y>.
  • Run a subagent to answer that question.
  • As you build out this frontend feature, whenever you finish a page, run a subagent to QA it and wait for its feedback before moving on.
  • Run a subagent that activates the do-cool-thing skill and follows its instructions. (a quick way to turn a skill into a subagent)
  • Spin up a fresh subagent to review this against the spec and list what it got wrong.
  • Run a subagent as a security auditor and have it try to break this endpoint.

The one question

So the whole decision collapses to a single question you can ask before any chunk of work: do I want what happens next to stay in my context window?

If the output is something you will reach for again, a rule you need on every turn, a fact the rest of the conversation depends on, keep it. Do the work inline, or load a skill. If you only want the result and the process is noise, hand it off to a subagent.

Want more like this? Get my best AI tips in your inbox.

Will Ness
Written byWill Ness

AI DevX Engineer at SurePath AI. Former Amazon engineer. I write about using AI effectively for work.

Recommended Articles