Skip to Content
31 AI-Powered Dev Tools05 Copilot Instructions Guide

GitHub Copilot Customization Guide

Seven configuration primitives control how Copilot behaves in your project. They persist across sessions, apply to every team member, and are committed to version control.


Quick Reference

#PrimitiveFileLocationScope
1Workspace instructionscopilot-instructions.md.github/Every interaction in this repo
2AGENTS.mdAGENTS.mdRoot or subfoldersEvery interaction (monorepo-friendly)
3Scoped instructions*.instructions.md.github/instructions/Files matching applyTo glob
4Prompt files*.prompt.md.github/prompts/On-demand via prompt picker
5Custom agents*.agent.md.github/agents/Agent picker or subagent delegation
6SkillsSKILL.md + assets.github/skills/<name>/On-demand via / picker or auto-discovery
7Hooks*.json.github/hooks/Deterministic lifecycle events

Rule: Use copilot-instructions.md OR AGENTS.md for workspace instructions - not both.


1. Workspace Instructions

Create .github/copilot-instructions.md in your repo root. Automatically included in every Copilot interaction.

Example: Python ML Project

# Project: Zero to AI Curriculum ## Stack - Python 3.12+, scikit-learn, pandas, PyTorch - Jupyter notebooks for tutorials, pytest for tests - Sphinx for documentation ## Code Style - Type hints on all function signatures - f-strings over .format() or % - pathlib.Path instead of os.path - Google-style docstrings (Args, Returns, Raises) ## Project Structure - Each phase is a numbered directory (00-course-setup/, 01-python/, etc.) - Notebooks are ordered: 00_START_HERE.ipynb, 01_*, 02_*, ... - Each directory has a README.md as the chapter entrypoint ## Testing - pytest for all tests - Run with: pytest tests/ -v ## What NOT to Do - Do not add API keys or secrets to any file - Do not install packages globally; use .venv - Do not use print() for debugging; use logging

Example: FastAPI Backend

# Project: E-Commerce API ## Stack - Python 3.12, FastAPI, SQLAlchemy 2.0, Alembic, PostgreSQL 16 - pytest + httpx for testing, pydantic-settings for config ## Conventions - All endpoints return Pydantic v2 models - Use async def everywhere, not sync def - Dependency injection for database sessions (src/api/deps.py) - Environment variables via pydantic-settings, never os.getenv() ## Build Commands - Install: pip install -e ".[dev]" - Test: pytest tests/ -v --timeout=30 - Lint: ruff check src/ - Format: ruff format src/

2. AGENTS.md

An alternative to copilot-instructions.md with monorepo hierarchy support. Place AGENTS.md at the repo root or in subfolders - the closest file in the directory tree wins.

/AGENTS.md # Root defaults /frontend/AGENTS.md # Frontend-specific (overrides root for frontend/) /backend/AGENTS.md # Backend-specific (overrides root for backend/)

When to use AGENTS.md vs copilot-instructions.md

ScenarioUse
Single-project repocopilot-instructions.md
Monorepo with different stacks per folderAGENTS.md (one per subfolder)
Want cross-editor compatibilityAGENTS.md (open standard)

Important: Use one or the other - never both in the same repo.

Example

# Backend Guidelines ## Architecture - FastAPI + SQLAlchemy 2.0 - Service layer pattern: never put business logic in route handlers ## Build and Test - Install: pip install -e ".[dev]" - Test: pytest tests/ -v - Lint: ruff check src/ ## Conventions - Use async def everywhere - Environment variables via pydantic-settings

3. Scoped Instructions

For rules that apply only to specific files or directories. Place *.instructions.md files in .github/instructions/ with YAML frontmatter.

Frontmatter

--- description: "Use when writing database migrations" # For on-demand discovery applyTo: "**/*.py" # Auto-attach for matching files ---

Discovery Modes

ModeTriggerUse case
On-demand (description)Agent detects task relevanceTask-based rules: migrations, refactoring
Explicit (applyTo)Files matching glob in contextFile-based rules: language standards
ManualAdd Context → InstructionsAd-hoc attachment

Example: Test Rules

--- applyTo: "tests/**" --- # Test Rules - Use pytest.mark.asyncio for all async tests - Use the `client` fixture (defined in conftest.py) for HTTP tests - Assert specific error messages, not just status codes

