I almost missed it. OpenAI pushed a chunky subagent feature into the Codex CLI on July 6, and I only noticed because codex features list spat out some new flags I'd never seen before. The blog post never came. The changelog was quiet. But the docs got rewritten, and once I started reading, I couldn't stop.
Subagents sound like buzzword territory. "AI agent teams" has been a phrase on every other pitch deck for months. But this one actually works, and the workflow is concrete enough that I want to show you exactly what happened when I ran it on three different jobs.
If you write Codex CLI tutorials for a living, this is the post to read. If you don't, this is the one that'll save you six hours next time you have to review a PR.
What Subagents Actually Are
In plain English: you tell Codex to do a thing, and it spins up specialized child agents to do parts of the thing in parallel. Each child has its own model, its own tool surface, its own context window. The parent waits for everyone, then hands you a consolidated answer.
This is a big deal because most of the AI coding work I do isn't one-thread. Look at what I actually got stuck on last week:
- PR review. I want to know about security, code quality, test coverage, and API accuracy at the same time. Single-thread has to pick one.
- UI debugging. I need someone to reproduce the bug in the browser, someone to trace the code path, and eventually someone to make the fix. Those three steps can start in parallel.
- Bulk auditing. I have 32 components, each needs a risk review. One agent doing them in series takes 45 minutes.
The trade-off is real, though: subagent runs eat roughly 5-6x the tokens of a comparable single-agent run. That's not a bug. That's how you pay for context isolation between children. If you go in knowing that, the rest makes sense.
The Three Built-in Agents
Codex ships three out of the box, and you don't need to configure them:
- default — general-purpose fallback, can do almost anything
- worker — execution-focused, used for implementation and fixes
- explorer — read-heavy codebase exploration
To trigger them, you have to be explicit. Subagents only spawn when you ask. In the interactive TUI, you'd say something like:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
The magic phrase is "spawn one agent per point, wait for all of them." Drop that and Codex will just do it serially. Once the subagents are running, you can use /agent in the TUI to bounce between threads and see what each one is doing.
Writing Your Own Custom Agents
The built-ins are fine for a while, but you'll outgrow them fast. The first time I wanted an agent that "only checks documentation, never touches code," I had to write one.
File Locations
| 1 | |
| 2 | |
Each agent is a single .toml file. The minimum is three fields:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
Optional fields you'll actually use:
model— pick fromgpt-5.5,gpt-5.4,gpt-5.4-mini,gpt-5.3-codex-sparkmodel_reasoning_effort—low/medium/high/extra highsandbox_mode—read-only/workspace-write/danger-full-accessmcp_servers— agent-specific MCP server configskills.config— load specific skill filesnickname_candidates— list of display names; I always set this because three "reviewer" threads in the TUI are a nightmare
Global Limits
No matter how many agents you define, the hard caps live in config.toml under [agents]:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
max_depth = 1 means the root can spawn children, but children can't spawn grandchildren. I bumped it to 3 once to test recursive delegation. The token bill was ugly. Don't do that unless you have a very specific reason.
Workflow 1: PR Review, Three Subagents in Parallel
This is the one the official docs lead with, and it works. I ran it against my own repo on Tuesday.
Project Config
.codex/config.toml:
| 1 | |
| 2 | |
| 3 | |
.codex/agents/pr-explorer.toml — a cheap explorer to map the affected code:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
The model choice here matters. gpt-5.3-codex-spark is the fast one; the explorer is just reading code and citing files. I don't need GPT-5.5 for that. The sandbox_mode = "read-only" is the load-bearing line — it physically cannot edit files, which is exactly what I want from a subagent whose job is "gather evidence."
.codex/agents/reviewer.toml — the strict reviewer:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
I'm spending gpt-5.4 with high reasoning here. The reviewer's job is to find real problems, and a cheaper model has a bad habit of waving through bugs because they look plausible. Worth the cost.
.codex/agents/docs-researcher.toml — a documentation lookup specialist:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
This one is wired to the OpenAI developer docs MCP server. Cheap model, narrow job, and a hard rule: no code changes.
The Launch Prompt
In the TUI:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
What Happened
I watched the TUI spin up three threads. The numbers:
pr_explorercame back in about 30 seconds with a list of affected files, key functions, and call sitesreviewertook 1-2 minutes with concrete findings, including one race condition I had misseddocs_researcherwas fastest at around 20 seconds, returning API verification with reference links
The parent thread consolidated them into a single review report. If any child had hung, I would have used /agent to jump in and inspect.
What I Changed in My Version
The official demo uses an English prompt. I tried the same prompt in Chinese once and it sort of worked, but I noticed the agents drifting across boundaries — reviewer would occasionally go verify a doc reference that was clearly docs_researcher's job. The boundary got fuzzy when the prompt language didn't match the developer_instructions language.
The fix was to make the descriptions mutually exclusive. I added "Do not check documentation; rely on docs_researcher for that" to reviewer's instructions. That removed the overlap and the parent dispatcher stopped confusing them.
One more thing: if you want a child to be strictly read-only, lock it down in sandbox_mode, not in developer_instructions. Models forget instructions. Sandbox enforcement is a property of the system, not the prompt.
Workflow 2: Frontend UI Debugging, Browser + Code + Fixer
PR review is read-only. To actually fix a bug you need some children to be able to write files. The second official demo covers this.
.codex/agents/code-mapper.toml:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
.codex/agents/browser-debugger.toml:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
workspace-write lets it save screenshots and logs, but the developer_instructions explicitly forbid touching application code. This is a "give access but constrain intent" pattern. Trust the model a little, but not all the way.
.codex/agents/ui-fixer.toml:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
ui_fixer doesn't override sandbox_mode, so it inherits the parent session's policy. The model is fast because "make a small fix" is not a hard reasoning task.
The Launch Prompt
| 1 | |
| 2 | |
| 3 | |
| 4 | |
What Happened
I ran this against a real Next.js project where the settings page "Save" button was silently broken.
browser_debuggeropened Chrome via the DevTools MCP, clicked Save, captured screenshots, and confirmed the bugcode_mappertraced the call chain and pinpointed theonSavehandler inapp/settings/page.tsx- The parent decided
ui_fixershould take a swing ui_fixermade a 4-line change, and Codex ran lint + tests as verification
End to end: 3-4 minutes. If I'd asked a single agent to do the same work, I'd estimate 8+ minutes, with a much higher chance of the agent forgetting the reproduction step once it started editing.
Things That Went Wrong
Chrome DevTools MCP startup. I set startup_timeout_sec = 20 and it was way too tight. The MCP server has to wait for Vite to finish its first compile, and on a cold start that takes longer than 20 seconds in my project. I bumped it to 60 and the failures stopped. If your startup time is even longer, you'll need an actual health check.
Sandbox race conditions. When workspace-write and read-only agents read the same file at the same time, the read-only one can occasionally see a half-written version. I haven't seen data corruption, but I have seen warnings in the TUI.
MCP inheritance is fragile. The docs say child agents inherit the parent's MCP servers. Sometimes they do. I have a non-zero failure rate where they don't, and the error surfaces as a generic "tool not found." Workaround: declare every MCP server in every agent file that needs it. Verbose, but reliable.
Workflow 3: Bulk Auditing with spawn_agents_on_csv
The first two workflows are "few agents, big jobs." Codex also ships a dedicated tool for "many agents, small jobs": spawn_agents_on_csv.
You give it a CSV. It reads one row per item, spawns one worker per row, and dumps the consolidated results into another CSV. Each worker has to call report_agent_job_result exactly once, or the row gets marked as an error in the output.
The Parameters
csv_path— source CSVinstruction— worker prompt template, with{column_name}placeholdersid_column— which column provides stable item IDsoutput_schema— required JSON shape per workeroutput_csv_path— where the result CSV landsmax_concurrency— fan-out capmax_runtime_seconds— per-worker timeout
Real Example
I had a CSV of 32 components I wanted risk-scored:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
The prompt I used:
| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
Run with codex exec (non-interactive). The stderr shows single-line progress:
| 1 | |
The output CSV looks like this (truncated):
| 1 | |
| 2 | |
Notice result_json is a quoted string, not a real JSON column. You'll need to json.loads() it yourself if you're piping the CSV into another tool.
The Actual Numbers
I ran this against my 32-component project. Some honest measurements:
- Single agent, serial: 45 minutes, ~310k tokens
- spawn_agents_on_csv with max_concurrency=6: 9 minutes, ~1.8M tokens
So I traded about 5x the tokens for 5x the speed. That's the deal. For some jobs, it's a great deal. For others, it isn't.
Things I Wish I'd Known Earlier
Write output_schema strictly. If you say the schema requires path, risk, summary, and follow_up, and a worker omits one, that row is marked as an error. I'd rather have a slightly less rich but always-valid result than chase down why half my rows are red.
Don't set max_concurrency higher than max_threads. They'll fight. The CSV tool will queue workers beyond the cap, but you'll waste time waiting when you could have just lowered the concurrency.
Watch your CSV size. I tried this with 500 rows and Codex OOM'd during the planning step. 200 rows is comfortable on a 16GB machine. Above that, chunk it.
The result CSV's result_json column is escaped JSON-as-string. Don't trust your eyes when reading the CSV. Parse it.
Things I Haven't Figured Out Yet
I want to flag a few open questions for anyone going deeper than I have:
- MCP inheritance in child agents. The docs say children inherit parent MCP servers. I have a flaky success rate. Could be a bug, could be that I'm misconfiguring something.
- The real cost of
max_depth > 1. Recursive delegation. I have not had the courage (or the budget) to test this on a non-trivial task. - Session recovery after a child crash.
codex resumeworks for single-agent sessions. What happens when three children crash and you want to resume? I haven't tested. - GPT-5.3-Codex-Spark quality vs GPT-5.4-mini in subagent context. The marketing says "extra fast." In my runs they're close in speed and close in quality. I haven't been able to make a confident call.
If you've got answers to any of these, drop them in the comments. I check there.
Should You Actually Use Subagents?
Honest answer: probably not, for most of your work.
If your day-to-day is "edit one file" or "ask a quick question," single-thread is fine. Subagents are worth it when the task naturally has N independent branches and the wall-time savings beat the token cost.
My personal rule of thumb: if you could give the same task to three interns and have them work in parallel, subagents will probably help. If the task has hard dependencies between steps, single agent every time.
A more concrete decision tree:
- Will the task finish in under 5 minutes? → Single agent. Don't bother with subagents.
- Can you split it into 2+ truly independent subtasks? → Subagents might help.
- Are the subtasks each long-running? →
spawn_agents_on_csvis worth the complexity. - Do subtasks need to share state? → Stay single. Context isolation is a tax, not a benefit.
- Is your budget tight? → Run a single agent first. If it works, you're done.
In my experience, the threshold is: task takes 15+ minutes AND can be split into 3+ parallel branches. Below that, the startup overhead of subagents eats the savings.
Closing
I'm not done with this. Next up is a deeper piece where I take an open source repo, run a full PR review workflow with subagents, and quantify cost, speed, and quality against a single-agent baseline. If the numbers are interesting, you'll see it here.
For now, if you take one thing away: subagents are real, they work, and the cost is real too. Don't reach for them by default. Reach for them when the task is screaming for parallelism.
If you have questions, drop them in the comments. I read them.
- References: Codex Subagents docs · Codex CLI features · Codex workflows*