Skip to content

Course · OpenCode · Subagents

Subagents

Every task you hand a coding agent carries a hidden question: where does the work happen? Your main session is one thread with one context window, and two kinds of job fit it badly. Anything that is mostly reading buries the decisions under the trawl it took to produce them, and anything whose slices don’t depend on each other waits in line for no reason. feedmill, the course’s illustrative Go feed aggregator, has one job of each kind waiting right now. The move that answers both is the subagent - a separate session with its own context window that does a scoped job off to the side and hands back only the conclusion. It is the counter-shape to a Skill: a Skill is a packaged routine the agent loads on demand, inside your conversation; a subagent is a second conversation entirely - its own context, its own permissions, its own model - running beside yours.

Delegation is also where OpenCode’s surface is unusually rich (as of October 2026; agents documentation). Its agents documentation lists three built-in subagents you invoke by @mention mid-prompt (the current release ships two of them; the next page has the detail), and the primary agent (the top-level agent you type at, such as build) can also dispatch a subagent itself, based on the subagent’s description. It also lets you author your own subagents, each with its own model and its own permissions. That last part is the lever. Model and permissions are set per agent: a built-in takes overrides in opencode.json, and a custom agent adds a new worker with its own description and prompt. A worker whose only job is to scan and report doesn’t need write access or your most expensive model, so you give it a cheaper model, lock down its permissions, and let it churn. Set no model and a subagent runs on the model of the primary agent that invoked it (same agents documentation, as of October 2026).

feedmill ingests differently-shaped feeds through parser adapters - one per source shape - and two things now need doing across all of them. Neither fits comfortably in a single thread, and they’re noisy in two different ways:

Find every place across the parser adapters that touches the dedupe hash - and separately, audit each adapter for the timezone bug class: a timestamp parsed out of the feed and stored as local time instead of UTC.

(In this chapter, feedmill has six adapters: the Atom path through internal/parse/atom.go and internal/adapter/normalise.go (which handles Atom feeds only), the JSON Feed adapter in internal/feed/json.go, and rss.go, rdf.go, reddit.go, and youtube.go, also under internal/feed/. Map them onto the parsers in your own repo.)

The first is a search, not a change: every adapter file to scan for every call site that feeds into the dedupe hash. You don’t want the file reads it takes to answer that - you want the answer. Run it inline and your context fills with grep output and file dumps you’ll never reread, crowding out the actual work.

The second is genuinely parallel: the same one-rule check, applied to every adapter independently. Each adapter parses timestamps its own way, so the UTC slip can hide in any of them - and which ones is exactly what a per-adapter check finds out. That’s not one big job - it’s the same small job repeated across many files that don’t depend on each other, which is exactly the shape that splits cleanly across workers.

Do both inline and you bury the decisions under a landfill of output the agent has to keep carrying. So we’ll do it the other way. The chapter’s pages, in reading order:

  • Meet the built-in subagents - general and explore, plus the scout the docs still list - and push the dedupe-hash scan into explore with a single @mention, so the file reads land in its context and only the call-site map comes back to yours.
  • Write a custom subagent when the built-ins don’t fit - your own markdown file with mode: subagent (agents documentation, as of October 2026), a per-agent model, and a permission set scoped to exactly what the job needs and nothing more, saved under .opencode/agents/.
  • Fan out across the feed adapters when the work is the same job repeated - dispatch a worker per adapter to check the UTC rule in parallel, and learn when that’s real leverage versus when it’s just showing off.

You could read these three pages as three disconnected tricks. Don’t. They’re one decision learned in three passes - should this happen in my thread, or somewhere else? - and they build in order. The built-ins teach you the @mention reflex and the read-only worker that answers without polluting your context. The custom subagent teaches you to shape a worker when the built-ins are the wrong fit - the cheaper model, the tighter leash. The fan-out then puts several of those workers to work at once on the parallel job.

Isolation has a price, so staying inline is sometimes the right answer. The worker starts without your thread’s context, and only its conclusion comes back. If your next step needs the raw lines it read, or the job is a quick lookup, keep it in your thread. By the end, that question - isolate, or stay inline? - is one you’ll ask before every noisy or parallel task on feedmill, and when the answer is isolate, you’ll know which of the three pages’ tools fits. Start by meeting the built-in subagents.