Course · Codex · Models & effort
Models & effort
A rules file decides what a coding agent knows; a sandbox decides what it may touch. Neither says anything about how hard it should think. That is a separate pair of knobs: which model answers at all, and how much reasoning effort it spends before it answers. Spend too little and a design decision ships as an unexamined guess; spend too much and you pay in tokens and waiting for deliberation the task never needed.
This chapter works both knobs against two concrete jobs in the running example repo, budgetcli (a small self-hosted personal-finance API: 166 lines of Python, about 230 lines all told, a pytest suite the course has kept green (seven tests in its labeled continuation), CSV import in app/importers/csv.py, money stored as integer cents).
Two tasks, one afternoon
Section titled “Two tasks, one afternoon”The light job: add an optional category filter to GET /transactions. The pattern sits ten lines away in app/main.py - a route decorator, a short handler, a call into the ledger - and the filtering method, ledger.by_category(), already exists, unused. One right answer, no fork: mirror the shape, delegate to the method, done.
The heavy job: wire categorise() into the import path. The keyword table in app/services/categorise.py exists and is correct (spotify and netflix to entertainment, whole foods to groceries, starbucks to dining, and so on, else uncategorised), but imported transactions still land uncategorised, because nothing calls it. Wiring it is a genuine fork: the hook could go in parse_csv or in the import route, and a description matching two keywords needs a rule for which one wins.
One job follows a pattern; the other contains a real design decision. Same repo, same size of edit - different amounts of thought earned.
The claim, before any dial moves
Section titled “The claim, before any dial moves”Size does not separate the two jobs. Both edits are a handful of lines, and the whole repo is ten files, roughly 2,000 estimated tokens by this course’s declared estimators - about one percent of a 200k window. Ambiguity is what separates them: the filter has one defensible answer, the wiring several.
Here is the chapter’s claim, with its basis stated up front. Run the filter through every effort level and the code that comes back is the same few lines each time - only the wait and the spend change. Run the wiring through the same stops and the output itself shifts, because most levels never surface the questions that decide it. The traces ahead are constructed for the comparison, not captured, and the split holds by construction - it is built into how the two task shapes differ.
The rest of the chapter walks that through stop by stop and ends on one table that says which gear earns its keep on which shape:
- Move the effort dial through its levels on both tasks, holding the model fixed.
- Move the model instead - the other knob - holding effort fixed, on the same two tasks.
- Bundle both into a profile, the way trust settings were bundled in the approvals chapter, so the right pairing returns with one flag.
- Read the bill without a price tag, land the wiring for real, and close on the matrix every stop was building toward.
Start with the dial that moves first and costs least to get wrong - the reasoning-effort levels, run against both jobs.