AGENTS.md is a newer convention that’s quietly becoming mandatory infrastructure for anyone running multi-agent AI workflows. If you’ve been using CLAUDE.md for single-agent projects, AGENTS.md extends that pattern to handle the harder problem: what happens when multiple AI agents are running in the same codebase, possibly simultaneously, with different roles?
This guide covers what AGENTS.md is, how it differs from CLAUDE.md, and how to write one that actually improves your multi-agent workflows rather than adding noise.
What AGENTS.md Is (and Isn’t)
AGENTS.md is an instruction file read by AI coding agents — particularly Codex, OpenAI’s agents system, and increasingly Claude Code — before they touch your codebase. Think of it as the briefing document you’d give a new contractor before they touch production code.
The file serves three purposes:
- Role clarity — tells each agent what it’s responsible for and what it should leave alone
- Workflow coordination — describes how agents should handle shared resources, test suites, and deployments
- Environment facts — build commands, test runners, linting setup, file conventions
Here’s the distinction from CLAUDE.md that matters in practice: CLAUDE.md is primarily a project context file for Claude Code. It describes the project to Claude, including its history, conventions, and rules. AGENTS.md is more explicitly a coordination document — it’s written assuming multiple agents might read it, and it needs to handle role-based scenarios.
In practice, many teams use both. CLAUDE.md handles Claude-specific configuration (hooks, tools, memory settings), while AGENTS.md handles the shared multi-agent coordination layer.
A file at the root of the openai/openai-agents-python repository actually contains nothing but: Read the AGENTS.md file for instructions. — which illustrates how these two conventions layer on each other in real projects.
The Anatomy of a Good AGENTS.md
Let’s look at what needs to go in the file, in order of importance.
1. The Essential Commands Block
Every AGENTS.md should start with a commands block. This is the highest-priority section because it’s what agents need every single time they work in the repo.
## Commands
- **Build**: `npm run build`
- **Test**: `npm test`
- **Lint**: `npm run lint`
- **Format**: `npm run format`
- **Type check**: `npm run typecheck`
- **Start dev server**: `npm run dev`
This seems obvious, but the mistake most teams make is burying this information in a README or omitting it entirely. Agents don’t read READMEs reliably. They read AGENTS.md. Put the commands up front.
For monorepos, be more specific:
## Commands
Run from the repo root unless specified.
- **Build all packages**: `pnpm run build --recursive`
- **Build a single package**: `cd packages/api && pnpm run build`
- **Test all**: `pnpm run test --recursive`
- **Test single package**: `cd packages/api && pnpm test`
- **Lint**: `pnpm run lint` (runs ESLint across all packages)
- **Type check**: `pnpm run typecheck` (uses project references)
Do not run `npm` commands — this repo uses pnpm workspaces.
That last line matters. Agents will reach for npm by default unless you tell them not to.
2. File Conventions and Project Structure
Agents need to understand where things live and why. Without this, they’ll create files in the wrong places and break conventions that aren’t obvious from code inspection alone.
## Project Structure
src/ api/ # Express route handlers — one file per resource services/ # Business logic — no database access here repositories/# All database queries live here models/ # TypeScript types and Zod schemas utils/ # Pure functions only, no side effects tests/ unit/ # Mirror src/ structure integration/ # Tests that hit the actual database e2e/ # Playwright tests
**Critical rules:**
- Services must not import from repositories directly — use dependency injection via the service constructor
- Repository files must not contain business logic
- Never add a `utils.ts` file at the top level — find the right subdirectory
The “critical rules” pattern — explicitly flagging the things agents get wrong — is more useful than comprehensive documentation. Agents are good at filling gaps. They need guardrails, not hand-holding.
3. Testing Requirements
This is where most AGENTS.md files fall short. Vague statements like “write tests for new code” don’t work. Be specific about what coverage is required, which test files to run, and what counts as passing.
## Testing
**Before submitting any change:**
1. Run the full test suite: `pnpm test`
2. Ensure no new lint errors: `pnpm lint`
3. Type check passes: `pnpm typecheck`
**For new features:** Write tests in `tests/unit/` using the same file path structure as `src/`. A new file at `src/services/invoices.ts` needs a test at `tests/unit/services/invoices.test.ts`.
**For bug fixes:** Add a regression test that reproduces the bug before fixing it.
**Integration tests (`tests/integration/`):** These hit a real PostgreSQL instance. They run in CI but are slow to run locally. Run them with `pnpm test:integration` only when you've changed database queries or repository code.
**Do not modify test configuration files** (`jest.config.ts`, `playwright.config.ts`) without explicit approval.
The last line — don’t modify test config — is something you’ll want in almost every AGENTS.md. Agents have a tendency to “fix” test configuration when tests fail, which can cascade into much larger problems.
4. Code Style Beyond the Linter
Your linter catches formatting and syntax. AGENTS.md handles everything else.
## Code Style
**TypeScript:**
- Prefer `interface` over `type` for object shapes
- Use `unknown` instead of `any` — if you need `any`, add a `// eslint-disable-next-line @typescript-eslint/no-explicit-any` comment with a justification
- Async functions must have explicit return type annotations
- Use early returns to reduce nesting depth
**Naming:**
- Files: `kebab-case.ts`
- React components: `PascalCase.tsx`
- Variables and functions: `camelCase`
- Database columns: `snake_case` (handled by the ORM mapper, don't convert manually)
- Constants: `SCREAMING_SNAKE_CASE` only for environment variables
**Imports:**
- Sort: built-ins → external packages → internal modules → relative imports
- Use path aliases (`@/services/...`) for src/ imports — no `../../../` chains
**Error handling:**
- Never swallow errors silently
- Use typed errors — see `src/errors/` for the error class hierarchy
- Log errors with context before re-throwing
Notice that style rules are written as positive statements (“prefer X”) with clear rationale when the reason isn’t obvious. This is different from linting rules, which agents interpret as absolute constraints. Style rules need to feel like guidance from a senior developer, not a config file.
5. What Agents Should Never Do
This is the most underrated section. Agents are generally good at doing what you ask; they’re less reliable at knowing what to avoid.
## Restrictions
**Never:**
- Commit directly to `main` or `release/*` branches
- Modify files in `migrations/` — create new migration files only
- Change the database schema without a corresponding migration
- Delete files without asking first
- Add new dependencies to `package.json` without checking for existing alternatives
- Make network requests in unit tests — use the mocks in `tests/mocks/`
- Hard-code credentials, API keys, or environment-specific values
**Require approval before:**
- Adding new database indexes
- Changing existing API response shapes
- Modifying authentication or authorization logic
- Updating dependencies with breaking changes
The two-tier structure (“never” vs. “require approval”) maps to the two types of mistakes you want to prevent: catastrophic ones and reversible ones that need a human in the loop.
Writing AGENTS.md for Multi-Agent Coordination
Single-agent AGENTS.md files look like sophisticated CLAUDE.md files. The interesting challenges emerge when multiple agents run concurrently.
Role-Based Sections
The most effective pattern for multi-agent coordination is to organize AGENTS.md with explicit role sections:
## Roles
### Orchestrator Agent
Responsibilities:
- Breaking down user requests into subtasks
- Delegating to specialist agents
- Aggregating results and handling conflicts
- Final decision-making on ambiguous cases
What the orchestrator should NOT do:
- Write code directly (delegate to coding agents)
- Run test suites (delegate to testing agents)
- Make deployment decisions unilaterally
### Code Agent
Responsibilities:
- Implementing features based on specs from the orchestrator
- Fixing bugs in existing code
- Writing unit tests for new code
- Refactoring code to meet style requirements
Boundaries:
- Does not modify CI/CD configuration
- Does not update documentation (delegate back to orchestrator)
- Does not make architectural decisions — escalate to orchestrator
### Review Agent
Responsibilities:
- Code review against project standards
- Security scanning
- Performance analysis
- Generating review reports
Boundaries:
- Does not modify code directly — reports findings only
- Does not block the pipeline — flags issues for human review
Role sections work because they make it unambiguous what each agent should do when it encounters something outside its scope. Without explicit roles, agents will try to handle everything, which creates coordination conflicts.
Handling Shared State
The hardest problem in multi-agent coordination is shared state. Multiple agents writing to the same files simultaneously will corrupt them. AGENTS.md can’t solve this problem technically, but it can establish conventions that minimize the risk:
## Shared State Conventions
**File locking:** If you need to modify a shared config file (`config/app.ts`, `package.json`), check if another agent is currently modifying it by looking for a `.lock` file in the same directory. Create the lock file before editing, remove it after.
**Git discipline:** Always pull before making changes. Commit frequently in small units. Never hold large batches of changes uncommitted for more than a few minutes.
**The state files:** The following files are high-contention — treat them as if they require a mutex:
- `src/routes/index.ts` (all agents add routes here)
- `src/models/index.ts` (all agents add model exports here)
- `package.json`
When adding to these files, make the minimal change needed and commit immediately.
This isn’t a perfect solution — you can’t solve distributed locking with a markdown file — but it reduces the problem significantly by making agents aware of the contention points.
Escalation Protocols
Multi-agent systems need a clear protocol for what happens when an agent encounters something it can’t handle:
## Escalation
When to escalate to the orchestrator (or stop and ask the user):
1. The task requires modifying more than 10 files
2. You encounter a test failure you can't explain
3. The specification is ambiguous and affects the public API
4. You need to add a new dependency
5. Something in the codebase contradicts these instructions
How to escalate:
- Stop what you're doing (don't commit partial work)
- Write a brief summary of what you were doing, what you found, and why you're escalating
- Include the specific files and line numbers relevant to the issue
- Wait for clarification before proceeding
The “how to escalate” section is often missing. Without it, agents either escalate in unhelpful ways (no context) or don’t escalate at all (just guess and proceed).
AGENTS.md vs. CLAUDE.md: Practical Differences
Here’s how to think about what goes where when you’re using both:
| Concern | CLAUDE.md | AGENTS.md |
|---|---|---|
| Claude-specific tools (WebSearch, Bash) | Yes | No |
| Hook configuration | Yes | No |
| Build commands | Yes | Yes |
| Code style rules | Yes | Yes |
| Multi-agent roles | No | Yes |
| Coordination protocols | No | Yes |
| Security boundaries | Both | Both |
| Project history/context | Yes | No |
| File naming conventions | Both | Both |
CLAUDE.md can reference AGENTS.md:
# CLAUDE.md
This project uses a multi-agent setup. Read AGENTS.md for coordination rules.
For Claude-specific configuration:
- Hooks: see `.claude/settings.json`
- Custom commands: see `.claude/commands/`
And AGENTS.md can reference CLAUDE.md:
# AGENTS.md
If you are Claude Code, also read CLAUDE.md for Claude-specific configuration.
General agent rules follow.
This layered approach lets you maintain agent-specific and tool-agnostic documentation separately, without duplicating content.
Real-World AGENTS.md Patterns
Here are three patterns that show up repeatedly in production multi-agent setups.
The Minimal AGENTS.md (Single-Developer Projects)
# AGENTS.md
## Build & Test
- Install: `npm install`
- Build: `npm run build`
- Test: `npm test` (runs Jest)
- Lint: `npm run lint` (ESLint + Prettier)
- Type check: `npm run tsc`
Run all of the above before submitting any change.
## Rules
- TypeScript strict mode is enabled. No `any`.
- New API endpoints need tests in `src/__tests__/api/`.
- Environment variables go in `.env.example` (never commit actual values).
- Don't modify `drizzle.config.ts` or files in `migrations/`.
Small, focused, and genuinely useful. The temptation is to write a comprehensive document. Resist it — agents don’t need comprehensive, they need precise.
The Team AGENTS.md (Medium-Sized Codebase)
# AGENTS.md
## Quick Reference
| Task | Command |
|---|---|
| Install | `pnpm install` |
| Build | `pnpm build` |
| Test | `pnpm test` |
| Lint | `pnpm lint` |
| Format | `pnpm format` |
| DB migrate | `pnpm db:migrate` |
## Architecture Overview
Three-layer architecture:
1. **Routes** (`src/routes/`) — request validation and response formatting only
2. **Services** (`src/services/`) — business logic, no DB access
3. **Repositories** (`src/repositories/`) — database queries only
Services import repositories via dependency injection. Routes never import repositories directly.
## Testing
- Unit tests: `src/__tests__/unit/` — mock all external dependencies
- Integration tests: `src/__tests__/integration/` — requires running `docker-compose up -d` first
- E2E tests: `src/__tests__/e2e/` — requires full stack, run in CI only
Every new service method needs a unit test. Coverage threshold is 80%.
## Critical Rules
1. Never modify `.env.production`
2. Migration files are append-only — never edit existing ones
3. All API responses must use the `ApiResponse<T>` wrapper type
4. Database columns use snake_case, TypeScript properties use camelCase — the ORM handles mapping
5. Add new environment variables to `src/config/env.ts` validation schema before using them
## Code Review Checklist
If you are a review agent, check:
- [ ] No raw SQL strings (use query builder)
- [ ] Error messages don't leak internal details
- [ ] New endpoints have rate limiting middleware
- [ ] Sensitive fields are excluded from response types
The Multi-Agent Orchestration AGENTS.md
# AGENTS.md — Multi-Agent Coordination
## Agent Roles
This project uses three specialized agents:
**Planner**: Receives user requests, creates implementation plans, delegates to Coder and Reviewer.
**Coder**: Implements plans created by Planner. Does not make architectural decisions.
**Reviewer**: Reviews Coder's output against this document and the project's style guide.
## Handoff Protocol
Planner → Coder: Create a task file at `tasks/active/{timestamp}-{task-name}.md` with:
- The goal
- Files to modify (list explicitly)
- Files not to touch
- Acceptance criteria (testable)
Coder → Reviewer: When done, add `status: ready-for-review` to the task file.
Reviewer → Planner: Add `status: approved` or `status: needs-revision` with specific feedback.
## Conflict Resolution
If two agents need to modify the same file simultaneously:
1. The later agent wins for new additions (append-only)
2. Modifications to existing lines require Planner to resolve
3. Never force-push or rebase shared branches
## Environment
- Node.js 22+
- pnpm 9+
- PostgreSQL 16 (via Docker for local dev)
- Commands: `pnpm build`, `pnpm test`, `pnpm lint`
## What Never Changes
- `src/auth/` — authentication logic is locked. Any changes require human review.
- `migrations/` — add new files, never modify existing ones
- `.env.production` — never read by agents, never written by agents
Common Mistakes
Mistake 1: Writing for humans, not agents
AGENTS.md is not documentation. Don’t write it like a README. Agents don’t need context about why the project exists or the team’s philosophy. They need precise instructions. Every sentence should be actionable.
Mistake 2: Using vague directives
“Follow best practices” means nothing to an agent. “Use the ApiResponse<T> wrapper type for all API responses — see src/types/api.ts” means something. Be specific. Reference actual files and types.
Mistake 3: Documenting what the code already shows
If agents can infer something from reading the code, don’t document it. AGENTS.md should capture things that aren’t obvious from code inspection: conventions that look arbitrary, historical decisions, things that break if done differently.
Mistake 4: Never updating it
AGENTS.md starts decaying the day after you write it. When you add a new tool, change a build command, or establish a new convention, update the file. Stale AGENTS.md files actively hurt — agents follow outdated instructions confidently.
Mistake 5: Making it too long
Every line in AGENTS.md competes for the agent’s attention. A 5,000-word AGENTS.md is less effective than a 500-word one with better selection. If you find yourself writing comprehensive section on topics the agent will encounter once, cut it. Put that information where it belongs — in code comments, in tests, in local AGENTS.md files for specific subdirectories.
Hierarchical AGENTS.md Files
Like CLAUDE.md, AGENTS.md supports a hierarchy. The file at the repo root applies everywhere. Files in subdirectories apply only to that subtree and extend (not replace) the root file.
.
├── AGENTS.md # Global rules
├── packages/
│ ├── api/
│ │ └── AGENTS.md # API-specific rules, extends root
│ └── web/
│ └── AGENTS.md # Frontend-specific rules, extends root
└── infrastructure/
└── AGENTS.md # IaC rules — different conventions
The infrastructure/AGENTS.md might look like:
# infrastructure/AGENTS.md
This directory contains Terraform configuration.
## Rules Specific to Infrastructure
- All changes require a `terraform plan` output before applying
- Never run `terraform apply` directly — use the CI pipeline
- State files are in S3 — never commit `.terraform/` or `*.tfstate`
- Module versions are pinned — don't update them without explicit instruction
## Commands
- Validate: `terraform validate`
- Format: `terraform fmt -recursive`
- Plan: `terraform plan -var-file=vars/staging.tfvars`
(Global rules from root AGENTS.md also apply.)
The parenthetical at the end is important — explicitly noting that root rules still apply prevents agents from treating subdirectory files as complete replacements.
Verifying Your AGENTS.md Works
The best way to test AGENTS.md is to ask an agent to read it and summarize what it would and wouldn’t do. If the agent’s summary doesn’t match your intent, rewrite the ambiguous section.
More specifically, run these checks:
-
The “new engineer” test: Does the AGENTS.md contain everything a competent developer would need to start contributing without asking questions? If not, what’s missing?
-
The “worst case” test: What’s the worst thing an agent could do while following your AGENTS.md to the letter? If the answer is catastrophic, you’re missing a restriction.
-
The “staleness” test: Check every command and file path in your AGENTS.md against the actual repo. If even one is wrong, agents will lose confidence in the whole file.
-
The “length” test: Can you cut 20% of the content without losing meaningful information? If yes, cut it.
A well-written AGENTS.md is a living document. It starts minimal, grows as you discover what agents get wrong, and shrinks as the codebase becomes more self-explanatory. The goal isn’t completeness — it’s precision.
Getting Started
If you’re starting from scratch, use this template:
# AGENTS.md
## Build & Test
- Install: `[install command]`
- Build: `[build command]`
- Test: `[test command]`
- Lint: `[lint command]`
## Project Structure
[2-3 sentences describing the main directories and what goes where]
## Code Rules
[3-5 specific, actionable rules — things that aren't obvious from the code]
## Restrictions
Never:
- [Thing 1]
- [Thing 2]
Ask before:
- [Thing 3]
Start with that. Add sections only when you discover an agent doing something wrong. That’s how you end up with an AGENTS.md that actually helps rather than one that sits in the repo being ignored.