Writing Effective Prompts
Codex executes instructions — prompt quality directly determines output quality. A good prompt has three components:
- Verb + target: what action to take, on which file or function
- Scope: which files to touch, which to leave alone
- Done criteria: what requirements the output must satisfy
| ❌ Vague prompt | ✅ Precise prompt |
|---|---|
| Optimize this code | Refactor the parseDate function in src/utils.js — eliminate duplicate logic and add TypeScript type annotations to all parameters |
| Fix the bug | Fix the validateToken function in src/api/auth.ts: when a token is expired, throw TokenExpiredError instead of returning null |
| Write tests | Write Jest unit tests for the createUser function in src/services/userService.ts, covering: duplicate email, password too short, and successful creation |
| Add comments | Add JSDoc to every function in all .ts files under src/db/migrations/, documenting parameters, return values, and side effects |
Rule of thumb: if you would need to explain "which specific function," the prompt isn't precise enough. A precise prompt means Codex doesn't need to guess.
Prompt patterns that work
# Batch operation pattern: use "all" but constrain the scope
Add try-catch error handling to all async functions in src/controllers/.
Pass errors to next(err). Do not modify anything in src/middleware/.
# Analyze-first pattern: reduces unintended edits
First list all functions in src/models/ that use raw SQL queries.
Wait for my confirmation before replacing them with Sequelize ORM calls.
# Constraint + output pattern: be explicit about off-limits
Refactor the OAuth callback in src/auth/passport.ts to improve readability.
Constraints: do not change function signatures, do not alter error handling, keep all function names identical.
# Progressive pattern: break big tasks into steps
Step 1 only: analyze src/legacy/ and list every function over 50 lines
with no type annotations. Do not modify any files.
Model Selection Strategy
Different tasks suit different models. Using the most expensive model for everything wastes money; using too cheap a model reduces quality.
| Task type | Recommended model | Reason |
|---|---|---|
| Quick fixes, comments, simple tests | gpt-4.1-mini |
Fastest, cheapest, good enough |
| Feature development, standard refactors | gpt-4.1 or default |
Best cost-quality balance |
| Complex architecture reasoning, large codebase analysis | o4-mini or gpt-5.x |
Stronger reasoning capabilities |
| CI/CD batch automation | o4-mini |
Optimal cost-to-quality for unattended runs |
| Exploratory analysis (no time pressure) | gpt-5.x or o3 |
Deep reasoning, accuracy over speed |
# Interactive mode: slash command (this session only)
/model gpt-4.1-mini
# CLI flag (single run)
$ codex --model o4-mini "refactor the auth module"
# config.toml (permanent default)
# ~/.codex/config.toml
model = "gpt-4.1"
Advanced AGENTS.md Patterns
AGENTS.md is Codex's project memory — but most people either write too little or too much. Here are a few patterns that make a measurable difference:
Pattern 1: Forbidden list first
The most impactful content in AGENTS.md is not the project introduction — it's what Codex must never do. Codex actively avoids triggering these rules:
## Off-limits (Codex must follow these)
- Never modify the generated/ directory — files there are auto-generated
- Never directly edit prisma/schema.prisma — run migrations with `pnpm db:migrate`
- Never put business logic in route files — it belongs in services/
- Never modify .env.example or .env — secrets live there
- The Stripe webhook handler in webhooks.ts has signature verification — tell me before touching it
Pattern 2: Command reference table
Put your most-used dev commands directly in AGENTS.md so Codex automatically uses the correct commands when it needs to run tests or start services:
## Common Commands
```bash
pnpm dev # Start dev server with hot reload, port 3000
pnpm test # Vitest unit tests
pnpm test:watch # Test watch mode
pnpm build # Build production bundle
pnpm db:migrate # Run Prisma migrations
pnpm lint # ESLint check (must pass before commit)
```
For more AGENTS.md techniques see: AGENTS.md Complete Guide.
Context Window Management
Running out of context mid-task is one of the most common advanced problems. These strategies help you use context efficiently:
Strategy 1: Task decomposition (most effective)
Break one large task into multiple focused smaller ones — one thing per session:
# ❌ Too much at once
Refactor the entire src/ directory, add type annotations, optimize performance, update docs
# ✅ Break it down
# Round 1: types only
Add TypeScript type annotations to all functions in src/services/. Make no other changes.
# After confirming Round 1 is good:
# Round 2: performance only
In the files we just typed in src/services/, identify and fix performance bottlenecks. No other changes.
Strategy 2: Specify file paths explicitly
Include exact file paths in prompts to avoid Codex spending tokens exploring the file tree:
# ❌ Let Codex find the files itself
Find all files that handle user authentication and refactor them
# ✅ Tell it exactly where to look
Refactor the authentication logic in these specific files:
- src/api/routes/auth.ts (route layer)
- src/services/authService.ts (business logic)
- src/middleware/jwtMiddleware.ts (JWT verification)
Strategy 3: Keep AGENTS.md lean
AGENTS.md consumes context. Split infrequently-needed background information into subdirectory AGENTS.md files, keeping the root file concise (under 300 lines).
codex exec Automation Patterns
codex exec is the key to embedding Codex into scripts and CI pipelines. Here are practical patterns:
#!/bin/bash
# Add type annotations to all untyped files
for file in src/services/*.ts; do
echo "Processing $file ..."
codex exec "Add TypeScript type annotations to all untyped functions in $file. No other changes."
done
#!/bin/bash
# Only run if TypeScript files changed
DIFF=$(git diff HEAD~1 --name-only '*.ts')
if [ -z "$DIFF" ]; then
echo "No TypeScript changes — skipping"
exit 0
fi
codex exec "Update JSDoc comments based on the TypeScript changes in git diff HEAD~1"
#!/bin/bash
set -e # exit immediately on any failure
# codex exec returns non-zero on failure; set -e terminates the script
codex exec "Fix all ESLint errors in src/api/. Do not change logic."
# Confirm lint passes
npm run lint
echo "✓ All lint errors fixed"
For complete CI/CD integration (GitHub Actions, GitLab CI) see: CI/CD Integration Guide.
Interactive Mode Tips
Keyboard shortcuts
| Shortcut | Action |
|---|---|
| Ctrl+C | Interrupt current task (Codex stops, already-made edits are kept) |
| Ctrl+D | Exit Codex interactive UI |
| ↑ / ↓ | Browse input history |
| Tab | Autocomplete (file paths, slash commands) |
| Esc | Cancel current input, return to empty state |
Approval mode vs full-auto
The default sandbox is workspace-write — Codex asks before certain operations. When you trust the task, you can relax this temporarily:
# Adjust in interactive mode with slash command
/permissions
# Or set a default in config.toml
# ~/.codex/config.toml
approval_policy = "auto-edit" # auto-approve file edits, still confirm shell commands
Multi-Project and Session Management
Each project has its own AGENTS.md
Each project root has its own AGENTS.md. Codex reads the file from the directory where it starts — switching to a different project directory automatically switches context. No contamination between projects.
Use ~/.codex/AGENTS.md for personal cross-project preferences
# These preferences apply to every project
- State the conclusion before explaining the reasoning
- Ask me before making assumptions about intent — don't guess
- Always include error handling in generated code
## My coding style
- Prefer functional patterns
- async/await over Promise.then
- camelCase variable names
Common Pitfalls and How to Avoid Them
Pitfall 1: Codex modifies files you didn't want changed
Cause: The prompt's scope was ambiguous, or AGENTS.md has no forbidden list.
Fix: Explicitly say "only modify X file" in the prompt. Add a forbidden list to AGENTS.md. If it already happened, use git checkout -- <file> to revert.
Pitfall 2: Codex stops halfway through a task
Cause: Task was too large and hit the context limit, or Codex paused waiting for confirmation.
Fix: Break big tasks into smaller ones. If it's waiting for confirmation, look at the terminal prompt and type y to continue, or adjust the approval policy with /permissions.
Pitfall 3: Output doesn't match your project's style
Cause: Coding conventions aren't in AGENTS.md, or the prompt didn't specify format requirements.
Fix: Write specific rules in AGENTS.md (no any, JSDoc required, naming conventions). You can also specify inline: "follow the project's ESLint config" or "all functions must have return type annotations."
Pitfall 4: Codex understood the problem but went in the wrong direction
Fix: Use the analyze-first pattern. Add "first list the files and functions you plan to change, wait for my confirmation before proceeding" to your prompt. Codex will give you an action plan to review before it makes any changes.
Pitfall 5: codex exec fails in CI without a useful error
Common causes: ① OPENAI_API_KEY not set; ② Node.js version too old (needs 18+); ③ outdated codex version; ④ network can't reach the OpenAI API from the CI server.
Debug: Add codex --version to confirm the version. Verify the key: echo $OPENAI_API_KEY | cut -c1-6 (shows only the first 6 chars). Test API reachability: curl https://api.openai.com/v1/models -H "Authorization: Bearer $OPENAI_API_KEY".
Effective Daily Workflows
Workflow 1: Feature Development
- Use Codex to generate a feature scaffold (run
/initto keep AGENTS.md current) - Review the scaffold, give Codex specific feedback
- Have Codex generate unit tests for the new feature
- Run tests, paste failing cases back to Codex for fixes
- Finally, ask Codex to add JSDoc comments to all new functions
Workflow 2: Bug Fixing
- Paste the error and stack trace, ask Codex to locate the problem ("analyze but don't modify anything yet")
- Once the analysis looks correct, ask Codex to fix it and explain the change
- Ask Codex to write a regression test that reproduces the original bug
Workflow 3: Code Review Assistance
- Run:
codex exec "Review the changes in git diff HEAD~1 from three angles: readability, potential bugs, and edge cases. Give feedback only — do not modify any files." - Review the feedback and decide if changes are needed
- If yes, ask Codex to apply the fixes based on its own review
Want to integrate these workflows into GitHub Actions? See the CI/CD Integration Guide for complete YAML configuration examples.