Course · Codex · Skills
Choose between a Skill, an AGENTS.md rule, and a plain prompt
You’ve now watched recognition take the defined scenario from six turns to two. But “write something down so Codex does it right” describes three different containers, and reaching for the wrong one is a common way to fight the grain. This lesson is the decision: when the import procedure is genuinely a Skill, when the next thing you want to capture is really an AGENTS.md rule, and when it shouldn’t be written down at all.
Skill vs rule: what Codex does vs what it knows
Section titled “Skill vs rule: what Codex does vs what it knows”This is the distinction that matters most, and the one most often gotten wrong. Both a Skill and AGENTS.md are “context you write down once” - but they load differently and they answer different questions.
- An
AGENTS.mdrule is a standing fact. “Money is integer cents, never floats.” “Dates are ISO 8601 UTC, never locale-dependent formats.” Codex readsAGENTS.mdautomatically at every session start, so a rule is always in view - it shapes everything Codex does, whether or not you mention it. - A Skill is a procedure. “To onboard a new bank’s CSV: read a sample, map the columns, normalize dates, convert to cents, write the importer.” Its metadata stub - name and description - sits in the always-present skills list for discovery; its body loads only when the situation fires, runs as a sequence of steps, and stays on disk the rest of the time.
The test: can you run it? “Always store money as cents” isn’t something Codex runs - it’s a constraint it should hold at all times. That’s a rule. “Import a new bank’s CSV” is a multi-step thing Codex does on a specific occasion. That’s a Skill.
Put a standing fact in a Skill body and it only applies when the Skill happens to fire - exactly when you don’t want a money rule to be conditional. Put a multi-step procedure in AGENTS.md and it’s loaded into every session whether you’re importing that day or not, paying full context cost to sit idle.
You saw the two cooperate two lessons back: the cents rule lives in AGENTS.md as a standing constraint, the parse path now implements it in code, and the import Skill restates the conversion step at the one point where a fresh bank’s format still slips past it. That’s not redundancy - the rule governs everything; the Skill puts the check at the point of maximum risk.
Rules are the floor; a Skill reinforces the floor where a procedure tends to trip over it. The rent a rule pays for always-on coverage is real, and it’s priced in the good-rules lesson - keep that pricing in mind for the table below.
Skill vs plain prompt: does it repeat?
Section titled “Skill vs plain prompt: does it repeat?”The other failure is over-engineering - packaging something as a Skill that didn’t need packaging. The honest test is repetition:
- One-off, or rare and varied -> a plain prompt. If you’re parsing one weird file once, just ask Codex to do it in the conversation. A
SKILL.mdthat takes longer to write than the task it automates has been over-built. - Same multi-step procedure, again and again -> a Skill. The import job cleared this bar the moment you noticed the same five steps narrated for each new format, at six turns apiece.
A good way to arrive at a Skill is to not write it first. Do the job by hand in a normal session - onboard the first new format as a plain prompt. By the third time, you’ll know the exact steps, the failure modes, and the wording that triggers it. Then the SKILL.md writes itself, grounded in a procedure you’ve actually validated rather than one you guessed at.
Same job, three routes
Section titled “Same job, three routes”Put a number on it rather than trust the shape of the argument. Take the exact task from this chapter - onboard one unseen format’s CSV - and run it through all three containers, in the defined scenario’s own arithmetic:
| Route | This job’s cost | Recurs next format? | Verdict |
|---|---|---|---|
| Skill | ~90 tokens every session (the stub) + ~300 tokens only when it fires; 2 turns | Yes - the procedure is captured once | Right home |
AGENTS.md rule |
The same ~300-token procedure, loaded on every session, importing or not - on top of the ~115 tokens the existing rules file already spends | Yes, but the coverage is paid for whether or not it is used that day | Wrong shape - pays rent idle |
| Plain prompt | ~0 tokens until you need it, but 6 turns of re-describing, re-asking, and re-correcting - the walkthrough from the chapter opening | No - you’re the memory, and the step you forget is the one that bites | Works once, taxes forever |
Same procedure, same job, three prices. The Skill is the only route that’s both cheap on a quiet day and complete on the day it’s needed.
The three-way test
Section titled “The three-way test”When you’re about to write something down for Codex, ask in this order:
- Is it a fact Codex should always hold, or a procedure it runs on occasion? Always-on constraint or domain fact ->
AGENTS.mdrule. A multi-step thing it does at a specific moment -> Skill. - Does the procedure actually repeat? A genuine, recurring, multi-step routine -> Skill. A one-off or rarely-the-same task -> just prompt it; don’t build a file.
- If it’s a Skill, should Codex fire it on its own? Harmless if mistimed, like our preview-first import -> leave implicit invocation on and let recognition fire. Expensive, slow, or state-changing -> take it off the automatic menu with
allow_implicit_invocation: false, from the last lesson.
Keep those straight and you’ll almost always reach for the right container. Rules are what Codex knows; Skills are what it does; a plain prompt is for what it does once. The quiet mistake is cramming a standing fact into a Skill body, where it only loads when the Skill fires, instead of into AGENTS.md where it’s always in view - so when in doubt, ask whether the thing is a fact or an action.
You can run that judgment on the ledger it’s really about. A rule pays its full size in every run; a Skill pays a tiny always-visible stub and loads its body only when it fires; a plain prompt costs nothing until you need it - and again every time after. Four pieces of knowledge, three homes each - see what the wrong home costs:
Notice which placements the widget punishes hardest: a fact filed as a skill, because a fact has no moment of invocation and just never loads, and a procedure filed as a rule, paying rent every session for the few that need it. Those are the two swaps this lesson exists to stop you making.
What a Skill still can’t do
Section titled “What a Skill still can’t do”A Skill orchestrates what Codex can already reach - your files, your shell, the importer and the suite inside the repo. That is enough for the import procedure, because everything it touches is in budgetcli (the course’s running example, a small self-hosted personal-finance API in Python and FastAPI). What skills add is what the agent runs on recognition - and two things are still missing from that picture, both of them the next chapter’s material.
One is reach beyond the repo. Constructed scenario, the same one the approvals chapter met: a handful of transactions sit in euros and pounds, and converting them honestly wants a live exchange rate from an API the repo has no client for. No skill can run what the agent has no tool to call - wiring a new tool in is a separate kind of extension.
The other is the hard guarantee. A skill is still guidance - instructions the model reads and can argue with, exactly like an AGENTS.md rule. For a condition that must hold no matter what the model decides - run the money tests after every money edit, no exceptions - you need a check that doesn’t live in the model’s head at all. Reach and guarantees are the extending chapter: MCP servers for the first, deterministic hooks for the second.
What the Skill changed, and what it cannot
Section titled “What the Skill changed, and what it cannot”Set the finished Skill beside the chapter’s starting point. The date-fix kind of work holds because it is a line in git; the habit behind it did not, because nothing carried the procedure forward to the next format. The Skill closes that second gap - not just today’s job done, but tomorrow’s version of the same job already covered: a ~90-token stub every session, ~300 more only when it fires, and two exchanges instead of six, with the mapping still confirmed before any write.
The container decision is settled now, and it is worth saying in one breath: a fact Codex should always hold goes in AGENTS.md; a repeating procedure becomes a Skill; a one-off stays a prompt. The import-bank-csv Skill sits under .agents/skills/ on your disk, and every export that lands from here on runs the same five steps without you narrating them.
What skills cannot supply was already visible at the edge of this one: reach past the repo - that external exchange-rate API - and guarantees that cannot be argued with, whatever the model’s confidence. That is the extending chapter.