BUILD·Jul 4, 2026

How to write project instructions that AI agents actually follow

Your AGENTS.md is competing with the model's training data. Clearer instructions won't win. Here's how to redirect an agent's behavior with before/after examples.

Agent-ready: drop this post into Claude Code or Codex

TL;DR: I spent a day writing the perfect AGENTS.md. Clear rules, documented patterns, exact commands. The first task I gave the agent, it ignored every instruction and did what it “knew” from training. The build failed. The agent blamed itself. It would do the same thing next time. Here is the fix I found: don’t describe the right path. Invalidate the wrong one.

Key takeaways:

  • Agents form a plan from training data before they read your project instructions.
  • A suggestion sits alongside the pre-formed plan. The agent can ignore it.
  • A contradiction forces the agent to abandon its plan and look for alternatives.
  • Three steps: identify the default plan, name it as a failure, point to the alternative.
  • Reserve invalidation for cases where the default approach fails. Overuse makes it noise.

The first time I watched an agent ignore my AGENTS.md, I thought I had written it wrong.

I had spent an afternoon on it. Clear rules about the project structure. Exact commands for the build tool. A documented pattern for adding new components. The agent acknowledged the file, said “reading project instructions,” and then did the exact opposite. It used the wrong package manager. It scaffolded files in the wrong directory. It wrote code that violated every convention I had documented.

I made the instructions clearer. The agent still ignored them.

I made them shorter. Same result.

I added examples. Nothing changed.

The problem was not my instructions. The problem was that the agent had already decided what to do before it read them.

Here is how it works: agents plan before they read

An AI coding agent does not arrive at your project as a blank slate. The moment you give it a task, it forms a plan based on what it learned during pre-training, before it fetches a single file from your project.

Garry Trinder, a Senior Cloud Advocate at Microsoft, documented this pattern in the Agent Experience (AX) series. His team was working on SharePoint Framework (SPFx) upgrades. The agent’s default plan for upgrading a project was to bump the npm packages to the target version. That is what most projects need. That is what the training data taught it.

But an SPFx upgrade is not a package.json edit. It changes file content, adds files, removes files, and requires three sequential upgrades (1.21.1 to 1.22.0 to 1.22.1 to 1.22.2) with different changes at each step. The CLI tool handles the full sequence in one command. The agent ignored it.

Waldek Mastykarz, the Principal Developer Advocate behind the AX series, describes the information cascade that leads to this:

  • The harness assembles context (your instructions, workspace files, tool descriptions)
  • The model reads everything at once and builds a mental model
  • If the model has seen your technology during training, it already has opinions
  • It decides what to do first based on those opinions, not your instructions
  • Your instructions arrive into the context window after the plan has already formed
  • They are read through the lens of that existing plan

If your instructions complement the plan without contradicting it, the plan wins. The instructions become optional input, not directives.

The catch: your instructions are competing with training data

Here is what I did not understand when I wrote that first AGENTS.md.

A suggestion in your instructions sits alongside the agent’s pre-formed plan as one more input. The model can take it or leave it. If the model’s default approach happens to be wrong, your instruction describing the correct approach does not tell it that its current plan is wrong. It says “here is another option.”

The agent weighs both. It has high confidence in its training-derived plan. Your instructions have zero track record. The plan wins.

François Zaninotto from Marmelab wrote about Agent Experience best practices and reached the same conclusion from a different direction. His team found that agents perform best when domain knowledge is embedded in the codebase, not externalized. But even embedded instructions get ignored when they conflict with what the model “knows.”

The TomatoPy benchmark from the State of Docs research tested this directly. Researchers built a fictional pizza-making API that no model had seen in training. They ran 3 agents across 9 sessions with the same task. Claude Code and Cursor fetched the quick-start guide once, wrote code, hit errors, and recovered. They never found the critical page. Codex read the full API reference before writing code and got it right.

The pattern: agents default to speed over accuracy. They act on their best guess and recover from errors. Your instructions need to account for that bias.

Why it works: invalidation forces the plan to change

The fix Trinder’s team found was counterintuitive. They had been writing clearer tips pointing to the correct tool. They made the tips more direct, spelling out the benefit. Nothing changed.

Then they added a warning that explicitly named the failing approach:

“Manually updating package.json alone will result in build failures.”

Five out of five runs used the correct tool.

Here is why this works at a technical level. An LLM abandons a plan when it encounters a statement in the context that makes it impossible to succeed. A suggestion sits alongside the existing plan as optional input. A statement that the plan will fail creates a constraint that cannot be satisfied without dropping that plan entirely. The model has to find another path.

The difference is:

PatternWhat it doesAgent response
Tip”You could use X instead”Optional. Agent evaluates both options. Default plan wins.
Invalidation”Doing Y will fail because Z”Binding constraint. Agent cannot satisfy the requirement and keep its plan.
Redirect”Use X. Here is the command.”After invalidation clears the wrong path, this becomes the obvious next step.

The invalidation is what does the work. Not the alert type, not the formatting. It is the specific naming of the failing approach and why it fails.

How to find the agent’s default plan

Before you can write instructions that redirect agents, you need to know what they are doing by default. Three steps:

Step 1: Run the agent on a real task without custom instructions.

Give the agent a task developers on your team would give it. Do not point it to any instructions, rules files, or AGENTS.md. Let it work. Watch what it does.

What package manager does it reach for? What patterns does it scaffold? What SDK version does it use? Does it call the right CLI tool, or does it try to do things manually?

