# AGENTS.md in 2026: The Pain Points It Removes and the Workload It Saves

> AI agents write more code each month than teams can review by hand. AGENTS.md is the one file that keeps it consistent: solo, team or enterprise.

- **Author:** Suthahar Jegatheesan (MSDEVBUILD)
- **Published:** 2026-05-02
- **Updated:** 2026-09-30
- **Category:** GitHub Copilot
- **Tags:** GitHub Copilot, AGENTS.md, Agent Mode, AI Coding Agents, Team Workflow
- **Canonical URL:** https://blog.msdevbuild.com/blog/agents-md-pain-points-workload-savings/

---

**Highlight:** AGENTS.md is one file at the root of your repository that every AI coding agent reads before it writes code. Without it, each session and each tool makes its own reasonable choice, and one feature ends up built three ways. With it, Copilot, Cursor, Codex and Claude Code all start from the same architecture, and a rule change is one edit.

import Callout from '../../../../components/mdx/Callout.astro';
import ShortHighlight from '../../../../components/ShortHighlight.astro';

AGENTS.md is one file at the root of your repository that every AI coding agent reads before it writes code. It exists because an agent will not stay consistent with itself, or with the agent on the next developer's laptop, unless something tells it how. This is what that inconsistency looks like on a real app, and what the file saves.

Picture the MSDevBuild Eats team starting a sprint. One developer uses GitHub Copilot, one has switched to Cursor, one is trying Claude Code. Each is asked for a piece of the same new feature: let customers save favourite restaurants.

By Friday the feature works. It is also written three different ways.

