All writing

How I Set Up Codex as a Small Model Team

I use Codex as a small team rather than asking one session to do every kind of work. Sol is the orchestrator: it plans, splits independent tasks, and checks the results. Terra handles work that needs careful reasoning, while Luna handles the mechanical work that benefits from being quick and focused.

The setup is deliberately small. There is one global config, one set of team rules, and one custom-agent file for each role. These are the public copies I keep reusable across projects.

codex-config.toml
model = "gpt-5.6-sol"
model_reasoning_effort = "high"

[features]
multi_agent = true

Sol starts at high, which is enough for ordinary planning and coordination. I keep higher effort as an exception: xhigh is for a hard single-agent task, and Ultra is only worth using when the work is meaningfully parallel. There is no Max setting in this setup.

codex-agents.md
# Codex model team

You are the Sol orchestrator. Use Sol for planning, splitting independent work, and synthesizing verified results. Delegate substantial implementation work instead of doing it in the orchestrator session.

## Roles

### deep-reasoner (Terra)

Use Terra for architecture, trade-off analysis, hard debugging, race conditions, algorithm design, and other complex logic.

### fast-worker (Luna)

Use Luna for boilerplate, tests, formatting, lint fixes, and clear small changes.

## Model and effort rules

- Keep the baseline at `high`.
- Use `low` or `medium` for mechanical work.
- Use `xhigh` only for a hard single-agent task that needs extra reasoning.
- Do not use `max`.
- Use Ultra only when the work is meaningfully parallel and multi-agent orchestration is worth the overhead.
- When calling `spawn_agent`, always set both `model` and `reasoning_effort` explicitly.

The rules define ownership before they define models. Sol owns the decision about what to delegate; Terra and Luna own different kinds of execution. The explicit spawn_agent requirement keeps a later caller from silently changing either the model or its effort level.

deep-reasoner.toml
name = "deep-reasoner"
description = "Use Terra for architecture, trade-off analysis, hard debugging, algorithms, and complex logic."
model = "gpt-5.6-terra"
model_reasoning_effort = "high"
developer_instructions = """
You are the deep-reasoner (Terra). Handle architecture design and trade-off analysis, hard debugging including unclear-cause bugs and race conditions, algorithm design, and complex logic.
"""

Terra is the judgment-heavy lane. I send architecture, unclear-cause bugs, race conditions, and algorithm design there because those tasks benefit from spending more effort before making a change.

fast-worker.toml
name = "fast-worker"
description = "Use Luna for boilerplate, tests, formatting, lint fixes, and clear small changes."
model = "gpt-5.6-luna"
model_reasoning_effort = "high"
developer_instructions = """
You are the fast-worker (Luna). Handle boilerplate, tests, formatting, lint fixes, and simple changes such as typos, renames, and clear small edits.
"""

Luna is the execution lane: boilerplate, tests, formatting, lint fixes, and small changes with a clear solution. The reusable custom role defaults to high to match the global agent config; mechanical per-call stages can explicitly lower effort to medium or low.

The useful part is not the names. It is the boundary: one session decides what kind of thinking a task needs, the appropriate specialist does the work, and the orchestrator verifies the result before combining it with anything else. That is enough structure to make a small model team predictable without turning every conversation into a workflow diagram.