Skip to content

Optimize AGENTS.md and skills for Codex

Optimizing AGENTS.md and skills for Codex means keeping the always-loaded instruction chain short and layered, moving multi-step procedures into skills that load only when a task needs them, and checking what Codex actually loaded with codex debug prompt-input. Codex joins project files root to leaf under a 32 KiB budget, so the deepest files are cut first.

This page is for the developer or tech lead who owns a repository’s Codex setup. The symptom is familiar: you added a precise rule to services/payments/AGENTS.md last week, and Codex still throws raw errors in that service while following every vague rule at the root. Before you blame the model, check whether that file reached the prompt at all.

If you are writing your first AGENTS.md, start with AGENTS.md setup and come back here once the files exist.

What you get from a tuned AGENTS.md and skills setup

Section titled “What you get from a tuned AGENTS.md and skills setup”
  • A way to see the exact instructions Codex received, without asking the model to remember them.
  • A budget script you can run locally and in CI that fails before a file is silently truncated.
  • A rule for deciding whether guidance belongs in AGENTS.md, a skill, config, or a test gate.
  • A skill layout Codex discovers, with its own context budget under control.
  • Four copy-paste prompts: cut a draft, find truncation, promote a procedure to a skill, and find contradictions.

How does Codex decide which AGENTS.md files to load?

Section titled “How does Codex decide which AGENTS.md files to load?”

The loader in codex-rs/core/src/agents_md.rs (checked against Codex CLI 0.157.1 on 2026-09-26) builds the chain in this order:

  1. Global file. Codex reads ~/.codex/AGENTS.override.md if it exists, otherwise ~/.codex/AGENTS.md. It arrives as user instructions and does not count against the project budget.
  2. Project root. Codex walks up from the startup directory until it finds a project_root_markers entry (default: .git). With no marker, only the startup directory is searched. An empty list (project_root_markers = []) disables the walk.
  3. One file per directory. From the root down to the startup directory, Codex takes the first name that exists as a file: AGENTS.override.md, then AGENTS.md, then each project_doc_fallback_filenames entry.
  4. Concatenation. Files join root to leaf, so the most specific file lands last in the prompt.
  5. Budget. The project files share project_doc_max_bytes, which defaults to 32 KiB (32,768 bytes).
  6. Trust. Since Codex 0.150.0, an untrusted project supplies no project-level AGENTS.md at all in a session. Only the global file loads.

Step 3 has a sharp edge. An empty AGENTS.override.md still wins its directory, contributes nothing, and hides the AGENTS.md beside it. You can reproduce this in a scratch repository in under a minute.

See exactly what Codex loaded with codex debug prompt-input

Section titled “See exactly what Codex loaded with codex debug prompt-input”

Asking the agent “which instruction files did you load?” gets you a summary the model writes from memory. codex debug prompt-input renders the model-visible prompt as JSON instead, so the answer is deterministic. Run it from the directory where you normally start Codex:

Terminal window
# terminal, from your usual startup directory
codex debug prompt-input "ping" > /tmp/prompt.json
grep -o 'AGENTS.md instructions for [^"]*' /tmp/prompt.json

The match shows the whole <INSTRUCTIONS> block Codex will send, with every loaded file in order. To see the budget cut without editing config, lower it for one run:

Terminal window
codex debug prompt-input -c project_doc_max_bytes=4096 "ping" | grep -o 'AGENTS.md instructions for [^"]*'

In a scratch repository with an 18-byte root file and a 51-byte services/pay/AGENTS.md, -c project_doc_max_bytes=40 ended the block at - Throw only Pay: the module file’s heading survived and its only rule was cut mid-word (Codex CLI 0.157.1, 2026-09-26). That half-rule is what a real truncation looks like.

codex debug prompt-input depends on local trust and config, so it is a diagnostic, not a CI gate. For the gate, compute the same chain from the file system. Save this as scripts/agents-md-budget.sh:

#!/usr/bin/env bash
# Usage: scripts/agents-md-budget.sh [START_DIR]
# Prints the AGENTS.md chain Codex loads for START_DIR and fails if it exceeds the budget.
set -euo pipefail
budget="${AGENTS_MD_BUDGET:-32768}" # keep in step with project_doc_max_bytes
start="$(cd "${1:-.}" && pwd -P)" # physical path: git prints the resolved root
root="$(git -C "$start" rev-parse --show-toplevel)"
chain=()
dir="$start"
while :; do
for name in AGENTS.override.md AGENTS.md; do # add your fallback names here
if [ -f "$dir/$name" ]; then chain=("$dir/$name" ${chain[@]+"${chain[@]}"}); break; fi
done
[ "$dir" = "$root" ] || [ "$dir" = / ] && break
dir="$(dirname "$dir")"
done
total=0
for file in ${chain[@]+"${chain[@]}"}; do
size=$(wc -c < "$file")
total=$((total + size))
printf '%7d bytes %7d total %s\n' "$size" "$total" "${file#"$root"/}"
[ "$size" -eq 0 ] && echo " warning: empty file shadows the AGENTS.md beside it" >&2
done
if [ "$total" -gt "$budget" ]; then
echo "AGENTS.md chain for $start is $total bytes, over the $budget-byte budget" >&2
exit 1
fi

