How to Write an AGENTS.md That Actually Works
I wrote about how I write and maintain AGENTS.md a few weeks ago. That post covered my process. This one is more prescriptive — what actually changes agent behavior, what doesn't, and what I've learned after maintaining these files across all my projects for over a year.
I ship an AGENTS.md as part of Stacknaut, my SaaS starter kit. Every project I work on has one. I use Droid, Claude Code, and Codex daily — all reading the same file.
PUT CRITICAL RULES AT THE TOP
The agent reads your file top to bottom, and earlier lines carry more weight in practice. Put the things that matter most — the things the agent must never do — at the very top.
Critical Rules
- Never generate database migrations unless explicitly told
- Never commit without running prettier on changed files first
- Never modify files under reference/ or screenshots/
Every rule here came from a real mistake. The agent ran a Drizzle migration without asking once. I added the rule, and it never happened again.
BE SPECIFIC ABOUT COMMANDS
Development commands are the highest-signal section. Agents guess wrong constantly about how to run tests, which package manager to use, how to build. Tell them exactly.
Commands
- Package manager:
pnpm(not npm, not yarn) - Dev server:
pnpm run dev - Type check:
pnpm run type-check - Lint:
pnpm run lint - Tests:
pnpm run test - Deploy:
scripts/push-and-deploy.sh
"Use pnpm not npm" is one line that saves me from correcting the agent every other session. The negative instruction matters — without it, agents default to npm about half the time.
DESCRIBE ARCHITECTURE IN 10 LINES OR LESS
The agent doesn't need a detailed architecture document. It needs to know where things are and how they connect.
Architecture
Monorepo with three packages:
- frontend/ — Vue 3 SPA
- backend/ — Fastify API server
- shared/ — shared types and schemas, keep flat
Path alias: @ resolves to src/ in both frontend and backend.
Database: PostgreSQL via Drizzle ORM. Edit schemas in shared/src/schemas/, not .sql files.
That's enough. The agent will read actual files when it needs more detail.
CODING CONVENTIONS CHANGE BEHAVIOR — BUT ONLY IF THEY'RE CONCRETE
Vague instructions like "write clean code" or "follow best practices" do nothing. The agent already tries to write reasonable code. What changes behavior are specific, testable rules.
Code Style
- Function declarations for top-level functions (not arrow functions)
- Always use curly braces for if/else/for/while, even one-liners
- Prefer const over let; use ternary instead of reassignment
- No comments unless the code is genuinely non-obvious
- Object parameters for functions with more than 2 arguments
Each of these prevents a specific pattern I don't want. Without the curly braces rule, the agent writes braceless one-liners half the time. Without the arrow function rule, I get a mix of styles across the codebase.
TELL IT WHAT YOU DON'T WANT
Negative instructions are often more effective than positive ones — they prevent the specific mistakes the agent keeps making.
- Don't use axios — use fetch
- Don't create new directories without asking
- Don't add try/catch blocks unless the error is actually handled
- Don't install new dependencies without asking
I add these reactively. Every time the agent does something I don't like, I add a negative rule. Over a few weeks, the file accumulates exactly the guardrails this project needs.
GIT COMMIT STYLE IS WORTH SPECIFYING
Without guidance, agents write commit messages like "Updated auth module to handle edge case where user session expires during OAuth flow." I want single-line messages that describe the change, not a paragraph.
Git
- Atomic commits, one logical change per commit
- Single-line commit messages, lowercase, no period
- Format: "add login page" not "Added login page functionality"
SKIP EXPLANATIONS, WRITE INSTRUCTIONS
The agent doesn't need to know why you chose Vue over React. It needs to know what to do and what not to do. Save the rationale for specs and prompts during development — that's where explaining why helps the agent explore solutions and make good decisions on its own. But AGENTS.md is for standing instructions, not reasoning.
Bad:
We chose Vue 3 because of its Composition API which provides better TypeScript support and more flexible code organization compared to the Options API. The reactivity system is built on JavaScript Proxies which gives us fine-grained reactivity tracking.
Good:
- Vue 3 with Composition API and
Discussion in the ATmosphere