DEV Community

Cover image for Codex Needed Better Subagent Control. So I Built It.
Viktor Vítovec
Viktor Vítovec

Posted on • Originally published at vvitovec.com

Codex Needed Better Subagent Control. So I Built It.

I use Codex every day, and subagents are one of those features where the potential is immediately obvious. They can already work in parallel, use custom roles, and load their own configuration. But once I wanted precise control over model choice, reasoning effort, and a larger queue of jobs, I started hitting differences between the various Codex surfaces.

So I built my own orchestration layer. Not as a replacement for Codex, but as a more programmatic layer on top of it.

What Codex can already do

Native Codex subagents are not a toy. The current official documentation describes the built-in default, worker, and explorer roles, custom agents in .codex/agents/*.toml, thread limits, and per-agent settings for the model, model_reasoning_effort, sandbox, MCP servers, and skills.

Codex can spawn a child, wait for it, send follow-up instructions, interrupt it, and bring its result back to the lead agent. For large repetitive workloads, there is also an experimental spawn_agents_on_csv flow that creates a worker per row and collects structured results into another CSV.

That is a strong base. The problem is not that Codex lacks subagents. The problem is that capabilities still vary between the desktop app, CLI, tool-backed sessions, and experimental modes. Something that can be expressed in a custom-agent TOML is not necessarily exposed with the same reliability as a dynamic choice on every spawn surface.

V1 and V2 subagents in Codex

V1 and V2 are not two variants documented as such in the user-facing docs. They are names for two implementations in the openai/codex upstream.

V1 is the stable path today. A lead agent starts child threads, waits for results, and can steer them afterward. Current upstream V1 can pass model and reasoning_effort directly at spawn time, while custom-agent TOML can pin them. My particular tool-backed desktop session did not expose those fields in its spawn_agent schema; it only offered the task name, prompt, and context-fork mode. The limitation is therefore not universal to Codex core, but an inconsistency between surfaces.

V2 is a more ambitious orchestration rebuild. It is built around canonical task paths, direct send_message, followup_task, and list_agents tools, and more granular fork_turns control (none, all, or the last N turns). It remains behind a feature flag and is marked UnderDevelopment upstream. A full-history fork intentionally rejects a different agent_type, model, or reasoning_effort; a child with a different role, model, or effort therefore needs a clean or partial fork. OpenAI collaborators have additionally said in GitHub issue discussions — not in the official docs — that V2 is not yet recommended for stable use.

Neither version is a good interface for precisely controlled orchestration yet. Not because they cannot split up work, but because I do not get reliable control over the model, reasoning effort, and token budget of every child across all Codex surfaces. Upstream supports some of those choices, but product workflows can still lock them, hide them, or take over the decision for me.

Ultra is an even more interesting case. OpenAI describes it as a multi-agent mode that coordinates four agents in parallel by default. It can therefore burn through tokens like almost nothing else, especially once a task starts branching. I would not claim that it is literally the public Codex multi_agent_v2 implementation, or that Ultra subagents recursively spawn more Ultra subagents, because OpenAI has not publicly confirmed either point. The practical limitation is the same either way: I can see the result of very powerful orchestration, but I do not get reliable per-child control over model, effort, depth, and budget.

This area changes quickly. Treat this section as a snapshot from July 13, 2026, not a permanent verdict on Codex.

What I was missing

I wanted the strongest model to act as a control plane: understand the project, split the work, choose the right worker, and verify the integrated result. I did not want every mechanical scan or routine check to inherit the most expensive model at an extreme reasoning setting.

The main point is to use the smartest model as the orchestrator and weaker, faster, cheaper models as workers. The orchestrator should spend its intelligence on architecture, delegation, and verification; workers should execute tightly scoped jobs at a sensible cost. Without my layer, I cannot reliably assemble and control that hierarchy dynamically across the different Codex surfaces today.

More specifically, I wanted to:

  • select the model and effort per job instead of hoping the runtime picked what I meant;
  • keep feeding a queue programmatically instead of manually spawning dozens of agents;
  • allow one writer by default unless ownership scopes were genuinely separate;
  • resume after interruption without repeating completed jobs;
  • keep a manifest, logs, a hash of the final artifact, and discovered thread IDs when the event stream exposes them;
  • run the same workflow on my MacBook, Mac mini, and Linux server.

My solution: Codex as the engine, my runner as the control layer

The result is the open-source vvitovec/codex-orchestration project. It contains five cooperating skills for decomposition, routing, compact delegation prompts, review, and scaling. I then added a real programmatic runner on top of codex exec.

Each job is a normal JSONL record:

{"id":"api-review","model":"gpt-5.6-terra","effort":"medium","sandbox":"read-only","workdir":".","prompt":"Review the API surface and return concrete risks."}
Enter fullscreen mode Exit fullscreen mode

The runner passes the model and effort explicitly to the Codex CLI, limits total and write concurrency, locks a run against duplicate execution, persists an atomic manifest, and verifies that a supposedly successful job actually produced a completed result. It records the output size and SHA-256 hash, so a missing or modified artifact cannot hide behind an old succeeded state during resume.

A timed-out writer is not automatically repeated unless the job is explicitly marked safe and idempotent. Parallel writers require an explicit opt-in and unique ownership_scope values. These details are boring, but they are what separates a nice orchestration demo from a workflow I am willing to point at a real repository.

Where it is different, and where native Codex is still better

My layer gives me more programmatic freedom. The requested model, effort, sandbox, timeout, retry policy, and ownership are not merely prompt suggestions: the runner passes them as CLI arguments or configuration and records them in a persistent manifest. That guarantees the exact launch request, not the effective backend route, which current codex exec --json does not explicitly attest. The queue can contain three jobs or three hundred and still behaves like a queue rather than a long chain of manual tool calls.

I am not pretending that I built a better Codex. Native subagents have a huge integration advantage: their threads are visible in the UI, I can steer them naturally, and the lead agent can collaborate with them conversationally. My runner is stronger for deterministic batches and auditable automation. The native system is nicer for interactive work.

Codex App Server already exposes better route information and reroute events, so that is the natural next backend for this project.

One of the few unfinished parts. For now.

This is not an attack on Codex. Quite the opposite: it is my main working tool because the team ships at an absurd pace and clearly cares about the product. Thibault “Tibo” Sottiaux, one of the people behind Codex, is unusually open on X and GitHub, responds to concrete problems, and the team often addresses user feedback before another company would finish scheduling the roadmap meeting.

I have also been testing GPT-5.6 Sol and the other models pretty intensely since release, and I think they are excellent. I have produced more code and finished more work with them than ever before. They can also keep going for absurdly long runs: the cover screenshot is one of my own GPT-5.6 Sol Ultra runs, at 23 hours and 50 minutes.

That is why I expect OpenAI to improve the native multi-agent workflow quickly. Custom agents and CSV fan-out already point in the right direction. My orchestration gives me the control I need today, while also being a useful experiment in how agent routing could become more precise.

Subagents are one of the few parts of Codex that still feel genuinely unfinished to me. FOR NOW.

I keep the rest of my technical experiments and builds in my projects.

Top comments (1)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.