Then check every directory that holds an instruction file, because the deepest directories carry the longest chains:

Terminal window
# terminal or CI step, from the repository root
git ls-files --cached --others --exclude-standard -- \
'AGENTS.md' '*/AGENTS.md' 'AGENTS.override.md' '*/AGENTS.override.md' \
| xargs -n1 dirname | sort -u \
| xargs -n1 scripts/agents-md-budget.sh

The --others --exclude-standard flags include new files you have not committed yet, so the check gives the same answer locally as in CI. The script ignores the global file on purpose, matching the loader. A green run proves every chain fits. It does not prove the rules are good, which is the next section’s job.

Each layer answers one question. Anything that fails that question belongs somewhere else.

LayerFileHoldsSize target
Personal~/.codex/AGENTS.mdHow you like to work in every repositoryUnder 20 lines
RepositoryAGENTS.md at the rootCommands, test framework, conventions that differ from defaultsUnder 50 lines
Moduleservices/payments/AGENTS.mdRules that apply only inside this directoryUnder 30 lines

A module file earns its place when it states something the root cannot:

services/payments/AGENTS.md
- Throw only through `PaymentError` from `src/errors.ts`; the API layer maps it to HTTP codes.
- Every public endpoint needs the `rateLimit()` middleware from `src/middleware/rate-limit.ts`.
- Run `pnpm --filter payments test` before you finish; the root test command skips this package.

Three kinds of lines waste the budget in every layer:

  • Things the model already does. “Write clean code” and “use meaningful names” change nothing.
  • Things the code already says. A directory map or architecture overview goes stale and costs bytes on every session.
  • Procedures. A 15-step release checklist loads on every turn, even when nobody is releasing. Move it into a skill.

For the evidence on cutting instead of adding, and a full ablation method, see Pruning CLAUDE.md and AGENTS.md.

When should a rule become a skill, config or a test instead?

Section titled “When should a rule become a skill, config or a test instead?”

AGENTS.md is advice the model reads. Some guidance needs a stronger home.

The guidance is…Put it inWhy
A short convention that applies to most tasksAGENTS.mdLoaded every session, cheap if short
A multi-step procedure for some tasks (release, migration, PR prep)A skillOnly its name and description load until it is used
A setting (model, sandbox, MCP servers)config.tomlConfig is applied, not interpreted
A command the agent must never run unsandboxedCodex rules (.rules)Enforced outside the model
A rule that must always hold (no raw errors, no console.log)A lint rule or test, plus one line in AGENTS.mdThe build fails when the agent forgets

The last row is how quality stays provable. AGENTS.md makes the right output more likely. A lint rule or test makes the wrong output fail the build, so you verify the rule by reading a red or green check instead of every diff.

A skill is a directory with a SKILL.md file. Codex lists each skill’s name and description in a catalog, and reads the full file only when you invoke the skill or your prompt matches its description.

.agents/skills/pr-ready/
SKILL.md # required: frontmatter + instructions
scripts/ # optional: code the skill runs
references/ # optional: docs the skill reads on demand
agents/openai.yaml # optional: Codex UI metadata and dependencies
---
name: pr-ready
description: Prepare the current branch for a pull request. Use when the user asks to get changes
PR-ready, open a PR, or check a branch before review. Not for reviewing someone else's PR.
---
1. Run `pnpm lint --fix`, then `pnpm lint`. Stop and report if errors remain.
2. Run `pnpm test`. Fix failures caused by this branch; report pre-existing ones separately.
3. Run `pnpm typecheck`.
4. Write a PR description: what changed and why, how it was tested, breaking changes.
5. End with a table of each check and its pass or fail result.

The description does the routing. Say when to use the skill and when not to, or implicit matching fires on the wrong prompts.

ScopeLocationNotes
Repository.agents/skills/<name>/SKILL.mdCommitted and shared. Scanned from the working directory up to the repository root
Personal~/.agents/skills/<name>/SKILL.mdRead by Codex 0.157.1 (checked 2026-09-26)
Installer target$CODEX_HOME/skills (default ~/.codex/skills)Where the bundled $skill-installer writes
BundledShips with Codeximagegen, openai-docs, plugin-creator, review-agent, skill-creator and skill-installer in 0.157.1; review-agent is bundled but not listed in the default catalog

Invoke a skill explicitly with $pr-ready in the prompt, or browse them with /skills. To scaffold a new one, type $skill-creator and describe the task.

