Claude Code as an Orchestrator: Using Cheaper Models to Ship Real Projects
A practical guide to running Claude Code like a small team: a strong orchestrator model that delegates design, implementation, review, and testing to cheaper, faster subagents. With ready-to-copy .md files.
Most people use Claude Code the same way they used a chat window: one powerful model, one long conversation, doing everything from reading the codebase to writing the code to running the tests. It works, but it is slow, it burns tokens on the expensive model for tasks a cheaper one could handle, and the context window fills up with noise from every file the agent grepped along the way.
There is a better mental model. Treat Claude Code like a small engineering team. One strong model acts as the orchestrator: it understands the goal, breaks it into pieces, and delegates. Cheaper, faster models act as the workers: they explore the codebase, run mechanical edits, and execute tests, then report back a short summary. The orchestrator never sees the 4,000 lines the worker read, only the two paragraphs that matter.
This article shows how to set that up for a real coding project, with copy-paste .md files, and a workflow that covers designing, implementing, reviewing, and testing.
The Mental Model: Orchestrator and Workers
The core idea rests on two features of Claude Code: subagents and per-agent model selection.
A subagent is a separate Claude instance with its own context window, its own system prompt, its own tool permissions, and its own model. When your main session delegates a task to a subagent, that subagent does the work in isolation and returns only its final answer. Your main conversation stays clean.
That isolation is what makes the cost savings possible. If a research task would read twenty files, you do not want those twenty files sitting in your expensive orchestrator’s context for the rest of the session. You want a cheap model to read them, distill them, and hand back a summary.
Here is the division of labor I use:
| Role | Model | What it does |
|---|---|---|
| Orchestrator (main session) | Opus 4.8 | Understands the goal, plans, delegates, synthesizes, makes judgment calls |
| Explorer | Haiku 4.5 | Searches the codebase, finds files and patterns, reports locations |
| Implementer | Sonnet 5 | Writes and edits code against a clear spec |
| Reviewer | Sonnet 5 | Reads a diff, flags bugs and style issues |
| Test runner | Haiku 4.5 | Runs the test suite and build, reports pass or fail with the relevant output |
The rule of thumb: use the cheapest model that can do the job reliably. Searching and running commands are cheap tasks. Writing nuanced code and reviewing it are worth a mid-tier model. Only the coordination and the hard judgment calls need the top model.
Step 1: Give the Project a Memory
Before you define any agents, write a CLAUDE.md at the root of your project. This file is loaded automatically into every session and every subagent, so it is the right place for the facts that everyone on the “team” needs to know.
# Project: taskflow-api
REST API for a task management app.
## Stack
- Node.js with TypeScript
- Fastify for the HTTP layer
- PostgreSQL via Prisma
- npm as the package manager
## Conventions
- Routes live in `src/routes/`, one file per resource
- Business logic goes in `src/services/`, never in the route handlers
- All request input is validated with zod schemas in `src/schemas/`
- Errors are thrown as `AppError` and caught by the global error handler
## Commands
- `npm run dev` starts the dev server with hot reload
- `npm test` runs the vitest suite
- `npm run build` type-checks and compiles to `dist/`
Keep it short. A CLAUDE.md that runs past two hundred lines starts costing you real context on every turn. Put the durable facts here (stack, conventions, commands) and leave the transient details to the conversation.
You can also place a CLAUDE.md inside a subdirectory. It loads only when the agent starts working with files in that directory, which keeps package-specific guidance out of the main context until it is needed.
Step 2: Define the Workers
Subagents live in .claude/agents/ as Markdown files. The YAML frontmatter configures the agent, and the body becomes its system prompt. The fields you will use most are name, description, model, and tools.
The description matters more than it looks. Claude reads it to decide when to delegate to this agent automatically, so write it as a trigger, not a title.
The explorer (cheap and read-only)
---
name: explorer
description: Search the codebase to locate files, functions, and patterns. Use before any change that touches unfamiliar code. Returns locations and short summaries, never edits.
model: haiku
tools: Read, Glob, Grep, Bash
---
You are a fast codebase research agent. Your job is to find things and
report them concisely.
- Locate the relevant files, functions, and call sites for the task you are given.
- Report file paths with line numbers so they are easy to open.
- Summarize how the existing code works in a few sentences.
- Do not propose changes and do not edit anything. Finding and explaining is your whole job.
Running this on Haiku is deliberate. Searching and reading is exactly the kind of high-volume, low-judgment work where the cheapest model earns its keep.
The implementer (mid-tier, can edit)
---
name: implementer
description: Write and edit code against a clear, specific instruction. Use once the design is decided and you know exactly which files change.
model: sonnet
tools: Read, Edit, Write, Bash
---
You implement a well-defined change. You are given a spec: which files to
change and what the result should be.
- Follow the conventions in CLAUDE.md exactly.
- Match the style of the surrounding code: naming, imports, error handling.
- Make the change and nothing more. Do not refactor unrelated code.
- After editing, run the build or the relevant command to confirm it compiles.
- Report what you changed and any decision you had to make.
The reviewer (mid-tier, read-only)
---
name: reviewer
description: Review a diff or a set of recent changes for correctness bugs and convention violations. Use after implementation, before considering a task done.
model: sonnet
tools: Read, Grep, Bash
---
You review code the way a careful senior engineer reviews a pull request.
- Read the diff and the surrounding code for context.
- Flag correctness bugs first: off-by-one errors, missing awaits, unhandled
errors, broken edge cases.
- Then flag convention violations against CLAUDE.md.
- Be specific: cite the file and line, explain the failure, suggest the fix.
- Do not rewrite the code yourself. Report findings and let the orchestrator decide.
The test runner (cheap, mechanical)
---
name: test-runner
description: Run the build and test suite, then report pass or fail with the relevant output. Use to verify a change works before moving on.
model: haiku
tools: Bash, Read
---
You run verification commands and report results plainly.
- Run the project's build and test commands (see CLAUDE.md).
- If everything passes, say so in one line.
- If something fails, quote the exact error and name the file it points to.
- Do not try to fix anything. Reporting accurately is the job.
Notice the pattern across all four: each worker is narrow, each has a model matched to the difficulty of its task, and each is told to report back rather than sprawl. The orchestrator (your main session, running Opus) is what ties them together.
You set the main session’s model with /model opus inside a session, or by launching with claude --model opus. Everything below assumes the main session is your orchestrator.
Step 3: The Workflow
With the workers defined, a real feature moves through four phases. The orchestrator drives all of them and delegates the heavy lifting.
Design
Start in plan mode. Press Shift+Tab until Claude Code is in plan mode, which makes the session read-only, so the model explores and proposes without touching anything.
In this phase the orchestrator delegates exploration to the cheap explorer agent to map the territory, then does the actual thinking itself, because design is a judgment call worth the strong model.
You: I want to add cursor-based pagination to the GET /tasks endpoint.
Plan it. Use the explorer to find how that endpoint works today.
Orchestrator (Opus): [delegates to explorer on Haiku]
Explorer (Haiku): GET /tasks is handled in src/routes/tasks.ts, which calls
listTasks() in src/services/taskService.ts. That service runs a Prisma
findMany with no limit and no cursor. Query input is validated by a zod
schema in src/schemas/tasks.ts.
Orchestrator: Here is the plan:
1. Add `limit` and `cursor` query params to the tasks schema.
2. Pass them into listTasks() and use Prisma's cursor pagination.
3. Return a `nextCursor` alongside the results.
No database migration needed. Approve?
You review the plan as a human. This is the highest-leverage moment in the whole loop, because approving a good plan is cheap and catching a bad one here saves an hour of wrong implementation.
Implement
Once you approve, the orchestrator hands the spec to the implementer on Sonnet. The spec is concrete because the design phase made it concrete.
Orchestrator: [delegates to implementer on Sonnet]
"In src/schemas/tasks.ts, add optional `limit` and `cursor` fields to the
list query schema. In src/services/taskService.ts, update listTasks() to
accept them and use Prisma's `take` and `cursor`, returning the rows and a
`nextCursor`. Update the route in src/routes/tasks.ts to pass them through.
Follow CLAUDE.md conventions."
Implementer (Sonnet): Updated the schema, service, and route. Type-check
passes.
The orchestrator did not spend Opus tokens writing a for-loop. It spent them deciding what the for-loop should do.
Review
Never let the model that wrote the code be the only one to judge it. Delegate a fresh review to the reviewer agent, which reads the diff with no attachment to the implementation.
Orchestrator: [delegates to reviewer on Sonnet]
Reviewer (Sonnet): One issue. The `limit` field has no upper bound, so a
client can request the entire table with ?limit=1000000 and exhaust the
database. src/schemas/tasks.ts:12. Cap it, for example `.max(100)`.
That is a real bug the implementer would happily have shipped. A separate reviewer with fresh context catches things the author is blind to. For a heavier review you can use the built-in /review for a pull request or the code-review skill for the working diff.
Test
Finally, the orchestrator asks the cheap test-runner to verify.
Orchestrator: [delegates to test-runner on Haiku]
Test runner (Haiku): npm test passed, 47 tests green. npm run build type-checks
clean. GET /tasks?limit=20 returns 20 rows and a nextCursor.
Four phases, four different models pulling their weight, and the expensive one only touched the parts that needed judgment.
Codify the Workflow with a Slash Command
Once this loop feels natural, capture it as a custom command so you do not retype it. Slash commands are Markdown files in .claude/commands/. The filename becomes the command, and $ARGUMENTS is replaced with whatever you pass.
---
description: Design, implement, review, and test a feature end to end
argument-hint: <feature description>
---
Deliver this feature using the full workflow: $ARGUMENTS
1. Use the explorer agent to map the relevant code. Do not skip this.
2. Propose a short plan and wait for my approval before editing.
3. Once approved, delegate the change to the implementer agent.
4. Delegate a review to the reviewer agent and address any real findings.
5. Delegate verification to the test-runner agent.
6. Summarize what changed in three lines.
Save that as .claude/commands/feature.md and you can run /feature add cursor-based pagination to the tasks endpoint. The orchestrator follows the recipe every time, which means the cheap-worker delegation happens by default instead of only when you remember to ask for it.
Automate the Boring Parts with Hooks
Hooks let you run a shell command automatically when certain events happen, configured in .claude/settings.json. The most useful one for this workflow is running your type-checker or linter after every file edit, so mistakes surface immediately instead of at review time.
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx tsc --noEmit 2>&1 | tail -10"
}
]
}
]
}
}
Now every time any agent edits a file, the type-checker runs and its output goes back to the agent. If a change introduces a type error, the implementer sees it and fixes it on the spot, without waiting for the test phase. Hooks are deterministic, so this happens whether or not the model remembers to check.
A word of caution: a hook that runs a slow command on every edit will make the whole session drag. Keep hook commands fast, or scope the matcher so they only fire on the files that matter.
Why This Is Cheaper and Better
The obvious win is cost. Haiku is a fraction of the price of Opus, so pushing search and test execution down to it adds up quickly over a long session. But the more important win is quality, and it comes from context hygiene.
When one model does everything, its context fills with the raw output of every search, every file read, and every failed command. By the end of a long task it is reasoning over a haystack. When workers absorb that volume and return summaries, the orchestrator reasons over a clean, curated view of the project. It makes better decisions because it is not distracted.
The separation also creates natural checkpoints. A dedicated reviewer with fresh eyes catches what the author missed. A dedicated planner that you approve before any code is written catches wrong directions early. These are the same practices that make human teams effective, applied to a team of models.
Practical Tips
A few things I learned the hard way:
- Write descriptions as triggers. Claude decides when to delegate based on the agent’s
description. “Use before any change that touches unfamiliar code” delegates reliably. “Codebase agent” does not. - Give workers the narrowest tools they need. An explorer that cannot write cannot accidentally edit. Constraint is a feature.
- Do not over-delegate. A one-line typo fix does not need a five-agent pipeline. The orchestrator should just fix it. Reserve the full loop for real features.
- Keep CLAUDE.md honest. Every agent trusts it. A stale command or a wrong convention in that file propagates to every worker at once.
- Approve plans, not just diffs. The cheapest place to fix a mistake is in the plan, before a single line is written.
Setting this up takes an afternoon. After that, every project you touch gets a small team of specialists instead of one overworked generalist, and you spend your own attention on the decisions that actually need a human.
If you found this useful, share it with someone who is still running every task through a single model.