Give each agent its own model
You’re about to map a part of feedmill you don’t know yet. The repo carries something north of a hundred feed configs, each one declaring how a particular source’s dates, GUIDs, and content fields are shaped, and you need to know where in the parser code every one of those date layouts actually gets consumed — because the timezone bug you’re chasing might live in any of them. That’s a wide, dumb sweep: read a lot of files, grep for a pattern, report back. It is exactly the kind of work a cheap, fast model finishes for pennies.
So watch what it costs when you don’t think about which model does it. You’re sitting on the build agent with your strong reasoner behind it — the one you want for the actual timezone fix — and you fire off the scan:
> find every place in the parser package where we call time.Parse or otherwise turn a feed's raw date string into a time.Time, and list the file and the layout string used at each oneIt works. It reads thirty-odd files, walks the configs, and comes back with a clean table. But it did all that bulk reading and pattern-matching on a frontier reasoning model billed at frontier rates — you paid reasoning prices for grep work. Do that twenty times across a week of exploring an unfamiliar codebase and the waste isn’t a rounding error; it’s most of your bill, spent on the cheapest kind of task you have.
The fix: send the scan to a cheap, read-only scout
Section titled “The fix: send the scan to a cheap, read-only scout”OpenCode ships a built-in subagent for precisely this. explore is a fast, read-only agent — it cannot modify files, so handing it a codebase sweep carries no risk of a stray edit — and you invoke it by @mention right in your prompt:
> @explore find every place in the parser package where we call time.Parse or turn a feed's raw date string into a time.Time, and list the file and the layout string used at each oneOpenCode spawns explore in its own child session with its own context window, runs the scan there, and returns a summary to your main thread — your build session’s context stays clean instead of filling up with thirty files of parser source. That isolation alone is worth the @mention. But by default, when explore has no model of its own, it runs on the model of whichever primary agent invoked it — which is very likely your expensive one. The lever this lesson is about is the next step: give explore its own model, a cheap one, so the scan is cheap by construction every time you reach for it.
Pin a model in the agent’s frontmatter
Section titled “Pin a model in the agent’s frontmatter”Every OpenCode agent — built-in or your own — is configurable through a markdown file with YAML frontmatter, and one of the fields is model. Set it and that agent overrides the default; leave it off and the agent inherits a model — but which model depends on what kind of agent it is. A primary agent with no model set uses the globally configured model. A subagent like explore with no model set inherits the model of the primary agent that invoked it — not the global default. That’s exactly why pinning a model on explore is what makes it cheap: otherwise it rides along on whatever your build agent is using. The value is a provider/model-id string, the same shape you’ve used everywhere else in this chapter.
To override a built-in agent, drop a file with its name into your agents directory — .opencode/agents/explore.md in the project, or ~/.config/opencode/agents/explore.md for every project on the machine. (The singular .opencode/agent/ still loads too, as a backwards-compat alias, but agents/ is the canonical form.) You only have to specify the fields you’re changing; OpenCode merges your file field-by-field over the built-in definition, so the rest of explore’s built-in setup (read-only, the right tools) stays as shipped.
---description: Fast read-only codebase scoutmodel: anthropic/claude-haiku-4-5---That’s the whole change. The next time you @explore anything, the scan runs on the cheap model and your wallet stops noticing it. Meanwhile your default build agent — the one your top-level prompts run on, and the one that’ll handle the actual timezone fix — is untouched, still pointed at the strong reasoner. You’ve split the spend exactly where it should split: cheap throughput for reading, strong reasoning for changing.
Why this is the move, not just a tidy trick
Section titled “Why this is the move, not just a tidy trick”The shape you’ve just set up — a cheap, read-only explore and a strong build — is the canonical OpenCode posture, and it pays back every time you scale work out across agents. Reading is the cheap, high-volume half of agentic coding: scanning, grepping, mapping, summarizing. Changing is the expensive, low-volume half: the reasoning that has to be right because it touches your code. A single model has to be priced for the hard half, so running the easy half through it is pure overpayment. Per-agent model lets you stop doing that without thinking about it again — the routing is baked into who does the work, not decided fresh on every prompt.
Dial the judgment by hand once and both leaks price themselves — the pinned expensive default and the false economy of running everything cheap. Per-agent models are this widget’s left dial made permanent: the scout lives on the light setting, the build agent on the capable one.
It also composes with what’s coming. When a later chapter fans a big job out across subagents, every one of those workers inherits the model you pinned to it, so the cheap-scout / strong-builder split scales for free instead of being a choice you re-make per task. And it’s a genuine OpenCode differentiator: a single-vendor agent can dial effort up and down, but it can’t put a structurally cheaper model behind the cheap work, because it only has the one vendor’s lineup. OpenCode can reach across 75+ providers for the scout and keep a frontier reasoner on the build loop — different models, different providers, different prices, one session.
One caveat worth stating plainly: a cheaper scout is cheaper because it’s weaker. For a mechanical sweep — “list every call site of this function” — that’s a fine trade. Don’t quietly let it creep into work that needs judgment; if a scan turns into “and figure out which of these is the bug,” that’s reasoning, and reasoning belongs back on the strong model. Pin the model to match the kind of work the agent does, and re-check the fit when the work changes.
Two providers wired, models switchable mid-session, and now a model pinned to each agent so the cheap and strong work route themselves. Next, point both at the same task at once and let them argue: Run two providers side by side.