OpenAI’s catalog is the openai/skills repository. Inside Codex, the bundled installer reads its curated list:

$skill-installer install gh-fix-ci

From a terminal, the cross-agent skills CLI (1.7.0 on 2026-09-26) installs into the project’s .agents/skills/:

Terminal window
npx skills add openai/skills --skill gh-fix-ci -a codex

Install per project when you can. With -g, the CLI writes Codex skills to ~/.codex/skills/, not ~/.agents/skills/, so confirm with /skills that Codex sees them.

Skills are cheaper than AGENTS.md, not free. The catalog of names and descriptions has its own budget, skills.max_context_tokens, which defaults to 2% of the model’s context window and is capped at 10,000 tokens when you set it. Too many installed skills crowd each other out of that catalog: with -c skills.max_context_tokens=50, codex debug prompt-input listed no skills at all. Turn off the ones you do not use:

~/.codex/config.toml
[[skills.config]]
name = "imagegen"
enabled = false
[[skills.config]]
path = "/home/you/.codex/skills/old-release/SKILL.md"
enabled = false

For shared skill standards across a team, see skills optimization and team sharing.

Use AGENTS.override.md for a temporary phase

Section titled “Use AGENTS.override.md for a temporary phase”

An AGENTS.override.md replaces the AGENTS.md in the same directory while it exists. That makes it a clean switch for a migration or a freeze:

services/api/AGENTS.override.md
# TEMPORARY: delete when the v3 router migration is merged (owner: @api-team)
- Add new endpoints only under src/routes/v3/. Do not edit v1 or v2 routes.
- Use AuthContext from src/lib/auth-v3.ts in all new middleware.
- Run `pnpm test:contract` before finishing; v2 clients must keep passing.

The override hides the whole permanent file, so copy across any permanent rule you still need. Put an owner and an exit condition in the first lines, and let the budget script’s file list remind you it is still there.

/status in the Codex TUI shows the current session configuration and token usage. /mcp lists the connected MCP tools. Each MCP server adds tool schemas to every turn, so switch off the ones this repository does not need, or narrow them to the tools you use:

# ~/.codex/config.toml or .codex/config.toml
[mcp_servers.jira]
enabled = false
[mcp_servers.github]
enabled_tools = ["get_pull_request", "list_pull_request_files"]

Raise project_doc_max_bytes only after you have cut and split. A larger budget keeps the file whole, but every session still pays for it:

project_doc_max_bytes = 65536 # default 32768

If you raise it, set AGENTS_MD_BUDGET in CI to the same value. For the wider picture of compaction and context across the App, CLI and cloud, see context management across Codex surfaces.

Prove the instructions work without reading every session

Section titled “Prove the instructions work without reading every session”

A clean setup is one you can check from outputs, not transcripts:

  1. Loaded. scripts/agents-md-budget.sh passes in CI for every directory with an instruction file.

  2. Received. codex debug prompt-input from each service directory shows that service’s last rule inside <INSTRUCTIONS>.

  3. Enforced. Every rule that must always hold has a lint rule or test. The CI result proves compliance, and a reviewer does not have to spot it in the diff.

  4. Owned. AGENTS.md, AGENTS.override.md and .agents/skills/ sit under a CODEOWNERS entry for the tech lead who owns the setup. Changes to them get reviewed like code, because they change every future session.

  • A module rule is ignored while root rules are followed. The chain is over budget. Run the budget script from that directory, then cut or split the root file. Raise project_doc_max_bytes only as a last resort.
  • A whole directory’s rules vanished. An empty or forgotten AGENTS.override.md is shadowing the AGENTS.md beside it. Run find . -name AGENTS.override.md and delete what no longer has an owner.
  • No project instructions load at all. The project is untrusted (0.150.0 and later), or the startup directory is outside the repository root. codex debug prompt-input does not apply the trust check (it still rendered project files with trust_level = "untrusted" in 0.157.1), so a clean render does not rule trust out. Look at the [projects."<path>"] entry in ~/.codex/config.toml, and trust the project when Codex asks.
  • Rules are followed early and forgotten late in a long session. Compaction summarised the conversation. Restate the one constraint that matters in your prompt, or start a new session with /new.
  • A skill never fires implicitly. Its description does not match how people ask. Add the phrases your team uses, invoke it with $name until it does, and check that /skills lists it.
  • A skill fires on the wrong tasks. Its description is too broad. Add a “Not for…” clause, and disable overlapping skills with [[skills.config]].
  • Cloud tasks ignore your local rules. Cloud environments read the AGENTS.md committed to the repository. Commit what matters; keep only personal preferences in ~/.codex/AGENTS.md.

Where to go next with AGENTS.md and skills

Section titled “Where to go next with AGENTS.md and skills”