<Callout type="tip" title="A scenario, on a real app you can run">
This sprint is a scenario played out on MSDevBuild Eats, the open-source Flutter food delivery app used across this blog. The repository ships a real [`AGENTS.md`](https://github.com/jssuthahar/food-delivery-app/blob/main/AGENTS.md), and the commands below run against it.

- **Source code**: [github.com/jssuthahar/food-delivery-app](https://github.com/jssuthahar/food-delivery-app)
- **Live web**: [jssuthahar.github.io/food-delivery-app](https://jssuthahar.github.io/food-delivery-app/)
- **Android build**: [download and install](https://appdistribution.firebase.dev/i/00432c5aa60de58b)
</Callout>

## One sprint, three tools, three "correct" versions

| Day | What happened |
| --- | --- |
| Mon | The Copilot developer adds a `FavouritesCubit`, matching the BLoC used everywhere else |
| Tue | The Cursor developer builds the favourites list screen. Cursor reaches for Riverpod and adds it to `pubspec.yaml` |
| Wed | The Claude Code developer adds the heart button on the restaurant card with a `StatefulWidget` and `setState` |
| Thu | Each part talks to favourites through its own helper. There are now two ways to load the same list |
| Fri | The pull request: **nine review comments** that all ask a version of "why is this different from everywhere else?" |

Nobody did anything wrong. Each agent made a reasonable local choice with zero view of what the others had done. Each tool also had its own idea of the rules: Copilot read `.github/copilot-instructions.md`, Cursor had no rules file, and Claude Code had none either.

That is the whole problem, and it does not depend on team size.

**Solo developer.** In January you ask an agent for a login screen. It picks one way to manage state, one folder structure, one style of error handling. In April you ask again in the same project and get a different answer. Nothing carried January's decision forward.

**Small team.** Three developers, three reasonable choices for the same problem, and duplicate helpers because no agent can see what already exists two folders away.

**Enterprise.** The same thing, at a size where squads do not know they chose differently until a shared feature makes two patterns meet.

<figure>

![Fan-out diagram. One problem, an AI agent writing code without shared context, appears at three scales: a solo developer whose second session does not remember the first, a small team where two people bring two conventions to one repo, and an enterprise where every squad re-explains the same architecture. All three converge on AGENTS.md, written once and read by every agent, described as not a longer file but a more specific one.](./images/agents-md-same-problem-every-scale.png)

<figcaption>Figure 1 — one problem, three scales. The file is the same size in all three.</figcaption>

</figure>

## The commands that showed the drift

On Friday the tech lead stops reading the pull request line by line and asks the repository a different question: how many ways do we manage state now?

```bash
# Features using the house pattern: BLoC or Cubit
grep -rlE 'extends (Bloc|Cubit)<' lib/features | cut -d/ -f3 | sort -u | wc -l

# Anything using Riverpod, which the app does not use
grep -rlE 'riverpod|ConsumerWidget|StateNotifier' lib pubspec.yaml

# Screens holding state with setState
grep -rl 'setState(' lib/features
```

On the favourites branch the answers come back as three lines where there should be one:

| Pattern | Where |
| --- | --- |
| BLoC / Cubit | every feature, including `favourites/bloc/favourites_cubit.dart` |
| Riverpod | `pubspec.yaml` and `favourites/presentation/favourites_screen.dart` |
| `setState` | `restaurant/presentation/widgets/favourite_heart.dart` |

Run the same three commands on `main` and the Riverpod one returns nothing. The `setState` one does return files, and every hit is local form state: a checkbox, a selected emoji, a carousel page, a quantity stepper. That is fine. What is not fine is `setState` holding a feature's data, which is what the favourites heart did. It is also a sign the rule needs one more word: "not `setState` *for business state*". The drift arrived in one sprint, from three tools that each followed their own defaults.

## The real problem: every agent starts from zero

An AI agent does not remember yesterday's session, and it cannot see another developer's. Every session starts from the training data and whatever files are open. If the repository does not say "we use BLoC", the agent picks whichever state library fits the prompt best, and three prompts can easily give three answers.

Per-tool rules files help only the people using that tool. The Copilot developer was consistent with the app because `copilot-instructions.md` said so. Cursor and Claude Code never read that file.

## What AGENTS.md actually fixes

It is one Markdown file at the root of the repository. Agents read it automatically before they write anything. It tells them the architecture, the one approved way to handle state and data, where things belong, and what already exists so they do not rebuild it.

It does not matter whether you write Dart, TypeScript, C# or Python, or whether you are a team of one or two hundred. The fix is the same because the problem is the same.

There is a difference between handing someone repository access and saying "go", and walking them through how the project is built. An agent needs that walkthrough every session. AGENTS.md is that walkthrough, written once and read automatically every time after.

If you would rather see it first, the idea is a short video:

<ShortHighlight slugs={['agents-md-one-file-every-agent']} />

## How is this different from copilot-instructions.md?

They overlap in purpose and differ in scope and in who reads them. [Copilot custom instructions](/blog/github-copilot-custom-instructions) are the Copilot-only version of the same idea.

| | `.github/copilot-instructions.md` | `AGENTS.md` |
| --- | --- | --- |
| Who reads it | GitHub Copilot | Codex, Cursor, Copilot, Windsurf, Aider and more, natively |
| Where it lives | One fixed path | The root, plus optional nested files per folder or package |
| Origin | A GitHub convention | An open, vendor-neutral standard |
| Claude Code | Not applicable | Through a symlink or an `@AGENTS.md` import |
| Best fit | A Copilot-only team | Anyone using, or likely to use, more than one tool |

If everyone uses Copilot and plans to stay there, `copilot-instructions.md` is simpler. The moment a second tool shows up, AGENTS.md stops being the extra file and becomes the one that saves you from maintaining three near-identical instruction files that drift apart.

You can run both. Copilot reads AGENTS.md as well as its own file, so the cleanest setup is shared rules in AGENTS.md and only Copilot-specific guidance, like how to write pull request summaries, in `copilot-instructions.md`.

<figure>

![Architecture diagram. An amber box, AGENTS.md at the repository root, holding the stack, architecture, state, errors, tests and off-limits rules. An arrow labelled "adds folder rules" goes to a grey box, packages/api/AGENTS.md, a nested file where the closest file wins. Arrows from the root file go to four tools: GitHub Copilot, Cursor and OpenAI Codex, which read it natively, and Claude Code, drawn dashed, which reads it through CLAUDE.md with a symlink or @AGENTS.md. All four arrows converge on a green box: one set of rules, whichever tool a developer opens, and a rule change is one edit, not three.](./images/agents-md-one-file-every-ai-coding-agent.png)

<figcaption>Figure 2 — one file, every agent. Claude Code reaches it through a redirect; a nested file adds rules for one folder.</figcaption>

</figure>

## A generic example, not tied to any framework

Here is the shape that works for any stack or team size:

```markdown
# AGENTS.md

## Project
Web app, React frontend, Node/Express backend, PostgreSQL. Monorepo.

## Architecture
Feature-based folders, not type-based. Each feature owns its components,
hooks, and API calls — don't split a feature across /components and /hooks
at the top level.

## State management
Use the existing Zustand store in /src/store. Don't introduce Redux,
Context-based state, or a second store.

## API layer
All requests go through /src/api/client.ts. Don't call fetch() directly
in components, and don't create a second HTTP client.

## Error handling
API errors return a Result<T, Error> type, never throw across the
API boundary. Log unexpected errors through /src/lib/logger.ts.

## Testing
Vitest for units, Playwright for e2e. New features need at least one
unit test per new function in /src/api or /src/store.

## Off-limits
- Don't modify /prisma/migrations
- Don't add new npm dependencies without flagging it in the PR description
```

Swap the details and the same shape works for a Django backend, a Spring Boot service, a Flutter app or an Angular frontend. The sections stay: stack, architecture, the one approved pattern for state and data, error handling, testing, and what is off-limits.

For the Flutter version, open the [`AGENTS.md` in the food delivery app](https://github.com/jssuthahar/food-delivery-app/blob/main/AGENTS.md). It has nine sections, the same ones as above plus setup commands, hard business rules and conventions, filled in for a Clean Architecture Flutter app with BLoC. Its state management section is the line that would have stopped the favourites sprint: "BLoC / Cubit … Not Riverpod, not Provider, not `setState`."

## Creating the file, step by step

The simplest version costs nothing. Create a file named `AGENTS.md` at the root of your repository. Plain Markdown, no tools, no config. Every agent that reads it picks it up from there.

In VS Code with Copilot there is a faster way: open Copilot Chat and type `/init`.

![Copilot Chat in VS Code after running /init, drafting an instructions file from the workspace](./images/CopilotInit.png)

It scans the repository and drafts a first version from what it finds: dependencies, folder structure, existing config. Treat it as a draft. It is good at spotting patterns that are already consistent, but it cannot tell you which one to keep if the codebase already has two or three competing ones. That call is still yours.

For a monorepo, or sub-projects with different stacks, add more `AGENTS.md` files inside subfolders. The file closest to the code being edited wins. Keep shared rules at the root and sub-project details in the nested files.

## Claude Code and AGENTS.md

AGENTS.md is an open standard, and a long list of tools read it natively: OpenAI Codex, Cursor, GitHub Copilot, Windsurf, Aider, Cline, Continue, Goose, Zed and more. No per-tool setup.

The exception is easy to get wrong: when this was written, **Claude Code did not read AGENTS.md natively**. It reads its own file, `CLAUDE.md`. The documented workaround is one of these:

```bash
# Option 1: a symlink, so Claude Code reads AGENTS.md through CLAUDE.md
ln -s AGENTS.md CLAUDE.md
```

```markdown
# Option 2: an import line inside CLAUDE.md
@AGENTS.md
```

Either way you keep one source of rules. This area moves fast, so check the current Claude Code docs before you pick one; native support may have arrived since.

## When AGENTS.md is not the fix

Use AGENTS.md for any rule an agent would otherwise guess. Do not expect it to do three things.

- **Clean up drift that already exists.** It stops *new* drift. Three state libraries already in the codebase stay there until someone removes two of them. Budget that as its own task; the discovery approach in [understanding a legacy codebase with Copilot](/blog/github-copilot-understand-legacy-codebase-discovery) is a good way to find every variant first.
- **Enforce a rule.** It guides; it does not block. If Riverpod must never be merged, add a check in CI that fails when `riverpod` appears in `pubspec.yaml`.
- **Hold secrets or environment details.** Every agent reads it, and it is committed. Keys, connection strings and internal URLs never belong in it.

<Callout type="mistake" title="One rules file per tool">
The instinct on a mixed team is to give every tool its own file: `copilot-instructions.md`, `.cursorrules`, `CLAUDE.md`. It works for a month. Then someone updates one of them, the other two drift, and the agents disagree again, now with three files to blame. Keep one source, AGENTS.md, and point the other tools at it.
</Callout>

## How much workload does it actually save?

There is no controlled study, and anyone quoting a confident percentage is guessing. What you can do is measure it on your own repository, the way the favourites sprint was measured. The file costs almost nothing to run and saves the same kinds of work every sprint.

What the file costs:

| | Size |
| --- | --- |
| The food delivery app's AGENTS.md | 108 lines, 4,548 characters |
| Added to each agent request | roughly 1,100 tokens |
| Time to write a first version | an hour, with `/init` for the draft |

What changed for the favourites feature, rebuilt the following sprint with AGENTS.md in place and every tool pointed at it:

| | Without AGENTS.md | With AGENTS.md |
| --- | --- | --- |
| State patterns in the feature | 3 | 1 |
| New dependencies nobody agreed | 1 (Riverpod) | 0 |
| Ways to load favourites | 2 | 1 |
| Review comments about conventions | 9 | 1 |
| Rules files to keep in sync | 3 (or none) | 1, plus a symlink |

Where the savings show up, in the order you will notice them:

- **Code review time drops first.** Reviewers stop asking "why is this different?" and review the logic.
- **Rework drops next.** Fewer features get built on the wrong pattern, so fewer need a partial rebuild.
- **Ramp-up drops, slowly.** A new developer, or you returning to an old side project, reads one file instead of reverse-engineering competing patterns.

The rule underneath: **the cost is one file read per request; the saving grows with the number of tools and people writing code**. One developer on one tool saves a little. Three developers on three tools save a sprint's worth of "why is this different?".

## Questions a tech lead will ask about this

1. **"We already have copilot-instructions.md. Why another file?"** Because only Copilot reads it. The first time someone opens Cursor or Claude Code, the rules stop applying.
2. **"Won't AGENTS.md and copilot-instructions.md contradict each other?"** Only if the shared rules live in both. Put them in AGENTS.md and keep the Copilot file for Copilot-only guidance.
3. **"Does it fix the Riverpod screen we already merged?"** No. It stops the next one. Removing the existing one is a separate task.
4. **"How do we stop someone ignoring it?"** You cannot, with a Markdown file. A CI check on `pubspec.yaml` and a lint on imports turn the important rules from advice into a failed build.
5. **"Who updates it?"** Whoever changes a convention, in the same pull request that changes the code.

## What to do on day one of a mixed-tool team

- Create `AGENTS.md` at the root, and draft it with `/init` if you use Copilot.
- Move the shared rules out of any tool-specific file into AGENTS.md.
- Symlink `CLAUDE.md` to it, or add `@AGENTS.md` to `CLAUDE.md`.
- Add a CI check for the one or two rules that must never break.
- Run the three `grep` commands above once a sprint, and watch for a second answer.

## Key takeaways

- The problem is not your framework or team size. It appears whenever an agent writes code without shared context.
- Per-tool rules files only reach the people using that tool. AGENTS.md reaches every agent.
- Copilot, Codex, Cursor and many others read AGENTS.md natively; Claude Code needs a symlink or an import line.
- AGENTS.md stops new drift. Existing drift needs its own cleanup, and critical rules need a CI check.
- Measure the savings on your own repo: count competing patterns and convention comments before and after.

## The next sprint

Two weeks later, the same three developers pick up the next feature: order notes for the rider. The repository now has an `AGENTS.md`, a `CLAUDE.md` symlinked to it, and a CI check that fails if `riverpod` appears in `pubspec.yaml`.

Copilot, Cursor and Claude Code each build their part. All three reach for a Cubit. All three load order data through the existing `GetOrderById` use case.

The pull request gets one comment about conventions, a missing `const`. The `grep` commands return one line each, and the favourites cleanup ticket is the only place Riverpod still appears.

## Test yourself: answer in the comments

<Callout type="quiz" title="Test yourself · five questions">

Five situations this article prepares you for. None of the answers is a sentence you can copy from above; each one needs two sections put together. Reply in the comments with the question number and your answer. If you get all five, you could set this up for any mixed-tool team.

1. **The quiet Claude Code session.** A developer adds a thorough AGENTS.md, then uses Claude Code for a week and still gets `setState` screens. What is missing, and what are the two ways to fix it?
2. **The monorepo.** Your repository has a Flutter app in `/app` and an ASP.NET Core API in `/api`. Where do the files go, and which rules belong at the root?
3. **The grep that still answers.** A month after adding AGENTS.md, the Riverpod `grep` still returns two files. Did the file fail? What does it tell you, and what should happen next?
4. **Two files, one rule.** The team's `copilot-instructions.md` says "use Cubit for simple screens" and AGENTS.md says "use Bloc for every screen". What happens, and how do you set the files up so it cannot happen again?
5. **The secret.** Someone adds the Firebase project ID and a test user's password to AGENTS.md "so the agent can run the app". What is wrong, and where should that information live?

<a href="#comments-heading" class="btn btn-outline btn-sm">Answer in the comments →</a>

</Callout>

---

## Frequently asked questions

### What is the difference between AGENTS.md and copilot-instructions.md?

Scope and audience. copilot-instructions.md is read by GitHub Copilot and lives at one fixed path. AGENTS.md is an open, vendor-neutral file read by Codex, Cursor, Copilot, Windsurf, Aider and others, and supports nested files per folder or monorepo package. You can keep both with no conflict.

### Does Claude Code read AGENTS.md?

When this was written it did not read it natively; Claude Code uses its own CLAUDE.md. The documented workaround is a symlink, ln -s AGENTS.md CLAUDE.md, or the line @AGENTS.md inside CLAUDE.md so it imports the shared rules. Support may have changed since, so check the current Claude Code docs.

### Which AI coding tools read AGENTS.md natively?

OpenAI Codex, Cursor, GitHub Copilot, Windsurf, Aider, Cline, Continue, Goose and Zed pick it up with no per-tool configuration, because they agreed on the same filename and location. Claude Code is the notable exception and needs a symlink or an import line.

### Where do I put AGENTS.md in a monorepo?

Put one at the repository root for rules every package shares, and add another AGENTS.md inside any package with its own stack or conventions. Agents use the file closest to the code being edited, so the nested file adds to or overrides the root one for that folder only.

### Do I still need copilot-instructions.md if I have AGENTS.md?

Not if everyone reads AGENTS.md. Copilot reads it too, so a single AGENTS.md is enough for a mixed-tool team. Keep copilot-instructions.md only for Copilot-specific guidance, such as how Copilot should write pull request summaries, and avoid repeating the shared rules in both files.

### How much time does AGENTS.md actually save?

There is no controlled study, so treat any exact figure as a guess. The savings show up first in code review, as fewer "why is this different?" comments, then in rework and onboarding. Measure it on your own repo by counting competing patterns and convention comments before and after.