Example: RAG Notebook Rules

--- applyTo: "08-rag/**" --- # RAG Notebook Rules - All RAG notebooks must be self-contained (no API keys) - Use TF-IDF or sklearn for retrieval in toy examples - Every notebook must include a benchmark comparison table

Glob Patterns

applyTo: "**" # Always included (use with caution - burns context) applyTo: "**/*.py" # All Python files applyTo: ["src/**", "lib/**"] # Multiple patterns (OR) applyTo: "src/api/**/*.ts" # Specific folder + extension

4. Prompt Files

Reusable workflow templates that appear in Copilot’s prompt picker (/). Save in .github/prompts/.

Frontmatter

--- mode: agent # agent or ask tools: ["terminal", "codebase"] # tools the agent can use description: "Add evaluation metrics" # shown in the picker ---

Example: New API Endpoint

--- mode: agent tools: ["terminal", "codebase"] description: "Scaffold a new API endpoint with tests" --- # New API Endpoint Create a new endpoint for the ${input:resource} resource: 1. Create the route in src/api/routes/${input:resource}.py 2. Create request/response schemas in src/schemas/${input:resource}.py 3. Create the SQLAlchemy model if needed 4. Write tests in tests/api/test_${input:resource}.py 5. Run tests: pytest tests/api/test_${input:resource}.py -v

The ${input:name} syntax prompts the user for values when the prompt is selected.

Example: Security Review

--- mode: agent tools: ["codebase"] description: "Review code for security issues" --- # Security Review Review the current file for: 1. SQL injection vulnerabilities 2. Hardcoded secrets or credentials 3. Missing input validation 4. Insecure deserialization 5. Path traversal risks For each issue found, explain the risk and provide a fix.

5. Custom Agents

Custom personas with specific tools, instructions, and behaviors. Create *.agent.md files in .github/agents/.

Frontmatter

--- description: "Use when running database migrations" # Required: for discovery tools: [read, search, execute] # Tool aliases model: "Claude Sonnet 4" # Optional: override default user-invocable: true # Show in agent picker ---

Tool Aliases

AliasPurpose
executeRun shell commands
readRead file contents
editEdit files
searchSearch files or text
agentInvoke other agents as subagents
webFetch URLs and web search
todoManage task lists

Example: Read-Only Researcher

--- description: "Research codebase questions without making changes" tools: [read, search] --- You are a read-only research agent. Your job is to answer questions about the codebase. ## Constraints - DO NOT edit any files - DO NOT run terminal commands - ONLY read and search ## Output Format Provide a concise answer with file paths and line numbers as evidence.

Example: Test Writer

--- description: "Generate tests for Python modules following project conventions" tools: [read, search, edit, execute] --- You are a test specialist. Generate comprehensive pytest tests. ## Approach 1. Read the target module to understand its API 2. Read existing tests in tests/ for conventions 3. Write tests covering: happy path, edge cases, error cases 4. Run pytest to verify all tests pass ## Constraints - Follow patterns in conftest.py - Use factory_boy for test data - Never mock the function under test

Subagent Pattern

A parent agent can delegate to specialized subagents:

--- description: "Coordinate feature implementation" tools: [read, search, edit, execute, agent] agents: [researcher, test-writer] ---

Set user-invocable: false on helper agents you only want accessible as subagents.


6. Skills

On-demand workflow packages with bundled scripts, templates, and reference docs. The agent loads them when relevant based on the description.

Directory Structure

.github/skills/webapp-testing/ ├── SKILL.md # Required - must match folder name ├── scripts/ │ └── run-tests.sh ├── references/ │ └── test-patterns.md └── assets/ └── config-template.json

SKILL.md Format

--- name: webapp-testing description: "Test web applications using Playwright. Use for verifying frontend, debugging UI, capturing screenshots." argument-hint: "Describe what to test" ---

Body

# Web Application Testing ## When to Use - Verify frontend functionality after changes - Debug UI behavior with screenshots - Run end-to-end tests ## Procedure 1. Start the dev server: `npm run dev` 2. Run [test script](./scripts/run-tests.sh) 3. Review screenshots in `./screenshots/` 4. Report failures with specific selectors

