Dynamic Workflows
Dynamic workflows are how Claude runs many subagents at scale. Instead of dispatching one agent and waiting, Claude writes a short JavaScript script that orchestrates agents — fanning work out, piping it through stages, looping until a condition holds — and a runtime executes that script in the background while your session stays responsive. The plan lives in code, so only the final answer returns to the main thread’s context.
Reach for this when a job is too big for one agent and too structured for an ad-hoc dispatch: reviewing every file in a large diff, researching across dozens of sources, migrating a hundred call sites. The trade-off is cost and visibility — a workflow can spawn dozens of agents, so it’s gated behind a confirmation prompt and a token budget, and the main thread sees the synthesised result rather than each agent’s reasoning.
For one-at-a-time delegation, see Subagents. Dynamic workflows are the orchestration layer above that.
The three primitives
Section titled “The three primitives”A workflow script is built from three calls:
agent(prompt, opts)runs a single subagent and returns its output. Pass a schema and the agent is forced to return validated structured data instead of free text.parallel(thunks)runs several agents at once and waits for all of them — a barrier. Use it only when the next step genuinely needs every result together.pipeline(items, ...stages)streams each item through a sequence of stages with no barrier between them. Item A can be in stage three while item B is still in stage one.
Default to pipeline(). It doesn’t make fast items wait on slow ones, which is what you want for almost all multi-stage work. Reach for a parallel() barrier only when a stage truly needs all prior results at once — deduplicating across the full set, exiting early when the count is zero, or comparing each result against the others.
A worked example
Section titled “A worked example”This pipeline reviews a diff across several dimensions, then adversarially verifies each finding — the same code-reviewer and adversarial-reviewer jobs from the previous page, run at scale:
const results = await pipeline( DIMENSIONS, // Stage 1: review the diff for one dimension (bugs, perf, security…) d => agent(d.prompt, { schema: FINDINGS_SCHEMA }), // Stage 2: verify each finding the moment its dimension finishes review => parallel( review.findings.map(f => () => agent(`Adversarially verify this finding — try to refute it: ${f.title}`, { schema: VERDICT_SCHEMA }) .then(verdict => ({ ...f, verdict })) ) ))const confirmed = results.flat().filter(f => f.verdict?.isReal)Because it’s a pipeline, the bugs dimension starts verifying its findings while the perf dimension is still reviewing — no wall-clock wasted waiting on the slowest reviewer. A parallel() barrier across both stages would force every review to finish before any verification began.
The failure modes it targets
Section titled “The failure modes it targets”Spawning more agents isn’t the point; applying a repeatable quality pattern is. Anthropic frames dynamic workflows against three failure modes that show up when one agent works alone for too long:
- Agentic laziness — stopping after partial progress and calling it done. Fan-out-and-synthesize forces coverage.
- Self-preferential bias — an agent rating its own output highly. An independent verifier or judge breaks the tie.
- Goal drift — losing the objective across many turns, especially after the context is compacted. Deterministic control flow in the script holds the objective steady.
The patterns that address these — fan-out-and-synthesize, adversarial verification, tournament ranking — are why a workflow beats simply asking one agent to do more.
When not to reach for it
Section titled “When not to reach for it”Dynamic workflows are token-hungry by design. Before the first run you get a confirmation prompt; a token budget and a hard agent ceiling bound the cost; and each agent can take an isolated git worktree when several write files in parallel. Don’t reach for a workflow on a one-off task a single subagent handles — the orchestration overhead isn’t free, and it takes an explicit opt-in (ultracode) precisely because it shouldn’t fire by default.
When you do want one, /deep-research is a built-in workflow worth studying, and any workflow you write can be saved to ~/.claude/workflows as a command or bundled inside a skill.