Even advanced models like Claude Sonnet 5 write code fast, but they write code for a generic version of the internet. They do not know your repository. They do not know that you migrated from Tailwind v3 to v4 last week, or that your team bans default exports, or that your database wrapper requires a specific transaction helper for writes.
When you prompt an AI agent in a large codebase, it relies on semantic search to find context. If the search query misses the file containing your architectural rules, the LLM guesses. It uses outdated patterns, leading to the security and maintainability issues of vibe coding. You spend your afternoon reverting commits and fixing type errors.
You can fix this by introducing a single file to your repository root: agent.md.
This file acts as a system prompt and architectural blueprint designed specifically for AI coding assistants. It tells the agent how your codebase works, what libraries to use, and what patterns to avoid.
The Context Retrieval Problem
Most modern AI code editors use Retrieval-Augmented Generation (RAG) to pull context into the prompt. When you ask the agent to "create a new user registration form," the editor searches your codebase for files matching "user," "registration," "form," and "input."
This approach has three major flaws:
- Missing Implicit Rules: Your team might have a rule that all form submissions must go through a custom hook for telemetry. If that hook is defined in a generic
telemetry.tsfile, semantic search probably will not pull it into context for a "user registration" query. - Version Mismatch: The LLM training data contains millions of outdated code examples. Without explicit version pinning in the context, the LLM will write code using deprecated syntax from three years ago.
- Noise Pollution: RAG often pulls in test files, configuration files, and build scripts that distract the model. The LLM tries to synthesize code from this noise, leading to bloated implementations.
An agent.md file bypasses these search limitations. It serves as a static, high-priority context anchor that the LLM reads before generating any code.
Why Markdown Works Best
You might wonder why we use Markdown instead of JSON or YAML.
LLMs are trained on natural language. They parse Markdown headings, bullet points, and code blocks with high accuracy. Markdown allows you to write clear, expressive rules, embed code snippets of correct patterns, and format text in a way that aligns with the model's attention mechanisms.
Markdown is also human-readable. Your developers can update it during standard code reviews without fighting syntax errors or schema validations.
Anatomy of a Productive agent.md File
A good agent.md file is structured, concise, and direct. It should avoid vague advice like "write clean code" or "make it fast." Instead, it must provide concrete constraints and specific patterns.
A production-ready agent.md contains five core sections:
1. System Architecture & Tech Stack
This section defines the bounds of your system. It prevents the LLM from suggesting libraries you do not use or writing code in the wrong paradigm.
## Tech Stack & Versions
- Runtime: Node.js v20 (LTS)
- Framework: Next.js v15 (App Router, React Server Components)
- Database: PostgreSQL via Prisma ORM v6
- Styling: Tailwind CSS v4 (using CSS-first configuration)
- State Management: Zustand (no Redux, no MobX)2. Core Coding Conventions
Explain how you write code. If you enforce specific variable naming best practices, prefer functional components over classes, or use explicit types over inference, state it here.
## Coding Conventions
- Use TypeScript strictly. No `any`. Use `unknown` if the type is truly dynamic.
- Prefer functional programming patterns. Avoid classes unless extending framework base classes.
- All data fetching must happen in React Server Components (RSCs) where possible.
- Use arrow functions for component definitions.
- Export components as named exports, not default exports.3. The Anti-Library (Banned Patterns)
This is the most critical section. LLMs default to common internet patterns. If those patterns are anti-patterns in your codebase, you must explicitly ban them.
## Banned Patterns & Anti-Patterns
- Never use `useEffect` for data fetching. Use React Server Components or TanStack Query.
- Do not use inline styles. Use Tailwind utility classes.
- Never write raw SQL queries directly in route handlers. Use the Prisma client wrapper in `lib/db.ts`.
- Do not import icons from the main `lucide-react` package. Import from `@lucide/lab` to keep bundle sizes small.
- Do not use `console.log` for error logging. Use the structured logger in `lib/logger.ts`.4. Common Workflows and Commands
AI agents frequently need to run tests, build the project, or run migrations to verify their work. Give them the exact commands to use.
## Development Commands
- Run development server: `pnpm dev`
- Run unit tests: `pnpm test:unit`
- Run integration tests: `pnpm test:integration`
- Generate Prisma client: `pnpm prisma generate`
- Run database migrations: `pnpm db:migrate`5. Code Patterns (The "Write it Like This" Section)
Provide short, correct code templates. LLMs copy patterns. Showing them a perfect implementation of a route handler or a database query ensures they match your exact style.
## Reference Implementation: Route Handler
Write API route handlers using this exact structure:
```ts
import { NextResponse } from 'next/server';
import { db } from '@/lib/db';
import { logger } from '@/lib/logger';
import { z } from 'zod';
const RequestSchema = z.object({
email: z.string().email(),
});
export async function POST(request: Request) {
try {
const json = await request.json();
const payload = RequestSchema.parse(json);
const user = await db.user.create({
data: { email: payload.email },
});
return NextResponse.json({ id: user.id }, { status: 201 });
} catch (error) {
logger.error('Failed to create user', { error });
return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
}
}
## Configuring IDE Agents to Read agent.md
Creating the file is only half the battle. You must configure your development tools to read it.
### Cursor
Cursor is a popular AI-first code editor. It looks for a file named `.cursorrules` in the root of your project. Instead of duplicating your rules, keep your `.cursorrules` file simple and point it directly to `agent.md`.
Create a `.cursorrules` file in your root:
```text
Always read the rules, tech stack, and coding conventions defined in agent.md before writing, editing, or refactoring code. Adhere to the banned patterns strictly.
This setup ensures that whenever Cursor initializes its system prompt, it reads the contents of agent.md and applies them to the session.
Cline / VS Code Extensions
If you use Cline, Roo Code, or similar agentic extensions, you can configure them to read agent.md by setting it as a system prompt instruction.
In your project settings or the extension's configuration block, add:
{
"systemPromptInstructions": "Read the file agent.md at the root of the project to understand the architectural rules and coding standards before generating code."
}GitHub Copilot
For GitHub Copilot, you can create a .github/copilot-instructions.md file. Add a reference inside that file pointing to your root agent.md file:
Refer to the rules in the root agent.md file for coding style guidelines, tech stack details, and banned patterns.Keep the File Up to Date
An outdated agent.md is worse than no agent.md. If the file tells the agent to use Prisma, but you migrated to Drizzle last month, the agent will write broken code.
Integrate agent.md maintenance into your team's workflow:
- Pull Request Reviews: When a pull request changes a major dependency or introduces a new architectural pattern, make updating
agent.mda merge requirement. - Automated Validation: Write a simple shell script or GitHub Action that runs on pull requests to verify that the versions listed in
agent.mdmatch the versions inpackage.json,Cargo.toml, orgo.mod.
Here is a quick bash script you can run in your CI pipeline to prevent version drift:
#!/usr/bin/env bash
set -euo pipefail
# Extract version from package.json
PACKAGE_VERSION=$(node -p "require('./package.json').dependencies.next")
# Check if agent.md contains this version
if ! grep -q "Next.js v${PACKAGE_VERSION%%.*}" agent.md; then
echo "Error: agent.md version mismatch. Please update agent.md to match Next.js version: $PACKAGE_VERSION"
exit 1
fi
echo "agent.md validation passed."The Results
Standardizing your repository context using an agent.md file changes the way you interact with AI coding tools. Instead of spending your time correcting syntax errors, explaining your directory layout, and deleting hallucinated code patterns, you can focus on the logic of your application.
The agent becomes a developer who knows your codebase. It writes code that matches your team's style, avoids your specific pitfalls, and uses your exact toolset from the very first prompt.