Run this 3 to 5 times. Agents have variation across runs. You are looking for the consistent default.

Step 2: Name the default plan and document why it fails.

Write down what the agent does by default. Be specific:

  • “The agent will try to upgrade by editing package.json directly.”
  • “The agent will scaffold components with default Vite settings instead of the project template.”
  • “The agent will use SDK v2 imports instead of v3.”

Then state why each default fails:

“Editing package.json alone will cause build failures because each version upgrade requires file migrations that the npm install command does not handle.”

Step 3: Add the invalidation to your instructions, followed by the redirect.

Put both in your project instructions file (AGENTS.md, CLAUDE.md, copilot-instructions.md, or a .cursor/rules file):

## Upgrade instructions

Do NOT edit package.json directly to upgrade the framework version.
Doing that alone will result in build failures because migration
scripts need to run between versions.

Instead, run: `npx cli upgrade --target <version>`

The invalidation comes first. The redirect follows. The agent reads the invalidation, drops its plan, and reaches for the command you specified.

When to break the pattern

The invalidation pattern works because it is rare. If every instruction tells the agent its plan will fail, none of them do. The model learns to treat them as noise, the same way it treats everything else.

Reserve the pattern for cases where:

  • The agent’s default plan is consistently wrong and the cost of failure is high (breaking build, wrong SDK, deleted files).
  • The correct approach is not what the model would naturally reach for. It requires a specific tool, a multi-step process, or configuration the agent cannot infer.
  • You have evidence from running the agent that the default approach fails. Do not guess. Run it first.

For code style preferences, naming conventions, and architectural patterns, use the standard instruction format. Tell the agent what to do. It will follow because there is no pre-formed plan to override.

Shrivu Shankar’s AI Can’t Read Your Docs makes a related point about designing tools that give agents actionable feedback. If your CLI produces error messages that name the failure and suggest the next step, the agent self-corrects without needing instruction files. That is a better pattern than invalidation because it works at runtime, not only at plan formation.

Invalidation is for the cases where runtime feedback is impossible. The failure happens at build or deploy, not during the agent’s loop.

What this looks like in practice

Here is a before-and-after for a project instructions file. The project uses a custom CLI for component scaffolding instead of the default framework generator.

Before (tip format):

## Scaffolding

Use `npm run scaffold:component` instead of the default generator.
It handles routing registration and dependency injection automatically.

The agent reads this as optional guidance. Its training data says the default generator works fine. It uses the default generator.

After (invalidation format):

## Scaffolding

Using the default framework generator for components will fail
because the CLI must register routes and inject dependencies that
the default generator does not know about.

Run: `npm run scaffold:component --name <ComponentName>`

The agent reads the first paragraph and cannot keep its default plan. The default generator is now a constraint violation. It drops the plan and runs the command.

The same pattern applies to AGENTS.md files for AI projects. If your agent project uses a specific harness, name the harnesses the agent should not use:

## Agent framework

Do NOT use LangGraph for this project. The deployment environment
requires a harness with built-in MCP support that LangGraph does
not provide.

Use Flue or the custom harness in /lib/harness/ instead.

The agent’s training data might rank LangGraph as the best option. An invalidation in your instructions overrides that.

Addy Osmani’s How to write a good spec for AI agents covers the broader pattern of using governance-like project rules (commands, testing, boundaries) that agents follow reliably. The invalidation pattern slots into the “Boundaries” section of any spec. It tells the agent not only what to use but what approach will fail.

Why this matters more as agents get smarter

As frontier models absorb more training data, their default plans get more confident. A model that has seen 10,000 Django projects “knows” how to scaffold a Django app. If your project uses a non-standard setup, that confidence works against you.

The invalidation pattern will not always work. Future agent architectures might weigh instructions differently, or harnesses might change how context is assembled. But the core insight is rooted in how LLMs process context: agents plan before they read, and contradiction is more powerful than suggestion. That will survive model upgrades.

For now, the fix is simple. Write instructions that name the wrong path before you describe the right one. Your agent will thank you by reading them.

Agent mode

Agents form a plan from training data before reading project instructions. To redirect them, do not describe the right approach. Invalidate the wrong one. Name the default plan, state why it will fail, then point to the alternative. Suggestion is optional; contradiction is binding.

FAQ

Why do AI agents ignore project-level instructions like AGENTS.md? Agents form a plan from training data before they read your instructions. A suggestion in your instructions sits alongside the pre-formed plan. A statement that the plan will fail forces the agent to drop it.

How do I write project instructions that agents follow? Three steps: (1) Run the agent on a real task and identify its default plan. (2) Name that plan in your instructions and state it will fail. (3) Point to the correct alternative. The right instruction invalidates the wrong path, not only describes the right one.

What is the difference between a tip and an invalidation in agent instructions? A tip says “try this instead.” It sits alongside the agent’s plan as one more input. An invalidation says “this specific approach will fail.” It creates a constraint the agent cannot satisfy without dropping its current plan entirely.

When should I NOT use the invalidation pattern in agent instructions? When the agent’s default plan is already correct. Invalidation language everywhere becomes noise. Reserve it for cases where the default approach genuinely causes failures.


This article was published on Agentic Up (https://agenticup.dev): practical guides for developers and founders building with AI agents. Reach me at [email protected]

Newsletter

Get the brief on AI agents

Practical posts on shipping agents, automating work, and building in public. No hype, no fluff.

Contact: [email protected]