What dynamic workflows are, how they differ from subagents, skills, and agent teams, and how to run your first one.
BEFORE YOU START
You need Claude Code v2.1.154 or later and a paid plan (on Pro, flip on Dynamic workflows in /config). Have a repo you know reasonably well handy.
Here's a terminal on a Friday afternoon. I asked Claude Code to audit every route handler under src/routes/ for missing auth checks and to verify each finding before reporting it. The session isn't doing the audit. It's idle, free for other work, while a progress view fills in behind it.
The Scan phase at the top shows 38 agents, a climbing token count, and elapsed time. One agent per route file. Below it, a Verify phase picks up findings as they arrive, and those agents have one job: take a claimed vulnerability and try to knock it down. Findings that survive go in the report. Findings that don't are gone before I ever see them. Selecting any agent shows its prompt, its recent tool calls, and what it returned.
You already know how this task goes in a normal session. The context window fills with file contents, the model re-decides what to do next after every file (forty separate times), and somewhere around file twenty it starts summarizing to save room, which is exactly where audits go to die. You babysit the whole thing.
The forty agents are the least interesting part of that screenshot. The interesting part: Claude wrote the program that runs them, the program is deterministic, and you can read it.
Big tasks break single-conversation agents in two different ways, and the fixes are different too.
The first is context degradation, and it starts well before the window is full. The capacity math is bad enough (500 files at even 2K tokens of findings apiece is a million tokens of intermediate state), but capacity is the crude version of the problem. Long before overflow, recall gets uneven: models attend most reliably to the start and end of a long context and lose material in the middle, so the suspicious pattern from file 12 is competing for attention with everything read since, and what it concluded about file 12 quietly anchors how it reads file 30. Summarizing between steps doesn't save you, because summaries drop line-level detail and line-level detail is the entire point of an audit. Bigger windows raise the ceiling without fixing the attention economics.
The second failure is sneakier. On a long task the model re-plans every turn. Each decision looks reasonable in isolation; across forty turns, steps get skipped, a loop that should run until a check passes stops after two iterations because the model felt done, and the same request takes a different path tomorrow than it did today. Subagents help with the first problem (fresh context per worker) and do nothing for this one. The orchestration is still improvised by a model with no obligation to be consistent.
So: intermediate results need to live outside the context window, and the plan needs to live in code. Both fixes are the same object. A program.
OBJECTION
“Isn't this just parallel subagents?” Parallelism is the least of it. Subagents parallelize work. A workflow also moves the plan out of the model's turn-by-turn judgment and into a script: loops with real exit conditions, verification gates that can't get skipped, results that never touch the orchestrator's context. You could write a useful workflow with zero parallelism in it.
Ask Claude Code for a workflow and it writes a small JavaScript program. A runtime executes that program in the background, in an isolated environment, while your session stays responsive. Here's roughly what it wrote for the audit above, short enough to read in full:
export const meta = {
name: 'audit-routes',
description: 'Audit every route handler for missing auth checks',
}
const found = await agent('List every .ts file under src/routes/.', {
schema: { type: 'object', required: ['files'],
properties: { files: { type: 'array', items: { type: 'string' } } } },
})
const audits = await pipeline(found.files, file =>
agent(`Audit ${file} for missing authentication checks.`, { label: file }))
return audits.filter(Boolean)
The meta block names the workflow and says what it does. One agent lists the route files, and the schema option forces its answer back as a validated object instead of prose, so found.files is a real array the code can iterate. That single option is doing more work than anything else on the page. It's what lets code, not a model, drive the loop, and post two digs into it properly. From there, pipeline runs one auditing agent per file. Agents that get stopped or die on an API error come back as null; the script drops those and returns. That return value is the only thing that lands back in Claude's context. Everything in between lived in script variables.
Look at what the script is made of: await, arrow functions, filter, template strings. Plain JavaScript. If you can read a fetch call, you can read this.
The resulting shape has a name that sounds like a contradiction until you take it apart: these runs are deterministically dynamic. The structure (what fans out, what gets verified, when a loop stops) is code, and it executes the same way every time. The content of each step is dynamic, because each step is a model reading real files and exercising judgment. And the script itself is dynamic in a second sense: Claude generated it for this task, this afternoon, not from a library somebody had to write in advance.
I'm deliberately skipping two things here; progressive disclosure applies to blog series too. The full agent() option set and the sandbox rules are post two. Why this example uses pipeline instead of its sibling parallel, and the verification patterns that make large runs trustworthy, get their own post after that.
Claude Code already has several ways to run multi-step work, and you've probably half-learned all of them. They sort cleanly on a single question: who holds the plan?
| SUBAGENTS | SKILLS | AGENT TEAMS | WORKFLOWS | |
|---|---|---|---|---|
| What it is | A worker Claude spawns | Instructions Claude follows | A lead agent supervising peers | A script the runtime executes |
| Who decides what runs next | Claude, turn by turn | Claude, following the prompt | The lead agent | The script |
| Intermediate results live in | Claude's context | Claude's context | A shared task list | Script variables |
| Scale | A few per turn | Same as subagents | A handful of peers | Dozens to hundreds per run |
Subagents are workers: spawn one, it does a job in its own context, the result comes back. Right tool for delegating a handful of tasks inside a conversation. Skills are instructions: use one when the repeatable thing is a procedure a single agent should follow. Agent teams give you a lead agent supervising long-running peers over a shared task list, which fits a few substantial parallel efforts better than a big fan-out.
A workflow moves the plan into code, and that's the variable that actually changed. Reach for one when the task overflows a context, or when the orchestration itself is something you want to keep.
You might expect plan mode in this table, and its absence is the point. Plan mode changes when the plan gets written and whether you approve it: Claude explores read-only, drafts, waits for your sign-off. Custody never moves. once you approve, execution is the same turn-by-turn loop, and the approved plan is prose in a context window, enforced by the model's attention rather than by anything structural. It's subject to the exact drift described earlier: step five can still get reinterpreted or quietly dropped. Plan mode reviews the plan; a workflow compiles it, while keeping the part of plan mode that mattered: you see the plan (and the raw script) before anything runs. They also stack: plan in plan mode, then have Claude turn the approved plan into a workflow.
These four compose; they don't compete. Workflows orchestrate subagents, and every agent() call in that script spawns one. A skill can kick off a workflow. Post five wires saved workflows together under a higher-level script, using exactly the pieces in this table. Separation of concerns, applied to agents. And the fan-out gives you single responsibility for free: each agent gets one file, one question, and a fresh context where nothing else is competing for attention or coloring its read.
OBJECTION
“More agents means better results.” Agent count is a cost knob. Quality comes from structure. The launch-day claims (codebase-wide audits, Bun's 750,000-line Zig-to-Rust rewrite) rest on verification: independent agents adversarially reviewing findings before a human sees them. Independent means more than parallel: a verifier gets the claim and none of the reasoning behind it, so it can't inherit the auditor's anchoring. A ten-agent run with a verify phase beats a hundred-agent run without one. Post three covers how to build that.
Three on-ramps, in increasing order of commitment.
Gentlest: the bundled workflow. Claude Code ships with /deep-research, which takes a question, fans out searches across several angles, cross-checks the sources, votes on each claim, and returns a cited report with the failed claims already filtered out. Pick something from your backlog you'd otherwise burn an afternoon on:
/deep-research What changed in the Node.js permission model between v20 and v22?
Second: ask for a workflow on your own task. Include the keyword ultracode in your prompt, or say it plainly: “use a workflow to audit every route handler under src/routes/ for missing auth checks.” Either way, Claude writes a script for the task instead of grinding through it turn by turn.
The keyword is an explicit opt-in, and the reason is cost. A workflow can spawn dozens of agents; typing the word is how you consent to that scale. It only counts in prompts you typed yourself, so a webhook, a CI job, or a PR comment can't trigger a run by smuggling the word in. Before anything executes, Claude Code shows the planned phases and asks. One of the options is viewing the raw script. Take it at least once. Reading the program your agent wrote is the fastest way to build a real mental model of this feature.
Third: /effort ultracode, a session-wide setting where Claude plans a workflow for every substantive task without being asked. It exists, it's useful once you know what you're doing, and it is not day-one advice.
Once a run starts, /workflows is home base. Arrow to the run, press Enter, and you get the view from the top of this post: phases with agent counts, token totals, elapsed time. Drill into a phase for its agents, then into an agent for its prompt, tool calls, and result. p pauses and resumes. x stops the run, or just the selected agent. There's also an s key that saves the run's script as a reusable command; that one matters in post four.
If the spend makes you nervous, good. That instinct is correct and you should keep it. A run is observable and stoppable the entire time, and a stopped run usually keeps its completed work. Start with a small slice regardless: one directory, not the repo; a narrow question, not a broad one. Watch what it costs. Then scale.
Three task shapes fit well, each mapping back to a failure mode from earlier.
Fan-out across many independent units is the obvious one: audits, migrations, per-file review of a large PR. Too big for one context, trivially decomposable. Second, verification-heavy work: anywhere you want findings independently checked before you read them. Written in code, the checking is structural; the model can't skip a gate that's a line in a script. Third, discovery of unknown size. “Find flaky tests until two consecutive rounds turn up nothing new” is a loop with a real exit condition. Turn-by-turn prompting approximates that. A while loop guarantees it.
Now the other column, which gets equal time because the failure cases are just as real. A single-file fix gains nothing from orchestration; you'd pay the overhead with no fan-out to spread it across.
Mid-run judgment is the interesting case, and the honest answer is “it depends on granularity.” A running workflow takes no input: there's no channel to answer a question mid-script. What you can do is checkpoint: the script returns early with its partial results and the decision it needs, you answer in conversation, and it relaunches with your answer as a parameter. Completed agent calls replay from cache on the way back, so re-entry is nearly free. A sign-off between stages fits this shape well. A decision per item does not, since each escalation round-trips the whole script, and at that granularity you've rebuilt turn-by-turn conversation with extra steps. If the task is mostly judgment, a workflow was the wrong tool to begin with.
The strongest objection came out of the Hacker News launch thread, and I'll paraphrase it fairly: my limiting factor was never how fast the agent churns through code; it's how fast I can review what comes out. That criticism lands. If review capacity is your bottleneck, a machine that produces more artifacts per hour makes your life worse. The honest pitch is narrower than the launch framing: workflows that verify, deduplicate, and rank their own output reduce reviewer load; workflows that merely generate more output inflate it. Which one you build is a design decision, and posts three and six are about making it on purpose.
OBJECTION
“So this thing runs off unattended.” Three separate consents sit between you and a large run: a trigger you typed yourself, an approval prompt showing the planned phases (raw script one keystroke away), and a live view with pause and stop. Nothing fires from CI or a PR comment.
Quick recap of where you stand. Workflows put the plan in code and the judgment in agents. Against the other multi-step features, the sorting question is who decides what runs next; for workflows, the answer is the script. You know the three on-ramps, and you have a two-part fit test: does the task overflow a context, and should its orchestration be deterministic?
Homework is one command. Run /deep-research on a real question from your backlog, open /workflows while it works, and drill into an agent or two. When it finishes, press s and save it.
The rest of the series goes down the stack from here. Post two takes a script apart line by line: meta, agent(), schemas, parameters, sandbox. Post three covers the orchestration patterns that separate trustworthy runs from expensive ones. Post four turns good runs into team assets in the repo or a plugin, and post five composes those saved workflows under higher-level scripts. If you're an engineering leader deciding whether any of this belongs in your org, skip ahead: post six on economics and governance assumes only this post, no code required.
Written against Claude Code v2.1.239. The feature is moving fast; the changelog is the source of truth for what's changed since.