Codex prompting tips: prompts that get done right the first time
How to write prompts Codex executes well: goal, context, constraints and verification, with before and after examples and when a prompt should become a skill.
The four parts of a prompt that works
OpenAI’s guidance for Codex comes down to this: a useful prompt names the behavior you want, points to the relevant code or reproduction steps, preserves the important constraints, and says how to verify the change. Their general prompting advice uses four headings that map onto it:
| Part | Question it answers | Example |
|---|---|---|
| Goal | What should be true when you are done? | “Saving settings persists after reload” |
| Context | Where should Codex look? | “src/settings/, the bug started after #412” |
| Constraints | What must not change? | “Keep the public API of SettingsStore” |
| Verification | How do we know it worked? | “Add a test that fails before the fix; run pnpm test settings” |
Use only the parts a task needs. “Rename getUser to fetchUser across the repo” needs no ceremony. A bug that only appears in production needs all four.
Before and after
Fixing a bug
Before:
the settings page is broken, fix it
After:
Bug: clicking Save on /settings shows "Saved" but the change is gone after reload.
Repro: pnpm dev, change the display name, Save, reload.
Likely area: src/settings/ (SettingsForm.tsx and api.ts). It started after PR #412.
Write a failing test that reproduces it first, then fix the cause. Do not change
the SettingsStore public API. Done when `pnpm test settings` passes and you can
explain the cause in two sentences.
The second version gives Codex a reproduction, a search area, a constraint and a stopping condition. The systematic-debugging skill bakes that loop in, so you can write less.
Adding a feature
Before:
add rate limiting to the API
After:
Add per-API-key rate limiting to the public endpoints in src/api/public/.
Limit: 100 requests per minute per key, sliding window, stored in the existing Redis
client (src/lib/redis.ts). Over the limit, return 429 with a Retry-After header and
our standard problem+json error body.
Do not touch internal endpoints or add dependencies.
Start with a short plan; wait for my OK before editing.
Verify with unit tests for the limiter and one integration test hitting /v1/search.
Asking for a plan first is the cheapest review you will ever do. In the CLI, /plan switches Codex into planning mode for the same effect.
Understanding code
Before:
explain this repo
After:
I need to change how invoices are numbered. Explain the invoice flow from
POST /invoices to the PDF being stored: modules involved, where numbers are
generated, what is validated where, and one or two things that would break if
numbering changed. End with a numbered list of the files involved.
Purpose shapes the answer. “Explain this repo” gets a tour; “I need to change X” gets what you need for X.
Refactoring
Before:
clean up the payments module
After:
Refactor src/payments/charge.ts: split the 300-line chargeCustomer() into steps
(validate, compute amount, call provider, record result) without changing behavior.
Run the existing tests before and after each step; stop and tell me if any test
needs to change. One commit per step.
“Without changing behavior” plus “tests before and after” is the whole contract of a safe refactor. See safe-refactoring.
Reviewing
Before:
review my changes
After:
Review the diff against main for correctness first: race conditions in the job
queue changes, missing error handling, and any query without a tenant filter.
Ignore formatting. List findings by severity with file:line and a suggested fix.
Do not edit files.
codex review --base main runs a dedicated non-interactive review as well.
Give context the efficient way
-
Point, do not paste. In the CLI, type
@to insert a file path or use/mention. Codex reads the file itself. -
In the IDE extension, open files and selections are included automatically, so select the code you mean.
-
Images help for UI bugs and diagrams:
codex -i screenshot.png "the dropdown overlaps the header at 768px; fix it". -
Pipe output instead of describing it:
npm test 2>&1 | codex exec "summarize the failing tests and propose the smallest likely fix" gh run view 123456 --log | codex exec "find the first real error and the likely cause" -
Name what to ignore. “Ignore
vendor/and generated files” saves context in large repositories.
Steer instead of restarting
Your first prompt does not have to be perfect. While Codex works, press Enter to steer the current turn (“also handle the empty list case”) or Tab to queue a follow-up for the next turn. If a turn went wrong from the start, press Esc twice to edit your previous message and fork from there rather than piling corrections on top.
Prompts for codex exec
Non-interactive runs cannot ask you questions, so the prompt must stand on its own:
codex exec --sandbox workspace-write \
"CI failed. Run npm test --silent to reproduce. Make the minimal change that makes
the tests pass, run npm test --silent again, and do not modify unrelated files.
Finish with a one-paragraph summary of the cause and the fix."
- State the exact commands to run and the condition for success.
- Say what not to touch.
- Specify the output format. For machine consumption, add
--output-schema schema.jsonand-o result.json. - Choose the sandbox deliberately;
codex execis read-only unless you say otherwise.
The codex-output-schemas skill helps design schemas that validate.
Common mistakes
- Vague success criteria. “Make it better” ends whenever Codex decides. Name a test, a number or an observable behavior.
- Over-specified steps. A 20-step recipe for a problem Codex has not investigated yet often encodes a wrong guess. Describe the result; let Codex find the path, then review its plan.
- Hidden constraints. If the API must stay backward compatible, say so. Codex cannot read your mind or your last meeting.
- Everything in one prompt. Large changes go better as a plan followed by small, verified steps. codex-task-decomposition covers splitting work.
- Repeating yourself every session. That is a sign the instruction belongs somewhere permanent.
When a prompt should become a skill or an AGENTS.md rule
Some prompts you write once. Others you find yourself pasting every week. Promote them:
| Signal | Move it to |
|---|---|
| A rule that applies to every task (“use pnpm”, “run lint before finishing”) | AGENTS.md |
| A procedure for one kind of task, longer than a few lines | A skill |
| A procedure the whole team uses | A skill in the repository’s .agents/skills |
| A procedure that should only run when you ask | A skill with allow_implicit_invocation: false |
Converting is quick. The review prompt above becomes .agents/skills/backend-review/SKILL.md:
---
name: backend-review
description: Reviews backend diffs for correctness - race conditions in job queues, missing error handling, queries without tenant filters - and reports findings by severity with file:line and a fix. Use when asked to review a backend change, a PR touching src/jobs or src/db, or before merging.
---
1. Diff against the base branch the user names, else main.
2. Check, in order: tenant filters on every query, error handling on external calls,
concurrency in src/jobs/. Ignore formatting.
3. Report findings as: [Severity] title, file:line, why it matters, suggested fix.
4. Do not edit files.
Now “review this before I merge” triggers it, and $backend-review forces it. Custom prompts in ~/.codex/prompts used to fill this role, but they are deprecated in favor of skills. The first skill tutorial walks through building and testing one, and the codex-prompting-patterns skill helps Codex rewrite your prompts in this shape.
Frequently asked questions
What makes a good Codex prompt?
It names the behavior you want, points to the relevant code or a way to reproduce the problem, states the constraints that must hold, and says how to verify the result. Short prompts are fine for small tasks; add these parts as the stakes grow.
Should I tell Codex every step?
Usually not. Describe the result and the boundaries and let Codex investigate. Spell out steps only when the process itself matters, such as a migration order or a release checklist, and at that point consider writing a skill.
How do I give Codex context in the CLI?
Type @ to insert file paths, use /mention to attach a file, attach screenshots with --image, and pipe logs or command output into codex exec. In the IDE extension, open files and selections are included automatically.
When should a prompt become a skill?
When you have pasted roughly the same instructions three or more times, when the instructions are longer than a few lines, or when teammates need the same workflow. A skill loads automatically when the task matches and can be shared through the repository.