TL;DR
An effective AGENTS.md is a small, reviewed contract between a repository and the coding-agent hosts that actually load it. Write exact commands, source-of-truth paths, change boundaries, and evidence required for completion. Keep task-specific requests, secrets, permissions, and long manuals elsewhere. Then verify both delivery (which instructions the host loaded) and effect (whether representative tasks improved without new failures).
There is no universal best template, line count, or precedence rule. The AGENTS.md project defines a plain Markdown convention with no required fields; discovery and merge behavior belong to each host implementation.
Table of Contents
- Start with the file identity
- Define the contract before writing
- Write instructions that change decisions
- Use root and nested files deliberately
- Validate the file statically
- Test discovery and behavior separately
- Keep security outside the prompt
- Maintain the file as code
- Frequently Asked Questions
Key Takeaways
AGENTS.mdis repository context, not an authorization or execution standard.- Exact host behavior matters more than claims about broad ecosystem support.
- Useful instructions connect a condition to an action and verifiable evidence.
- Root files hold shared invariants; nested files should contain only subtree-specific deltas.
- Static linting catches stale paths and risky text, but only task evaluation measures usefulness.
- Context-file research is mixed, so treat every change as an intervention to test.
Start with the File Identity
AGENTS.md is a predictable location for instructions that help a coding agent work in a repository. The format itself is intentionally thin: standard Markdown, arbitrary headings, and no mandatory schema.
That simplicity creates an important boundary. Similar filenames can represent different artifacts:
| Artifact | Typical purpose | Do not assume |
|---|---|---|
AGENTS.md |
Persistent repository guidance | Every host discovers or merges it identically |
AGENTS.override.md |
A Codex-supported replacement at one discovery level | Other hosts implement this filename |
.github/agents/*.agent.md |
GitHub custom agent profile with frontmatter | It is an AGENTS.md repository rule |
CLAUDE.md |
Claude Code project memory/instructions | It follows Codex precedence |
.github/copilot-instructions.md |
Copilot repository-wide instructions | Every Copilot surface supports all instruction types |
| Task prompt | One task's goal, evidence, and acceptance criteria | It belongs in persistent repository context |
The name collision matters. GitHub's article about lessons from more than 2,500 agents.md files discusses custom agent profiles, not the uppercase AGENTS.md convention. Use the GitHub custom-agent documentation for .agent.md, and the repository-instruction documentation for AGENTS.md and Copilot instruction files.
For the broader architecture across hosts, see AI coding context files. This guide stays narrow: design and validate one AGENTS.md contract.
Define the Contract Before Writing
A useful AGENTS.md records information that is stable, non-obvious, frequently needed, and testable. Inventory the repository before writing prose:
- Identify the real package manager, runtime, build files, CI workflows, and test entry points.
- Locate generated code, migration directories, public API contracts, deployment configuration, and sensitive paths.
- Map a changed area to the smallest useful verification command and the broader release gate.
- Find existing authoritative documents instead of copying them.
- Record who owns each rule and what event should trigger review.
Use this placement test:
| Information | Best location |
|---|---|
| Stable build command and repository-specific precondition | AGENTS.md |
| Package-specific command or invariant | Nested instruction file, if the host supports it |
| Current bug, reproduction, and acceptance criteria | Task prompt or issue |
| Long architecture rationale | Owned design document |
| Repeatable multi-step workflow | Skill or automation |
| Enforceable permission or approval | Tool, policy service, sandbox, CI, or branch rule |
| API key, token, customer data | Secret manager; never an instruction file |
This separation follows the same principle as context engineering: select the smallest evidence set that changes the current decision while preserving provenance and trust boundaries.
Write Instructions That Change Decisions
Good instructions answer four questions: where may the agent work, what should it do, how can it verify the result, and when must it stop?
Prefer condition-action-evidence statements:
| Weak instruction | Stronger instruction |
|---|---|
| Follow best practices | Match the adjacent module; do not introduce a new abstraction unless two current call sites need it |
| Run tests | After changing packages/api/**, run pnpm --filter @acme/api test; report any skipped integration test |
| Be careful with generated files | Do not edit src/generated/**; change schema/openapi.yaml, then run pnpm generate |
| Do not break the API | Preserve fields in contracts/public-api.json; run pnpm test:contract after contract changes |
| Ask if unsure | Stop before destructive data changes, production writes, or a public API break |
A root file can remain compact while still being operational:
# Repository Working Agreement
## Scope
- Work in the package named by the task.
- Preserve unrelated worktree changes.
- Do not edit `generated/**`, `vendor/**`, or committed migrations.
## Sources of truth
- Commands: `package.json` and `.github/workflows/ci.yml`.
- API contract: `contracts/openapi.yaml`.
- Architecture decisions: `docs/adr/`.
## Verification by changed area
- `apps/web/**`: `pnpm --filter web test` and `pnpm --filter web lint`.
- `services/api/**`: `pnpm --filter api test` and `pnpm test:contract`.
- `contracts/**`: `pnpm generate`, then review generated diffs.
## Escalation
- Ask before adding a production dependency or changing a public API.
- Never perform production writes or bypass required checks.
## Delivery
- Report changed files, commands run, failures, and unverified risks.
The commands and paths above are examples, not defaults. A copied command that does not exist is worse than an omitted command because it converts uncertainty into confident failure.
What to omit
Remove material that does not improve a concrete repository decision:
- language syntax and generic style advice already enforced by linters;
- copied README, API, architecture, or onboarding manuals;
- volatile release status, sprint notes, current incidents, or temporary branches;
- aspirational persona text such as “act as a world-class engineer”;
- permissions that the agent cannot actually grant or revoke;
- secrets, credential values, internal customer data, or production identifiers;
- unverified commands, paths, version numbers, and fixed performance claims.
Link to owned documentation when the detail is needed. A link preserves one source of truth, although the agent must still verify the target exists and applies to the current revision.
Use Root and Nested Files Deliberately
Nested files help only when a subtree genuinely has different operating rules. Do not duplicate the root file inside every package.
repo/
├── AGENTS.md
├── apps/
│ └── web/
│ └── AGENTS.md
└── services/
└── payments/
└── AGENTS.override.md
For the current Codex behavior documented by OpenAI:
- Codex first selects one non-empty global file:
AGENTS.override.md, otherwiseAGENTS.md. - It walks from the project root to the current working directory.
- At each directory it selects at most one file: override, regular file, then configured fallback names.
- It concatenates selected files root-to-leaf; closer guidance appears later.
- It stops when the combined instruction size reaches
project_doc_max_bytes, whose documented default is 32 KiB. - It rebuilds the chain for each run or TUI session.
These are Codex implementation details, not guarantees of the open format. GitHub Copilot surfaces, Cursor, Claude Code, and other hosts have their own discovery rules and feature flags. Verify the exact host and client before relying on nested scope or precedence.
Use nested files as deltas:
# Payments Delta
- Applies to `services/payments/**`.
- Run `pnpm --filter payments test:integration` after behavior changes.
- Preserve ledger idempotency keys and audit events.
- Do not execute a real payment or rotate credentials.
If the nested file repeats root commands, ownership, and security text, the copies will drift. If it silently contradicts a root invariant, reviewers cannot tell whether the override is intentional. Make every override explicit and add a conflict fixture.
Validate the File Statically
Static checks can catch broken local links, duplicate headings, secret-like assignments, and a host-specific size budget before the file reaches an agent. They cannot prove that the host loaded the file or that the guidance improves task results.
Save this dependency-free checker as scripts/check-agent-instructions.mjs and run it from the repository root:
import { existsSync, readFileSync } from "node:fs";
import { dirname, resolve } from "node:path";
const file = resolve(process.argv[2] ?? "AGENTS.md");
const maxBytes = Number(process.env.AGENT_CONTEXT_MAX_BYTES ?? 32_768);
const text = readFileSync(file, "utf8");
const errors = [];
if (Buffer.byteLength(text, "utf8") > maxBytes) {
errors.push(`instruction file exceeds ${maxBytes} bytes`);
}
const headings = text
.split(/\r?\n/u)
.filter((line) => /^#{1,6}\s/u.test(line))
.map((line) => line.replace(/^#{1,6}\s+/u, "").trim().toLowerCase());
const duplicates = headings.filter(
(heading, index) => headings.indexOf(heading) !== index,
);
if (duplicates.length > 0) {
errors.push(`duplicate headings: ${[...new Set(duplicates)].join(", ")}`);
}
const secretAssignment =
/\b(api[_-]?key|access[_-]?token|password|secret)\s*[:=]\s*[^\s<>{}\[\]]+/iu;
if (secretAssignment.test(text)) {
errors.push("possible literal secret assignment");
}
for (const match of text.matchAll(/\[[^\]]+\]\((?!https?:|#)([^)]+)\)/gu)) {
const target = resolve(dirname(file), match[1].split("#", 1)[0]);
if (!existsSync(target)) {
errors.push(`missing local link: ${match[1]}`);
}
}
if (errors.length > 0) {
console.error(errors.join("\n"));
process.exitCode = 1;
} else {
console.log("AGENTS.md static checks passed");
}
Run it with an explicit host budget:
AGENT_CONTEXT_MAX_BYTES=32768 \
node scripts/check-agent-instructions.mjs AGENTS.md
The environment value above models Codex's documented default at the time of writing. Pin the value in your own compatibility record; do not present it as an AGENTS.md specification limit.
Extend static checks only for repository facts you can verify deterministically, such as:
- referenced scripts exist in
package.json; - linked local documents resolve;
- generated directories have a corresponding generation command;
- protected paths are covered by CODEOWNERS or a branch rule;
- duplicate scope and priority declarations are rejected;
- Unicode controls and unexpected symlinks receive review.
Test Discovery and Behavior Separately
An agent repeating a sentence proves only that some text reached its context. It does not prove the instruction affects a real task correctly.
Test 1: instruction delivery
Build a disposable fixture with unique, harmless sentinels:
fixture/
├── AGENTS.md # REPORT_ROOT_MARKER
├── packages/
│ ├── api/
│ │ └── AGENTS.md # REPORT_API_MARKER
│ └── web/
│ └── AGENTS.md # REPORT_WEB_MARKER
└── src/
From the root, API directory, and web directory, ask the pinned host version to list active instruction sources and markers. Add one deliberate conflict, one oversized tail marker, and one empty file. Record the current working directory, host version, client surface, configuration, loaded sources, merge order, and truncation result.
For Codex, OpenAI documents commands such as:
codex --ask-for-approval never "Summarize the current instructions."
codex --cd packages/api --ask-for-approval never \
"List the instruction sources you loaded."
Use read-only permissions for discovery tests. A summary can expose unexpected instructions, so do not run it against a context that contains secrets.
Test 2: task effect
Evaluate the file on tasks with deterministic or reviewer-approved expected outcomes:
| Case | Expected evidence |
|---|---|
| Normal bug fix | Gold tests pass; diff stays in the intended package |
| Generated-file trap | Agent edits the source and regenerates output |
| Wrong-command trap | Agent selects the repository-specific command |
| Nested conflict | Host follows the behavior observed in the fixture |
| Injection negative control | Untrusted comment cannot authorize a tool action |
| Forbidden operation | Trusted policy blocks the action regardless of model text |
| Stale instruction | Agent reports the mismatch instead of hiding the failure |
Run paired trials with the same task, checkout, host version, model, tool permissions, budget, and evaluator: one condition with the candidate file and one without it. Measure task correctness, constraint violations, unrelated diff, command failures, human corrections, latency, and token use separately.
Two recent studies illustrate why this matters. A 10-repository, 124-pull-request study reported lower median runtime and output-token consumption while task completion remained comparable. A later two-agent ablation across 3 repositories and 288 evaluated runs did not find a measurable correctness improvement. Neither result licenses a universal promise. Your release decision should depend on your tasks and failure costs.
For a broader evaluation design, use the agent harness evaluation guide.
Keep Security Outside the Prompt
AGENTS.md can describe expected behavior, but it cannot enforce it. Repository content, issues, comments, generated artifacts, and retrieved pages can contain indirect prompt injection.
Use the file to route the agent toward controls:
| Risk | Trusted control |
|---|---|
| Secret disclosure | Secret manager, redaction, log policy |
| Unauthorized file access | Filesystem sandbox and identity-bound authorization |
| Network exfiltration | Egress allowlist, proxy policy, request audit |
| Production mutation | Environment isolation and explicit approval |
| Unsafe merge | Required checks, CODEOWNERS, protected branch |
| Malicious instruction change | Owner review, signed commit or digest, rollback |
| Untrusted generated output | Schema validation, tests, reviewer approval |
OWASP recommends separating instructions from data, minimizing privileges, validating outputs, and adding human approval for high-impact actions. Those controls remain necessary even when the instruction file says “never expose secrets.”
Treat AGENTS.md itself as a supply-chain asset. A small-looking pull request can change every future agent session. Require review from the team that owns developer tooling, inspect invisible Unicode and symlink changes, and prevent an agent from silently rewriting its own governing file.
Maintain the File as Code
Review AGENTS.md in the same change that invalidates one of its facts. A calendar reminder alone is too weak; connect maintenance to concrete triggers:
- a package-manager, runtime, script, or CI workflow changes;
- a path, generated artifact, contract, or ownership boundary moves;
- a host upgrade changes discovery, precedence, or size limits;
- an agent repeatedly chooses the wrong command or edits the wrong source;
- a rule has not affected any evaluated task and consumes context;
- a security incident reveals a missing trusted control.
Every rule should have an owner and a removal condition. Prefer deleting stale guidance over adding exceptions around it. Keep a known-good revision so a harmful instruction change can be rolled back independently of unrelated source changes.
A practical release sequence is:
- Inspect current host behavior and repository evidence.
- Make one coherent instruction change.
- Run static checks and the discovery fixture.
- Run paired representative tasks and security negative controls.
- Review the instruction diff as carefully as executable configuration.
- Roll out to a limited team or repository set.
- Compare outcomes and revert when failures or costs increase.
Frequently Asked Questions
Does every coding agent automatically read AGENTS.md?
No. The open-format site lists a growing ecosystem, but support, client surfaces, enablement, discovery, precedence, refresh timing, and size limits remain host-specific. Check the official documentation for the exact product version and run a fixture from the working directories your team uses.
Is the nearest AGENTS.md always authoritative?
No universal rule guarantees that. Codex currently merges selected files from the project root toward the current working directory, while other hosts can discover files differently. Even when closer guidance wins a conflict, external policy and explicit authorization must remain authoritative for side effects.
Should an LLM generate the file?
It may draft a candidate from inspected repository evidence, but a human owner should verify every path, command, boundary, and source. Generic generated advice adds context without reducing uncertainty. Never accept a generated file merely because it is well formatted.
Should README content be copied into AGENTS.md?
Usually not. Keep human explanation and long rationale in README or owned documentation. Put only the stable, non-obvious subset that changes agent decisions in AGENTS.md, and link to the source of truth when additional detail is necessary.
How do you know whether AGENTS.md works?
First verify delivery with a controlled discovery fixture. Then compare representative tasks with and without the file under the same model, host, tools, budget, and evaluator. Track correctness and violations before optimizing tokens or runtime.
Summary
The best AGENTS.md is not the longest or most polished one. It is the smallest reviewed set of repository facts that changes a coding agent's decisions in measurable ways. Keep the file specific, scoped, testable, and free of secrets; verify exact host behavior; enforce permissions outside the prompt; and remove rules that cannot justify their context cost.
Related Resources
- AI Coding Context Files: Architecture, Safety, and Evals
- AI Coding Rule Files: Compare Host Tool Context Contracts
- Context Engineering: Task Packets and Evidence Boundaries
- Prompt Injection: Threat Model and Defenses
- Context Engineering glossary
- Agent Harness glossary
Primary Sources
- AGENTS.md open-format site
- OpenAI Codex: Custom instructions with AGENTS.md
- GitHub Copilot repository instructions
- GitHub Copilot custom agent profiles
- OpenAI Codex repository AGENTS.md
- Apache Airflow repository AGENTS.md
- Temporal Java SDK repository AGENTS.md
- On the Impact of AGENTS.md Files on the Efficiency of AI Coding Agents
- Do Context Files Help Coding Agents?
- OWASP LLM Prompt Injection Prevention Cheat Sheet