A subagent is a separate role with its own context window that returns a result to the main agent rather than a raw stream of work. There are three built-in roles: an explorer for wide search, a shell for checks by command and a browser for page work. The point of the mechanism is isolation: the noisy part of the work happens off to the side, and only a summary reaches the main conversation. The difference between a summary and a stream is not cosmetic: reading thirty files costs the main agent their whole volume, while the conclusion drawn from that reading takes a few lines.
The naive alternative is to do everything in one context. On a small task that is convenient; on a large one it starts to get in the way: search results, command output and intermediate hypotheses crowd out what the conversation was started for. A subagent solves exactly that problem - it does not speed the model up, it preserves your context, which is worth more than a couple of seconds of waiting. Isolation has its price too: the role does not see your conversation, and everything it needs to know has to be stated in the task explicitly.
There is a choice between two execution modes, and it matters. A role in the main flow blocks the agent until its result - that is right when the next step is undefined without it. A background role lets the main agent keep working - that is right for a long check whose result will be needed later. A mistake in that choice costs time in both directions: a blocking role on a long search turns work into waiting, and a background role where the answer is needed immediately makes the main agent guess and then redo the guesses.
Your own roles are defined by files in standard directories and described by a short header: a name, a description, the model, a read-only flag and a background flag. It helps to see such a definition in full once. Below is a migration auditor: read-only, an instruction to return findings by severity with exact file references and an explicit ban on editing files. The read-only flag carries the main load here: a role that physically cannot write will break nothing even if it is wrong. The description works no less hard: the main agent uses it to decide whether to call the role at all, so it is written as a condition of use rather than as a title.
The boundary between a role and a skill runs along purpose. A role is needed when work benefits from a separate context or from parallelism. A skill is needed when one role has to be taught a reproducible procedure. They are often confused, and the result is either a role without a procedure that does it differently every time, or a procedure without isolation that clutters the main conversation. The working combination is the ordinary one: the role sets the boundaries and the rights, the skill inside it sets the order of the steps.
Here is what that looks like on a real task. A field in a record sometimes turns out empty, and it is unclear what clears it. The main agent holds the plan and the hypotheses, while the search for every place that writes to the field goes to a read-only role with a precise contract: return the list of call paths and the condition under which the value is overwritten. What comes back is a table of a dozen rows instead of hundreds of lines of search output, and the conversation continues from where it stopped. The main agent never opens the files that have nothing to do with the case.
The quality of delegation is determined by the contract, not by the choice of role. Describe the input, the allowed actions, the result format and the stop condition. A task of the sort sort out the backend is not a task: it has neither boundaries nor a sign of completion, so the role decides for itself when to stop, and it usually decides earlier than needed. The wording read-only, find everyone who writes to this field and return a table of call path to invariant is checkable: the result is either in the specified format or it is not, and that is visible without reading the whole transcript.
Delegation has a limit of applicability. It loses where a task requires dense dialogue: the role cannot ask you a question along the way, and its only exit is the final summary. It also loses on small things: stating the task and reading the answer cost more than the work itself. The sign that delegation failed is simple in real work - after the summary the main agent goes into the same files itself. That means the result format was not specified and the summary gives no grounds for the next step.
The engineering conclusion about the number of roles is simple: they are created for a function, not for a name. A separate role is justified by context isolation, narrowed rights, a different model or a different cost. If the only difference is the name, it is an extra entity that will have to be maintained and edited on every change of the process. And it is worth remembering the platform's limits separately: the cloud agents API caps custom roles at twenty per run, and their names must be unique and must not collide with the built-in ones.
The typical failures are predictable. Giving a role write access where reading would have been enough. Sending work whose result is needed immediately into a background role. Setting a task without a contract and getting a summary that cannot be checked. And multiplying roles for the sake of names instead of one well-described role.
---
name: migration-auditor
description: Finds data-loss and rollback risks in database migrations.
model: inherit
readonly: true
is_background: false
---
Inspect the requested migration and its callers.
Return findings ordered by severity with exact file references.
Do not edit files.