Writing Effective Instructions
A useful AGENTS.md depends less on how many instructions you write and more on how clearly you write them.
Compare:
- Write good tests.
with:
- Add unit tests for new service-layer business logic.
- Add a regression test when fixing a bug.
- Run `pnpm test` before completing changes.
Both talk about testing.
Only one clearly tells the agent what to do.
Let's learn how to write instructions that are easier for coding agents to follow.
1. Make Instructions Specific
Avoid instructions that can have many interpretations.
❌ Bad
- Write clean code.
What does "clean" mean?
⚠️ Better
- Keep code simple and reusable.
Still subjective.
✅ Strong
- Keep business logic outside React components.
- Extract shared business logic into functions inside `src/lib`.
Now the instruction describes an observable project convention.
2. Make Instructions Actionable
A useful instruction should usually imply an action.
❌ Bad
- Testing is important.
This states an opinion.
It doesn't tell the agent what to do.
⚠️ Better
- Make sure changes are tested.
Better, but still unclear.
✅ Strong
- Add unit tests for new business logic.
- Run `pnpm test` before completing changes.
The expected actions are clear.
3. Use Real Commands
Don't make the agent guess how to validate something.
❌ Bad
- Run the tests.
Which command?
⚠️ Better
- Run the test suite before finishing.
Still missing the command.
✅ Strong
- Run `pnpm test` before completing changes.
Even better when different validations have different purposes:
- Run `pnpm lint` after modifying application code.
- Run `pnpm typecheck` after changing TypeScript types.
- Run `pnpm test` after changing business logic.
4. Define When the Rule Applies
Not every rule needs to run for every task.
Consider:
- Run database integration tests.
Does this apply when changing a CSS class?
Probably not.
✅ Better
- Run database integration tests when modifying database queries, repositories, or migrations.
Now the instruction has a trigger.
A useful pattern is:
When <condition>,
do <action>.
For example:
- When adding a new API endpoint, add an integration test.
or:
- When changing a public API contract, update `openapi.yaml`.
5. Explain Important Boundaries
Sometimes telling the agent what not to do is essential.
❌ Weak
- Be careful with generated files.
✅ Strong
- Do not manually modify files inside `src/generated`.
Better still, tell the agent what to do instead:
- Do not manually modify files inside `src/generated`.
- Run `pnpm generate` when generated code needs to change.
This gives both:
Boundary
+
Correct workflow
6. Prefer Positive Instructions When Possible
Negative rules are sometimes necessary.
But positive instructions often provide better guidance.
❌ Only negative
- Don't put business logic in controllers.
The agent now knows what not to do—but not where the logic belongs.
✅ Better
- Keep controllers limited to HTTP concerns.
- Put business logic inside service classes.
Now the architecture is clear.
Use negative instructions primarily for important boundaries:
- Never commit secrets.
- Do not modify generated files manually.
- Do not remove failing tests simply to make the suite pass.
7. Avoid Subjective Words
Words like these can be difficult to act on:
clean
good
proper
nice
appropriate
best
simple
elegant
high quality
For example:
❌ Bad
- Write proper error handling.
✅ Better
- Convert known domain errors into typed API errors.
- Log unexpected server errors with request context.
- Do not expose stack traces in API responses.
The second version describes actual behavior.
8. Use Project Vocabulary
Generic instructions become more useful when connected to your actual architecture.
Generic
- Put code in the correct layer.
Project-specific
- Controllers handle HTTP request and response concerns.
- Services contain business logic.
- Repositories contain database access.
Now "correct layer" has a concrete meaning.
9. Point to the Source of Truth
Sometimes the best instruction isn't to repeat information.
It's to tell the agent where authoritative information lives.
For example:
- Follow `openapi.yaml` for public API contracts.
or:
- Follow `docs/architecture.md` when changing service boundaries.
or:
- Use existing design tokens from `src/styles/tokens.ts`.
This prevents AGENTS.md from duplicating information that may later become stale.
10. Avoid Over-Specifying the Implementation
Instructions should guide the agent without unnecessarily preventing reasonable solutions.
Consider:
- Every new feature must create exactly one service class containing exactly three methods.
That's extremely restrictive.
Unless your architecture genuinely requires this, it may produce worse code.
A better rule might be:
- Keep business logic inside the service layer.
Give the agent the constraints that matter.
Don't prescribe every implementation detail.
11. Avoid Ambiguous Absolutes
Words like:
always
never
every
all
only
are powerful.
Use them intentionally.
Consider:
- Always add tests for every code change.
Does changing a typo in documentation require a test?
Probably not.
Instead:
- Add tests for new business logic and bug fixes.
However, absolutes are appropriate for genuine boundaries:
- Never commit secrets.
or:
- Never manually modify generated migration snapshots.
Use absolute language when the rule is actually absolute.
12. Group Related Instructions
Compare this:
- Use Vitest.
- Use pnpm.
- Never commit secrets.
- Tests go beside source files.
- Use TypeScript.
- Run tests before finishing.
- Don't edit generated files.
with:
## Development
- Use TypeScript.
- Use `pnpm`.
## Testing
- Use Vitest.
- Place unit tests beside source files.
- Run `pnpm test` before completing changes.
## Repository Boundaries
- Never commit secrets.
- Do not manually edit generated files.
Same information.
Much easier to scan.
Markdown headings are useful because AGENTS.md is meant to remain understandable to humans too.
13. Keep Instructions Short
Avoid turning one instruction into an essay.
❌ Too much
Whenever you create a new service, you should remember that our
architecture has historically tried to separate database access from
business logic because we had problems several years ago where...
✅ Better
- Keep business logic inside services.
- Access the database through repositories.
If the architectural reasoning matters, link to documentation:
- Follow the service/repository boundaries described in `docs/architecture.md`.
14. Make Validation Verifiable
Consider:
- Make sure the application works.
How should the agent verify that?
Instead:
Before completing application changes:
1. Run `pnpm lint`.
2. Run `pnpm typecheck`.
3. Run relevant tests.
Now there is a concrete validation process.
A useful question when writing instructions is:
How would the agent know it has satisfied this instruction?
If that's difficult to answer, the instruction may be too vague.
15. Don't Repeat the Same Idea
Avoid:
- Run tests before finishing.
- Make sure tests pass.
- Verify the test suite.
- Don't finish without testing.
Prefer:
- Run `pnpm test` before completing changes.
One strong instruction is usually better than four weak ones.
16. Bad → Better → Strong
Let's practice.
Example 1 — Testing
❌ Bad
- Test your code.
⚠️ Better
- Add tests for new features.
✅ Strong
- Add unit tests for new service-layer business logic.
- Add regression tests for bug fixes.
- Run `pnpm test` before completing changes.
Example 2 — Architecture
❌ Bad
- Follow the architecture.
⚠️ Better
- Separate business logic from API code.
✅ Strong
- Keep HTTP handling inside controllers.
- Put business logic inside services.
- Access the database through repositories.
Example 3 — Dependencies
❌ Bad
- Don't install unnecessary packages.
⚠️ Better
- Prefer existing packages.
✅ Strong
- Reuse existing dependencies when they satisfy the requirement.
- Do not add another validation library; use the existing Zod dependency.
Example 4 — Documentation
❌ Bad
- Keep docs updated.
⚠️ Better
- Update documentation when needed.
✅ Strong
- Update `openapi.yaml` when changing public API contracts.
- Update README setup instructions when development commands change.
Example 5 — Generated Code
❌ Bad
- Be careful with generated code.
⚠️ Better
- Don't modify generated code.
✅ Strong
- Do not manually edit files inside `src/generated`.
- Run `pnpm generate` when generated code needs to change.
17. A Useful Instruction Formula
A strong instruction often contains three pieces:
WHEN
+
DO
+
HOW / WHERE
For example:
When fixing a bug,
add a regression test
using the existing Vitest test suite.
You don't need to literally write every instruction in this format.
But it's a useful mental model.
Another useful formula is:
Action
+
Scope
+
Constraint
Example:
- Add unit tests for new service-layer business logic using Vitest.
Where:
Action → Add unit tests
Scope → New service-layer business logic
Constraint → Use Vitest
18. Review Instructions Like Code
Your AGENTS.md should evolve with your repository.
When reviewing it, ask:
Is this still correct?
Is this specific?
Is this actionable?
Is this duplicated?
Does this conflict with another rule?
Can tooling enforce this instead?
Does the agent actually need this?
Delete instructions that no longer provide value.
Improving AGENTS.md isn't only about adding instructions.
Sometimes the best improvement is removing one.
Mini Exercise
Which instruction is better?
A
- Follow best practices when creating APIs.
B
- Validate API request bodies using Zod.
- Keep business logic inside services.
- Add an integration test for new endpoints.
B is more useful because the expected behavior is explicit and verifiable.
Now consider:
A
- Don't break anything.
B
- Run `pnpm typecheck` and relevant tests before completing application changes.
Again, B turns an intention into an actionable workflow.
Instruction Quality Checklist
Before adding an instruction, ask:
- Is it specific?
- Is it actionable?
- Is its scope clear?
- Is it still accurate?
- Can the agent verify it?
- Does it avoid unnecessary duplication?
- Is it project-specific enough to be useful?
- Is
AGENTS.mdthe right place for it?
You don't need every instruction to satisfy every question.
But the more it does, the more useful it usually becomes.
Key Takeaway
Don't write instructions that merely sound good.
Write instructions that help an agent make the right implementation decision.
Prefer:
Vague
↓
Specific
Subjective
↓
Observable
Generic
↓
Project-specific
Suggestion
↓
Action
"Make sure it works"
↓
Concrete validation
The best AGENTS.md instructions make it easy for both a coding agent and a human developer to answer:
What exactly am I expected to do here?
Up Next
Scope & Nested AGENTS.md
We've already introduced nested instruction files.
Next we'll go deeper: how to decide when a nested file is justified, how to divide instructions across a monorepo, how inheritance works conceptually, and how to avoid creating an instruction hierarchy that's harder to maintain than the code itself.