cc-os/plugins/os-orchestration/ORCHESTRATION.md

60 lines
4.2 KiB
Markdown
Raw Normal View History

## Session orchestration
- Main-loop tokens are the most expensive tokens in the session: every direct tool
call and every byte read into this context bills at the main-loop model's rate,
while a haiku/sonnet subagent does the same mechanical work for a fraction of it.
The more capable the main-loop model (opus- or fable-tier), the lower the
delegation threshold. The question is not "is this task big enough to delegate?"
but "does this step need main-loop judgment?" — when a sequence beyond ~3 tool
calls needs no main-loop judgment between steps, delegate it down-tier, even if
the steps are strictly sequential.
- Delegate when: work is parallelizable across independent files/subtasks; an
implementation task produces N independent files from an already-settled design,
spec, or plan (write-N-files fan-out is delegated work — the design decisions are
already made); an investigation spans many files or needs a large/isolated
context (long log review, wide grep-and-synthesize); or a mechanical multi-call
sequence (edits, lookups, conversions) needs no judgment between steps — this
includes your own eval/benchmark/extraction work: repeated near-identical
parsers, headless grid runs, and CLI syntax hunts are mechanical sequences too;
script once or delegate. This holds for the whole session: after one round of
spawns completes, the next eligible chunk of work is delegated too — don't drift
back into long direct runs mid-session. WHEN a design/decision settles
mid-session, stop before the first direct Write/Edit that implements it — the
resulting fan-out is a delegation event, even if the session started with
disciplined spawns.
- Work directly when: the op is single-file or ≤2 tool calls; steps are genuinely
judgment-dependent (each result changes what you do next); the user is in the
loop every few turns (interactive troubleshooting — delegation overhead exceeds
savings); a uniform multi-file change is covered by one scripted command (a
loop/script in a few Bash calls is direct work, cheaper than a per-file grind or
a spawn); or you are driving/polling a script's own output.
- Batch before spawning: plan the full fan-out before the first spawn, then group
related subtasks (~58 similar items) into one agent prompt with an explicit
return format, so each agent completes in one round. A follow-up on an agent's
result goes to that same live agent via SendMessage, not a fresh spawn — every
new spawn re-pays the per-agent system-prompt tax.
- Delegate async and keep working: launch independent subagents in the background
and continue your own thread while they run; intervene only when a result shows
an agent off track. Never sleep-poll a background job from the main loop —
background it and rely on completion notification (or Monitor); a `sleep` loop is
main-loop idle time billed at the top rate.
- Before every `Agent` call → set `model:` explicitly in that call. An omitted
`model` silently bills the subagent at the main-loop model. Mechanical
file-edit/shell work → `haiku`; anything requiring judgment → `sonnet`; genuinely
hard reasoning → `opus`.
- When a spawn requests `sonnet` or `opus` → append to its prompt: "State the exact
model ID you are running as in the first line of your report." (The launch result
does not show the resolved model; the subagent's self-report is the only visible
signal.) When a report comes back showing a lower tier than you requested → say so
and adapt (re-spawn or flag the downgrade) — never treat downgraded output as
judgment-tier work silently.
- Before delegating investigation → don't re-cover your own ground: a file you
already read goes into the subagent prompt as a stated fact or summary, not as an
instruction to read it again. If an investigation will span many files, delegate
it before reading them yourself — a short orienting Read is fine only when the
target file/path is uncertain. In an unfamiliar codebase, more than ~5 orienting
grep/read calls means the orientation itself is the delegable task — send it to
an Explore agent.
- Where a call exposes an effort dial (Workflow `agent()` opts), set it per stage:
mechanical stages `effort: low`; hard verify/judge stages `high`/`xhigh`.