Dynamic Workflows
Type ultracode and the model writes a script that spawns sub-agents: phases in sequence, agents in parallel, parent context window almost empty.
The one line:
ultracodelets the turn write a JavaScript script that spawns sub-agents for you, so phases run in order, agents inside a phase run at once, and the parent's context window stays nearly empty.
Settings first
Run default Opus. Set effort to high and stop touching it. The levels are low, medium, high, xhigh and max, set through /effort, --effort or CLAUDE_CODE_EFFORT_LEVEL; /effort also accepts ultracode. The effortLevel settings key takes only low through xhigh: max is session-only (model config).
My opinion: nothing above high is worth paying for. xhigh buys more thinking inside one context window; you get more, and cheaper, by splitting the same work across fresh agents. max is close to a scam. Orchestration beats cranking effort. If your plan's usage is tight, drop to medium before you cut the workflow.
What ultracode does
Type ultracode anywhere in the prompt: the word highlights and the turn becomes a dynamic workflow request. To set it for a whole session use /effort ultracode or claude --effort ultracode: that is xhigh effort plus automatic orchestration. ultracode is the exception to the effort rule above, you pay xhigh for orchestration, not on every turn. Dynamic workflows need a paid plan and Claude Code v2.1.154 or later; on Pro, switch them on in the Dynamic workflows row of /config.
The model does not "call sub-agents" from prose. It writes a JavaScript script, and the harness executes that script. agent() spawns one sub-agent, parallel() runs a batch at once, pipeline() runs one agent per item in a list, top-level await works, and the script cannot reach the filesystem or the shell. So the orchestration is deterministic code, not another model decision on every step. Documented caps as of writing: 16 concurrent agents, 1,000 agents per run, and a "Large workflow" warning past 25 agents or 1.5M projected tokens (dynamic workflows). Claude also follows a size guideline when it writes the script: the default medium aims for fewer than 15 agents, so run /config workflowSizeGuideline=large (under 50) when your phases need more.
Ask for the script before it runs: "save the workflow code to the repo first so I can review it." Workflows live in .claude/workflows/ or ~/.claude/workflows/, so a good one is reusable, not a one-off.
Two axes
Phases run strictly in sequence. Agents inside a phase run in parallel. That is the whole model.
Sixteen agents across one turn, but never more than five at once: the cap of 16 concurrent applies inside a phase, not across the run. Each agent starts with a clean context window and returns a short result. The parent reads only the summaries, so a job that would blow a single window finishes with the main session mostly empty.
Read the script it writes
A script opens with a meta literal naming the phases, then plain JavaScript drives the agents.
export const meta = {
name: "audit-agentic-surfaces",
description: "Inventory every agentic surface, then critique the findings",
phases: [
{ title: "Inventory", detail: "one agent per surface" },
{ title: "Critique", detail: "three lenses over the findings" },
],
};
const SURFACES = ["rules", "skills", "hooks", "mcp", "workflows"];
const FINDINGS = {
type: "object",
required: ["surface", "files", "findings"],
properties: {
surface: { type: "string" },
files: { type: "array", items: { type: "string" } },
findings: { type: "array", items: { type: "string" } },
},
};
phase("Inventory");
// Fan-out: one agent per surface, all at once, each with a clean window.
const inventory = (
await parallel(
SURFACES.map((surface) => () =>
agent(`Inventory the ${surface} config in this repo.`, {
label: `inventory:${surface}`,
model: "sonnet",
schema: FINDINGS,
})
)
)
).filter(Boolean);
phase("Critique");
// The next phase reads the previous phase's results as a JavaScript value.
const critiques = await parallel(
["skeptic", "cost", "security"].map((lens) => () =>
agent(`Critique this inventory as a ${lens}: ${JSON.stringify(inventory)}`, {
label: `critique:${lens}`,
})
)
);
return { inventory, critiques };Two details carry the whole script. parallel() takes thunks, not promises, so the runner controls when each agent starts. And schema forces the sub-agent into structured output: a validated object, not prose you have to parse. Any agent whose result feeds a later phase needs a schema.
The dials
Assign cheap models to mechanical stages: inventory, file listing and rewrites to Sonnet, genuinely dumb passes to Haiku. Spend Opus on planning, critique and the final report.
Widen research phases. Three or five agents reading different parts of the problem cost one turn and give the planner real material.
Add a QA phase that drives a real browser. I keep a line in my global rules saying QA runs through agent-browser, a CLI that drives a real browser and returns screenshots. The QA agent clicks the feature, screenshots it, then feeds those images back for analysis. That is a real check, not the model asserting its own work passed.
Wire a repair loop: a failed review or QA sends the work back to implementation as a new phase, then reviews and QAs again before the PR stage.
A suggestion phase is worth adding, with a filter. Most suggestions are noise. Ask two or three times, take the one that names an edge case you had not considered, and stop when they stop being interesting.
Use one even for small tasks
This is my default now, even for a one-file change: dynamic workflow, no parallel agents, one per phase, plan then implement then review, QA inside the implementation. One agent per phase costs almost nothing extra and buys a free QA pass on work you would otherwise ship unchecked.
Portability
Nothing else ships this, so I ported it. pi-ultracode is my extension for the Pi coding agent: the same orchestration scripts running outside the chat context, coordinating child agents through the same injected globals — agent, parallel, phase, log. Pi drives whatever model you configure, so if you landed on a different harness or a different model family in Choose Your Coding Agent, this is how you keep the pattern. MIT licensed.
pi install github:Mark-Life/pi-ultracodeIn Codex the closest move is telling it to manage several sessions, with the main session coordinating the others: worse than dynamic workflows, slightly better than plain sub-agents, better than nothing.
For the extreme demonstration, read Bun's rewrite from Zig to Rust: 535,496 lines of Zig, 11 days, a peak of 64 concurrent agents across four worktrees, roughly $165,000 at API pricing.
What to do
- Set default Opus and effort
high, and drop tomediumonly when usage is tight. - Type
ultracodein the prompt, then ask it to save the workflow script before it runs. - Name your phases in the prompt: plan, implement, review, QA, report.
- Give every agent whose result feeds a later phase a
schema, so you get an object, not prose. - Put mechanical phases on Sonnet or Haiku and keep Opus for planning and critique.
- Install
agent-browserwithnpm i -g agent-browser && agent-browser install, and require screenshots back before the PR stage.