How Skills Differ from Prompts

FeaturePrompt (.prompt.md)Skill (SKILL.md)
Bundled assetsNoYes (scripts, templates, references)
Auto-discoveryNo (manual / picker)Yes (agent reads description)
Progressive loadingNo (full content sent)Yes (description → body → assets)
Best forSingle focused taskMulti-step workflow with assets

Both appear when you type / in chat.


7. Hooks

Deterministic lifecycle automation. Unlike instructions (which guide behavior), hooks enforce behavior via shell commands at specific events.

Location

.github/hooks/*.json # Workspace (team-shared)

Hook Events

EventWhen it fires
SessionStartFirst prompt of a new agent session
PreToolUseBefore a tool is invoked
PostToolUseAfter a tool succeeds
UserPromptSubmitUser submits a prompt
StopAgent session ends

Example: Auto-format After Edits

{ "hooks": { "PostToolUse": [ { "type": "command", "command": "ruff format --quiet .", "timeout": 10 } ] } }

Example: Block Dangerous Commands

{ "hooks": { "PreToolUse": [ { "type": "command", "command": "./scripts/validate-tool.sh", "timeout": 15 } ] } }

The script receives JSON on stdin describing the tool call. It can return:

  • "permissionDecision": "allow" - proceed
  • "permissionDecision": "ask" - ask user for confirmation
  • "permissionDecision": "deny" - block the action

When to Use Hooks vs Instructions

NeedUse
Guide coding styleInstructions
Auto-run formatter after every editHook (PostToolUse)
Prevent rm -rf or DROP TABLEHook (PreToolUse)
Inject runtime contextHook (SessionStart)

8. Decision Flowchart

Is this a project-wide coding standard? ├── Yes → copilot-instructions.md or AGENTS.md │ (monorepo with subfolder differences? → AGENTS.md) └── No ├── Does it apply only to specific files? │ └── Yes → .instructions.md with applyTo ├── Is it a reusable one-shot task? │ └── Yes → .prompt.md ├── Is it a multi-step workflow with scripts/templates? │ └── Yes → SKILL.md ├── Is it a specialized persona with tool restrictions? │ └── Yes → .agent.md └── Must it be enforced deterministically (not just guided)? └── Yes → Hook (.json)

9. Best Practices

Keep Instructions Short and Specific

Bad: Write clean, well-documented code following best practices.

Good:

- Type hints on all function signatures - Google-style docstrings (Args, Returns, Raises) - Max line length: 100 characters - Use ruff for linting and formatting

Include Build/Test Commands

The agent can only run tests if you tell it how:

## Build & Test - Install: pip install -e ".[dev]" - Test: pytest tests/ -v - Lint: ruff check src/

List What NOT to Do

Negative instructions prevent common AI mistakes:

## Do NOT - Do not use os.getenv() - use pydantic-settings - Do not hardcode secrets - use environment variables - Do not add print() for debugging - use logging

Write Keyword-Rich Descriptions

The description field is how Copilot discovers skills, agents, and on-demand instructions. If trigger words aren’t in the description, the agent won’t find it.

Bad: "A helpful skill for testing"

Good: "Test web applications using Playwright. Use for verifying frontend, debugging UI, capturing screenshots."

Commit Everything to Version Control

All customization files should be committed to git - instructions, prompts, agents, skills, and hooks. This ensures every team member gets the same Copilot behavior.


10. Troubleshooting

ProblemFix
Copilot ignores instructionsVerify file is at .github/copilot-instructions.md (exact path)
Using both AGENTS.md and copilot-instructions.mdPick one - having both causes conflicts
Scoped instructions not applyingCheck applyTo glob matches the file you’re editing
Prompt files not appearingEnsure they’re in .github/prompts/ with .prompt.md extension
Agent not appearing in pickerCheck user-invocable isn’t false and description is present
Skill not auto-loadingVerify name in frontmatter matches folder name exactly
Hooks not firingCheck JSON syntax, type: "command", and file is in .github/hooks/
applyTo: "**" slowing things downToo broad - loads on every interaction. Use specific globs
Too much instruction textKeep under ~2000 words total; Copilot has context limits

Next: 06_copilot_workflows.md - real VS Code + Copilot workflows

Last updated on