Writing Custom Instructions for OpenAI Codex
Codex custom instructions are how you teach OpenAI's Codex CLI the rules of your codebase before it writes a single line of code. They live mainly in a file called AGENTS.md, plus a handful of settings in ~/.codex/config.toml, and once you understand how Codex discovers and merges them, you can make the agent behave like a developer who has already read your style guide, your test setup, and your deployment checklist. Most people skip this step and then complain that Codex "doesn't know how we do things here." It knows exactly what you tell it, in the files it's designed to read.
This guide walks through every layer of Codex custom instructions: the AGENTS.md format, where Codex looks for it, how nested files merge in a monorepo, global defaults in config.toml, custom slash-command prompts, and the approval/sandbox settings that shape how aggressively the agent acts on your instructions.
What Custom Instructions Actually Do in Codex
When you run codex in a terminal, the agent doesn't just see your prompt. Before it starts reasoning about your task, it assembles a system context that includes:
- The contents of any AGENTS.md files it finds, from the most general to the most specific
- Global instructions set in your config file
- The current shell environment, working directory, and git status
- Whatever custom prompt or slash command you invoked, if any
Custom instructions are plain-language rules injected into that context. They are not a config schema with fixed keys, they are prose the model reads and follows the same way it would follow a written brief from a senior engineer. That means the quality of your instructions matters as much as their presence. A vague AGENTS.md ("write good code") does almost nothing. A specific one ("run npm run lint before every commit, never touch files under generated/, use pnpm not npm") changes agent behavior immediately.
The AGENTS.md File: Your Primary Tool
AGENTS.md is a plain Markdown file that sits in your project. Codex treats it as the canonical place for project-specific instructions, the same role CLAUDE.md plays for Claude Code. There's nothing exotic about the format, it's just headings and bullet points, but a few conventions make it far more useful.
Start with a short paragraph describing what the project is, then break the rest into sections the agent can scan quickly:
# AGENTS.md
This is the backend API for Acme Checkout, a Node.js service on Express with a Postgres database accessed through Prisma.
## Setup
- Install dependencies with `pnpm install`, never `npm install`
- Copy `.env.example` to `.env` before running anything
- Start the dev server with `pnpm dev`, it runs on port 4000
## Testing
- Run the full suite with `pnpm test`
- Run a single file with `pnpm test path/to/file.test.ts`
- Every new endpoint needs at least one integration test in `tests/integration/`
- Do not mark a task done until `pnpm test` passes
## Code style
- Use named exports, not default exports
- Keep controllers thin, put business logic in `src/services/`
- No `any` types in TypeScript, use `unknown` and narrow it
## Things not to touch
- Never edit files under `src/generated/`, they are produced by `pnpm codegen`
- Never modify `prisma/migrations/` by hand, use `pnpm prisma migrate dev`
## Commit conventions
- Use Conventional Commits (`fix:`, `feat:`, `chore:`)
- Keep commit subject lines under 72 charactersThis is enough to change how Codex behaves on almost every task in that repo. It will run the right install command, use the right test command, avoid regenerated files, and stop writing default exports.
A few rules for writing a good one:
- Be concrete. "Use good naming" is noise. "Use camelCase for variables, PascalCase for React components" is a rule the model can apply.
- Put the most important constraints first. Codex, like most agents, weighs earlier context more heavily when instructions get long.
- List the exact shell commands you want run, verbatim, in backticks. Don't make the model guess your script names.
- Call out anything destructive explicitly: files that must never be deleted, branches that must never be force-pushed, migrations that must never be edited by hand.
- Keep it current. A stale AGENTS.md that references a build tool you dropped six months ago is worse than no file at all, because the agent will confidently follow bad instructions.
Where Codex Looks for AGENTS.md Files
Codex resolves instructions from multiple locations and merges them, going from general to specific:
- A global AGENTS.md at
~/.codex/AGENTS.md, applied to every session regardless of project - A project-root AGENTS.md at the top of the repository you're working in
- Nested AGENTS.md files in subdirectories closer to the files you're actually touching
When Codex works inside a subdirectory, it walks up the directory tree collecting every AGENTS.md it finds along the way, and it also picks up ones nested below the working directory if the task touches those paths. More specific files take precedence when there's a direct conflict, but in practice the layers are meant to be additive: global rules for how you like commits written, project rules for how this specific codebase works, and folder rules for the quirks of one package inside a monorepo.
You can check what Codex is picking up before you trust it with a real task. Ask it directly in a session:
$ codex
> What instructions are currently loaded for this session? List every AGENTS.md file you're reading from.This is the fastest way to catch a misplaced or missing file before the agent starts editing code based on assumptions you didn't intend.
Global Instructions with config.toml
Project-level rules belong in AGENTS.md. Preferences that should apply to every Codex session on your machine, regardless of repo, belong in ~/.codex/config.toml. This is where you set defaults like the model to use, the approval policy, and sandbox behavior, and it's also where you can point Codex at a custom instructions file explicitly.
A typical config looks like this:
model = "gpt-5.1-codex"
approval_policy = "on-request"
sandbox_mode = "workspace-write"
[shell_environment_policy]
inherit = "all"
[profiles.careful]
approval_policy = "untrusted"
sandbox_mode = "read-only"
[profiles.yolo]
approval_policy = "never"
sandbox_mode = "danger-full-access"Profiles matter for custom instructions because they change how literally Codex acts on what you've written. A file that says "run migrations automatically" is meaningless under a read-only sandbox, because the agent physically cannot write to disk without asking. If your AGENTS.md assumes a certain level of autonomy (auto-running tests, auto-committing), make sure the profile you're launching Codex with actually grants that autonomy, otherwise your instructions and your sandbox contradict each other and you'll spend the session approving prompts you thought you'd already automated away.
You can launch with a specific profile from the command line:
$ codex --profile carefulor set a default profile in config.toml so you don't have to remember the flag:
profile = "careful"Nested AGENTS.md for Monorepos
If you work in a monorepo with a frontend, a backend, and a shared package, one AGENTS.md at the root trying to describe all three gets long and generic fast. Split it up instead.
repo/
AGENTS.md # repo-wide conventions: git flow, PR rules, CI
apps/
web/
AGENTS.md # React + Vite specifics for the frontend
api/
AGENTS.md # Express + Postgres specifics for the backend
packages/
ui/
AGENTS.md # component library conventionsThe root file should stay short and cover things true everywhere: how branches are named, how PRs get reviewed, how CI is triggered. Each subproject's file should cover its own build and test commands, since a frontend and a backend rarely share them.
# apps/api/AGENTS.md
Backend service. Run everything from this directory, not the repo root.
## Commands
- `pnpm dev` starts the API on port 4000
- `pnpm test` runs Vitest
- `pnpm db:reset` drops and recreates the local database, only run this in dev
## Boundaries
- This service owns the `orders` and `payments` tables, do not add migrations that touch other services' tables
- Never import from `apps/web`, the dependency only goes the other way through the shared `packages/ui` packageWhen Codex is asked to fix a bug in apps/api/src/routes/orders.ts, it picks up both the root AGENTS.md and the apps/api/AGENTS.md, so it knows the repo-wide PR conventions and the fact that it should run pnpm test from inside apps/api, not from the repo root. This nesting is the single biggest lever for keeping instructions accurate as a codebase grows, because a stale monolithic AGENTS.md is much more likely than a stale one scoped to a single package that its own team maintains.
Custom Slash Commands and Prompts
Beyond AGENTS.md, Codex CLI supports reusable prompt files that behave like slash commands. Drop a Markdown file into ~/.codex/prompts/, and Codex exposes it as /filename inside a session.
$ mkdir -p ~/.codex/prompts# ~/.codex/prompts/review.md
Review the current diff for correctness bugs and obvious security issues.
Do not comment on formatting or style, a linter already handles that.
List findings as a short bullet list ordered by severity.
If there are no findings, say so in one line, don't pad the response.Now inside any Codex session:
> /reviewruns that exact instruction against whatever you're currently working on. This is a different layer from AGENTS.md: AGENTS.md is ambient context the agent always has, prompt files are instructions you invoke on demand for a repeatable task, like reviewing a diff, writing a changelog entry, or drafting a commit message in your team's format. Keep a handful of these for the tasks you repeat every day instead of retyping the same instructions into the chat each time.
Approval Policy and Sandbox Settings That Affect Instructions
Custom instructions don't operate in a vacuum, they interact with how much Codex is allowed to do without asking. Three settings matter most:
approval_policycontrols whether Codex asks before running commands.untrustedasks for almost everything,on-requestasks for risky actions and runs safe ones freely,neverruns everything without asking.sandbox_modecontrols filesystem and network access.read-onlycan't write at all,workspace-writecan write inside the project directory,danger-full-accessremoves the sandbox entirely.shell_environment_policycontrols what environment variables and shell state the agent inherits.
If your AGENTS.md tells Codex to "install dependencies and run the dev server automatically," but your sandbox is read-only, the agent will describe what it would do and stop, because it can't touch disk. Match your instructions to your sandbox on purpose. A safe pattern for day-to-day work is workspace-write with on-request approval: Codex can freely edit files and run your test commands, but still asks before anything that touches the network or leaves the project directory. Save danger-full-access and never for isolated containers or throwaway environments, not your main machine.
Testing and Iterating on Your Instructions
Treat AGENTS.md like code, not documentation you write once and forget. A short loop that works well:
- Write a first draft covering setup, test commands, and the two or three things you'd be most annoyed to see Codex get wrong.
- Give it a real task and watch what it does before you approve any action. Did it use the right package manager? Did it run tests before declaring done?
- When it does something wrong, don't just fix the output, fix the instructions file so the next session doesn't repeat the mistake.
- Periodically ask Codex to summarize what it understood from AGENTS.md at the start of a session. If its summary is missing something you thought was obvious, it wasn't in the file clearly enough.
> Before you start, summarize the constraints from AGENTS.md that apply to this task.This single question catches most instruction gaps early, before the agent has made any changes.
Common Mistakes to Avoid
- Writing instructions as aspirations instead of rules. "We try to write tests" produces different behavior than "every new function in
src/services/needs a corresponding test intests/services/." - Letting AGENTS.md drift from reality after a tooling change. If you migrate from Jest to Vitest and forget to update the file, Codex will confidently run the wrong command.
- Putting secrets or credentials in AGENTS.md. It's a plain text file that gets read into every session's context, treat it like any other file that might end up in a log or a shared screen.
- One giant root file in a monorepo instead of nested files per package. It gets stale faster and forces the agent to read irrelevant context for every task.
- Forgetting that sandbox and approval settings can silently override what your instructions ask for. If Codex isn't doing what AGENTS.md says, check config.toml before you assume the instructions were ignored.
FAQ
What's the difference between AGENTS.md and config.toml? AGENTS.md holds project-specific and behavioral instructions written in prose: setup steps, test commands, style rules, things not to touch. config.toml holds session-level settings: which model to use, the approval policy, sandbox mode, and profiles. AGENTS.md tells Codex what to do, config.toml controls how much it's allowed to do on its own.
Does Codex read AGENTS.md automatically, or do I have to reference it? It's read automatically. Codex walks the directory tree from your working directory, picking up every AGENTS.md it finds along the way, plus the global one at ~/.codex/AGENTS.md, without you needing to mention the file in your prompt.
Can I have different instructions for different folders in the same repo? Yes. Place an AGENTS.md inside any subdirectory and Codex applies it in addition to the parent-level files whenever a task touches that folder. This is the recommended pattern for monorepos with multiple apps or packages that have different build and test commands.
How long should AGENTS.md be? Long enough to cover setup, testing, and hard boundaries, short enough that every line is something you'd actually want the agent to follow. A few hundred words per file is typical. If a root AGENTS.md is growing past that, it's usually a sign you need nested files per subproject instead of one longer file.
Will Codex ignore instructions if they conflict with the sandbox settings? It won't ignore them so much as be unable to act on them. If AGENTS.md assumes write access or network access that the current sandbox_mode denies, Codex will typically explain what it would do and ask, or stop, rather than silently skip the instruction. Align sandbox_mode and approval_policy with the level of autonomy your instructions assume.
Can I use AGENTS.md for commit message or PR description formatting? Yes, that's one of the most common uses. Put your Conventional Commits format, PR title conventions, or changelog format directly in the root AGENTS.md, and Codex will follow that format when it generates commits or PR descriptions instead of falling back to a generic style.
Do custom prompt files in `~/.codex/prompts/` need any special syntax? No, they're plain Markdown, written the same way you'd write instructions in AGENTS.md. The filename becomes the slash command name, so review.md becomes /review. There's no frontmatter or metadata required, just a clear instruction in the body of the file.
AI CodingShip full-stack AI apps at conversation speed — specs, agents, deploys, all from the terminal.
CodexLearn to drive OpenAI's coding agent: real tasks, safe sandboxing, and terminal-to-cloud workflows that ship.