Skip to content

Course · Codex · Daily workflow

Briefing the agent well and smoothing the editing surface on budgetcli

The last lesson fixed the posture you work in; combined with the rules file, it took the course’s constructed fourth-bank job from 11 exchanges to 6 (the fourth bank is the teaching scenario; the repo imports a single format). This lesson protects the rest of the gain - not by adding a fifth technique, but by making sure the two you already built, the skill and the effort dial, land the way they were measured.

A profile without a sharp brief still burns a turn on a misread. A skill still has to be asked for cleanly, or it never fires at all.

Here is the difference that catches people. Chatting with a model, a vague question is cheap: you read the half-useful answer and ask again, and you have lost seconds. With an agent, one prompt can trigger a chain of work - read the importer, edit the parse path, run the tests, edit again - that grinds for minutes before it surfaces anything you can review.

By the time an ambiguous instruction bites, the agent has touched files on the strength of a guess. Vagueness did not cost you a re-ask; it cost you a run and a diff to unpick. The whole skill is reducing the ambiguity before execution starts, not correcting it after.

A prompt the agent cannot misread on budgetcli (the course’s running example, a small self-hosted personal-finance API in Python and FastAPI) has the same four parts every time. You do not need a template or a heading for each - just do not leave one out. (The new card’s export below is that constructed fourth bank.)

  1. Goal - what done looks like, in one concrete sentence, with an outcome verb. Not “look at the CSV importer,” but “extend app/importers/csv.py to read the new card’s statement format.”
  2. Context - the framework, and an analogous bit of the codebase to copy. “It is the same FastAPI service; follow the pattern in app/importers/csv.py, the one importer the repo has.” A pointer to existing code is worth a paragraph of description - the agent reads the reference and matches it.
  3. Constraints - what not to do. “Do not add new dependencies, do not change what POST /transactions accepts, money stays integer cents.” The off-limits list is where most wrong-but-reasonable runs come from: the agent will confidently make a technically fine choice that is wrong for this project if you never told it where the edges are.
  4. Completion criteria - a check it can actually run. “The new export imports and pytest exits clean.” Now the agent knows when it is finished instead of when it is tired.

A useful gut-check for scope: the sweet spot is a task a colleague could finish in an afternoon, with a clear before-and-after. Bigger than that, break it into ordered steps, each with its own small verification gate - the file parses, then the rows categorize, then the suite passes - so a wrong turn surfaces at the next gate instead of three changes downstream.

Most of this only needs saying once, though. The durable stuff - money is integer cents, dates are ISO, the test command - already lives in the AGENTS.md the repo has carried all week, and the agent reads it at session start. That is the point of writing things down: your per-task prompt carries only what is specific to this task. If you catch yourself re-typing a convention into every prompt, it belongs in the rules file, not the prompt.

Stop and rewrite - don’t nudge a bad run

Section titled “Stop and rewrite - don’t nudge a bad run”

When a run starts heading somewhere wrong, the instinct is to nudge it back: “no, not like that, do it this way instead.” Sometimes that works. But when the run went wrong because your prompt had two valid readings - and the agent picked the one you did not mean - nudging is the slow road. You are correcting on top of a foundation built from the wrong interpretation, and each correction inherits the original ambiguity.

The course lived a real two-reading prompt in the models chapter: “wire the categorizer into the import.” It had two valid homes - inside parse_csv, or in the import_csv loop in app/main.py - and they are not equivalent. The faster move, always, is to stop, throw the run away, and rewrite the brief so the reading you wanted is the only one left: “categorize inside parse_csv, so the parse hands the ledger fully labeled transactions,” stated up front rather than discovered three corrections in.

Reframing beats patching because the ambiguity was a bug in the prompt, not a failing of the agent. Interrupt immediately - the longer a misread run goes, the more diff you are discarding. A clean restart from a sharper brief beats five rounds of “no, the other thing.”

This is also why the budget-audit profile earns its place. While you are still figuring out what to ask for, explore with the agent unable to write - the cost of a misread is zero, because nothing changed. You switch to budget-build only once the brief is sharp enough to commit to.

The brief is the big lever. The small one is the friction in actually typing it - and because you do it dozens of times a day, small friction adds up to more than it looks.

The two ergonomics worth building into reflex:

  • Point at files by path instead of describing them. When you mean a specific file, name it rather than spending a sentence on where it lives - app/importers/csv.py lands faster and more precisely than “the CSV importer, in the importers folder.” Letting the agent resolve a path you typed is cheaper than letting it guess one from prose.
  • Let your shell carry your defaults. If you almost always want the same profile, you should not be re-typing it. The alias from the last lesson, or a small wrapper function, means a bare codex lands in the posture you want most, and you spend explicit flags only on the exception.

None of these is a feature you learn once; they are habits that shave a second off the action you repeat most. Over a week on budgetcli that is the difference between the tool feeling like a chore and feeling like an extension of your hands. The current set of input affordances is worth a skim in the Codex CLI reference so you adopt the ones that fit how you work.

Not every prompt deserves your full attention budget. Reformatting a docstring, renaming a field, regenerating a fixture - low-stakes, well-specified, and you mostly want the answer quickly rather than carefully. Fast mode - the latency tier covered in Switch models - is worth reaching for on these mechanical sweeps.

Pair it with the light end of the reasoning-effort dial and you have a genuinely fast loop for the trivial stuff, which frees your patience for the prompts that deserve it.

The skills chapter already ran this exact comparison and put a number on it: the same fourth-bank job, once the import procedure is packaged as a skill instead of narrated fresh each time, drops from 6 turns to 2. That is not this lesson’s number to claim - the skill mechanically closes the gap, by recognizing the situation and running the five import steps itself instead of waiting for you to spell them out again.

What a sharp brief and a matched effort setting buy is smaller and easier to miss: they stop those 2 turns from creeping back to 3 or 4 when the skill needs a nudge - a column that does not map cleanly, a date format it guesses wrong - and they keep each turn cheap. This task is pattern-following work, the same corner the category-filter endpoint sat in. Reach for high effort anyway and you are spending more tokens for the same two turns, not fewer.

The skill buys the turn count. The brief and the dial are what stop you from losing it back.

That is most of the friction. You have profiles you switch by instinct, briefs sharp enough that runs go where you meant, and the small ergonomics that make the common case free. But even sharp briefs go sideways sometimes - the next lesson is the recovery reflex for when a run loops or drifts, and the honest reading of whether the stack actually holds.