How to Write agents.md Files That Actually Work: 2,500 Repos Analyzed
Analysis of 2,500+ repos reveals what makes agents.md files actually work: executable commands, code examples over prose, clear boundaries, and exact tech stack details. Most fail because they're too vague.
TL;DR
- GitHub Copilot's custom agents feature lets you build specialist AI assistants via agents.md files
- Analysis of 2,500+ repos shows most agent files fail because they're too vague — specificity wins
- Successful agents have: executable commands early, code examples over prose, clear boundaries, and exact tech stack details
- Start with one simple task (docs, tests, linting) and iterate based on mistakes
The Big Picture
GitHub Copilot just got a lot more useful. Instead of one general-purpose assistant, you can now build a team of specialists through custom agents defined in agents.md files. Want a @docs-agent that only writes documentation? A @test-agent that never touches source code? A @security-agent that audits but never deploys? You can build all of them.
The concept is simple: each agents.md file defines an agent persona with frontmatter and custom instructions. You specify the agent's role, the exact tech stack it should know, the project's file structure, workflows, and the explicit commands it can run. You provide code style examples and set clear boundaries of what not to do.
But here's the problem: most developers are writing agent files that don't work. "You are a helpful coding assistant" is useless. "You are a test engineer who writes tests for React components, follows these examples, and never modifies source code" actually works.
One developer analyzed over 2,500 public agents.md files to understand what separates the failures from the successes. The pattern is clear: provide your agent a specific job, exact commands to run, well-defined boundaries, and concrete examples of good output. Vague instructions produce vague results. Specific instructions produce useful agents.
What Actually Works: The 2,500 Repo Analysis
The analysis revealed a sharp divide between agent files that fail and those that work. The successful ones aren't generic helpers. They're specialists with clear operating manuals. Here's what the top-performing files do:
Put commands early. The best agent files list executable commands in an early section: npm test, npm run build, pytest -v. Not just tool names — actual commands with flags and options. Your agent will reference these constantly.
Code examples beat explanations. One real code snippet showing your style is worth three paragraphs describing it. Show what good output looks like. Don't tell the agent to "write clean code." Show it what clean code looks like in your codebase.
Set clear boundaries. Tell the AI what it should never touch: secrets, vendor directories, production configs, specific folders. "Never commit secrets" was the most common helpful constraint across successful agent files. The three-tier system works best: always do, ask first, never do.
Be specific about your stack. Say "React 18 with TypeScript, Vite, and Tailwind CSS" not "React project." Include versions and key dependencies. The agent needs to know if you're using Jest or Vitest, Express or Fastify, Python 3.9 or 3.12.
Cover six core areas. The top-tier agent files hit these areas: commands, testing, project structure, code style, git workflow, and boundaries. Miss one and your agent will make predictable mistakes.
What This Changes For Developers
Custom agents shift how you interact with AI coding tools. Instead of one assistant that's mediocre at everything, you build specialists that excel at specific tasks. This matters because context switching kills productivity. When you're writing tests, you don't want an agent that might also refactor your API or update your docs. You want an agent that only writes tests.
The workflow changes too. You stop writing prompts from scratch every time. Instead, you invoke @test-agent or @docs-agent and the context is already loaded. The agent knows your tech stack, your file structure, your coding standards, and your boundaries. You're not teaching it every time — you taught it once in the agents.md file.
This approach also makes AI assistance safer. A @lint-agent that can only fix style issues and never change logic is low-risk. A @docs-agent that can only write to docs/ and never touch src/ won't break your build. A @dev-deploy-agent that requires explicit approval before deploying won't accidentally push to production. GitHub's approach to agentic security emphasizes these kinds of guardrails.
The real shift is moving from "AI that helps me code" to "AI team members with specific jobs." You wouldn't ask your QA engineer to write API documentation. Don't ask your @test-agent to do it either.
Try It Yourself
Here's a complete agents.md file for a documentation agent. Save this to .github/agents/docs-agent.md in your repo:
---
name: docs_agent
description: Expert technical writer for this project
---
You are an expert technical writer for this project.
## Your role
- You are fluent in Markdown and can read TypeScript code
- You write for a developer audience, focusing on clarity and practical examples
- Your task: read code from `src/` and generate or update documentation in `docs/`
## Project knowledge
- **Tech Stack:** React 18, TypeScript, Vite, Tailwind CSS
- **File Structure:**
- `src/` – Application source code (you READ from here)
- `docs/` – All documentation (you WRITE to here)
- `tests/` – Unit, Integration, and Playwright tests
## Commands you can use
Build docs: `npm run docs:build` (checks for broken links)
Lint markdown: `npx markdownlint docs/` (validates your work)
## Documentation practices
Be concise, specific, and value dense
Write so that a new developer to this codebase can understand your writing, don't assume your audience are experts in the topic/area you are writing about.
## Boundaries
- ✅ **Always do:** Write new files to `docs/`, follow the style examples, run markdownlint
- ⚠️ **Ask first:** Before modifying existing documents in a major way
- 🚫 **Never do:** Modify code in `src/`, edit config files, commit secrets
Why this works: It states a clear role (expert technical writer), gives executable commands (npm run docs:build, npx markdownlint docs/), specifies the tech stack with versions, and sets three-tier boundaries that prevent destructive mistakes.
You can also have Copilot generate one for you. Open a new file at .github/agents/test-agent.md and use this prompt:
Create a test agent for this repository. It should:
- Have the persona of a QA software engineer
- Write tests for this codebase
- Run tests and analyzes results
- Write to "/tests/" directory only
- Never modify source code or remove failing tests
- Include specific examples of good test structure
Copilot will generate a complete agent file based on your codebase. Review it, add YAML frontmatter, adjust the commands for your project, and you're ready to use @test-agent.
Six Agents Worth Building
@docs-agent: Reads your code and generates API docs, function references, and tutorials. Give it commands like npm run docs:build and markdownlint docs/ so it can validate its own work. Tell it to write to docs/ and never touch src/.
@test-agent: Writes unit tests, integration tests, and edge case coverage. Point it at your test framework (Jest, PyTest, Playwright) and give it the command to run tests. Critical boundary: it can write to tests/ but should never remove a failing test just because it can't fix it.
@lint-agent: A safe early agent. It fixes code style and formatting but shouldn't change logic. Give it commands that let it auto-fix style issues (npm run lint --fix, prettier --write). Low-risk because linters are designed to be safe.
@api-agent: Builds API endpoints. It needs to know your framework (Express, FastAPI, Rails) and where routes live. Give it commands to start the dev server and test endpoints. Key boundary: it can modify API routes but must ask before touching database schemas.
@dev-deploy-agent: Handles builds and deployments to your local dev environment. Keep it locked down: only deploy to dev environments and require explicit approval. Give it build commands and deployment tools but make the boundaries very clear.
@security-agent: Audits code for vulnerabilities, checks dependencies, scans for secrets. Give it commands like npm audit, semgrep scan, gitleaks detect. Boundary: it can report issues but should never auto-fix security problems without approval.
The Bottom Line
Use custom agents if you're tired of re-explaining your codebase to AI every single time. Skip them if you're working on a tiny project where one general assistant is enough. The real opportunity here is specialization — agents that do one thing well instead of everything poorly.
Start with one simple agent. Pick something low-risk like @lint-agent or @docs-agent. Don't try to build a "general helper" — that's what you already have. Build a specialist. Test it. Watch where it makes mistakes. Add detail to your agents.md file based on those mistakes. The best agent files grow through iteration, not upfront planning.
The risk is over-engineering. Don't build six agents on day one. Build one, use it for a week, then build another. The developers who analyzed 2,500 repos found that the successful ones started simple and added complexity only when needed.
If you're already using GitHub Copilot, this is worth trying. If you're not, this feature alone isn't a reason to switch — but it's a strong signal that AI coding tools are moving from generic assistants to specialized team members. That shift matters.
Source: GitHub Blog