Building Effective Agent Architectures with GitHub Copilot

Honest disclaimer: The thoughts here are mine — the prose, structure, and general readability are courtesy of AI. I handed it a brain-dump and it handed back something you'd actually want to read. Felt appropriate, given the topic.

GitHub Copilot's customization system separates into four distinct layers: custom agents, instructions, skills, and MCP servers. Each handles a different concern, and they compose together while remaining independently upgradeable.

The key insight: separating "who" (agent workflow), "rules" (project standards), and "how" (capabilities) means you can change one without touching the others. Update standards without rewriting agents. Upgrade skills without modifying instructions. Change agent behavior while keeping conventions intact.

Everything lives in git. Changes go through pull requests. You can review, approve, and roll back AI behavior like infrastructure.

GitHub Copilot ArchitectureCustom AgentsWho orchestrates?CopilotInstructionsWhat rules apply?SkillsWhat capabilities exist?MCP ServersWhat external data?AI Response

Project Structure

A typical setup:

.github/
├─ agents/                    # Custom workflow agents
├─ instructions/              # Context-specific standards
├─ skills/                    # Reusable capabilities (SKILL.md files)
└─ copilot-instructions.md    # Global standards
.vscode/
└─ mcp.json                   # MCP server configs

All version controlled in your repo. Skills are SKILL.md files that define specific operations agents can invoke.

All reviewable through PRs.

Quick example: Want all API errors to follow a consistent format?

# .github/instructions/api.instructions.md
---
applyTo: 'src/api/**'
---
Return errors as: { "error": { "code": "...", "message": "..." } }

Copilot applies this automatically when working on API files. Standard enforced through the tool, not documentation.


The Four Layers

1. Custom Agents

Custom agents define workflow orchestration. They specify which tools are available, coordinate multi-step processes, and delegate to specialist agents.

# .github/agents/feature-builder.agent.md
---
name: Feature Builder
tools: ['agent']
agents: ['Researcher', 'Implementer']
---
Coordinate feature development by delegating research to Researcher (read-only) and implementation to Implementer (write-access).

When custom agents work well:

  • Multi-phase workflows with distinct tool needs
  • Tool restrictions prevent accidents (researcher can't modify code)
  • Specialized expertise per domain

Keep workflow logic here, not coding standards.

2. Instructions

Instructions define project standards that apply automatically based on file context.

# .github/instructions/api.instructions.md
---
applyTo: 'src/api/**'
---
- Validate input with Joi schemas
- Return errors as: { "error": { "code": "...", "message": "..." } }
- Include tests

Global instructions (.github/copilot-instructions.md) apply everywhere. Targeted instructions use applyTo patterns for file-specific rules.

When instructions work well:

  • Team-wide conventions that always apply
  • File-specific standards (API patterns, component conventions)
  • Replacing documentation with enforcement

Keep global instructions under 50 lines. Use targeted files for context-specific rules.

3. Skills

Skills extend what agents can do by providing specific, invokable capabilities. You define them as SKILL.md files in .github/skills/, and agents gain new operations they can perform.

# .github/skills/github-pr-analyzer.SKILL.md
---
name: GitHub PR Analyzer
---
Analyze pull requests for code quality issues, suggest improvements,
and summarize changes for review.

Skills are executable capabilities. When an agent needs to analyze a PR, it invokes the skill. The skill handles the complex logic; the agent uses the result.

Skills load automatically when relevant. Any agent can invoke any skill in your .github/skills/ directory, making capabilities instantly reusable across workflows.

When skills make sense:

  • Complex operations requiring specialized logic
  • Reusable capabilities across multiple agents
  • Domain-specific workflows you want to standardize

4. MCP Servers

MCP servers connect Copilot to external systems—databases, APIs, cloud services.

// .vscode/mcp.json
{
  "mcpServers": {
    "postgres": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-postgres"],
      "env": { "POSTGRES_CONNECTION": "${env:DATABASE_URL}" }
    }
  }
}

When MCP works well:

  • Agents need runtime data (database schemas, API state)
  • External system information affects decisions
  • Data lives outside your codebase

Use environment variables for credentials. Start with read-only operations.


Why Separation Matters

Independent layers mean independent updates. Four examples:

Adding Capabilities

.github/skills/NEW: pr-analyzer.SKILL.md .github/agents/(unchanged) .github/instructions/(unchanged) .vscode/mcp.json(unchanged)All agents gainPR analysis capability

Adding capabilities: Add a new skill file to .github/skills/, and all agents can immediately invoke it. For example, add a PR analyzer skill and all agents gain PR analysis capabilities.

Enforcing Standards

.github/instructions/NEW: api.instructions.md .github/agents/(unchanged) .github/skills/(unchanged) .vscode/mcp.json(unchanged)All API work followsvalidation rules

Enforcing standards: Add API validation requirement to instructions file. Copilot applies it automatically when working on APIs. No reminders needed.

Changing Workflows

.github/agents/MODIFIED:feature-builder.agent.md .github/instructions/(unchanged) .github/skills/(unchanged) .vscode/mcp.json(unchanged)More thoroughplanning phase

Changing workflows: Update feature-builder agent to be more thorough during planning. Standards stay unchanged in separate instruction files.

Switching Data Sources

.vscode/mcp.jsonMODIFIED: postgresconnection .github/agents/(unchanged) .github/instructions/(unchanged) .github/skills/(unchanged)Now connects tocloud database

Switching data sources: Move from local Postgres to cloud database by updating MCP server config. Agents and instructions stay the same—only connection details change.

Shared standards across projects: Create a shared repository of instruction files. Reference them in multiple services via git submodules or sync scripts. Update once, all services benefit.


When to Use Each Layer

YesNoYesNoYesNoYesNoWhat do you need?Always appliesto files?InstructionsFile-based rulesMulti-stepworkflow?Custom AgentOrchestrationReusableoperation?SkillInvokable capabilityExternaldata?MCP ServerRuntime accessNot needed

Static rule that always applies → Instructions
Multi-step workflow → Custom Agent
Reusable specialized operations → Skills
Runtime data access → MCP

Examples:

  • "All API errors use format X" → Instructions
  • "Check if users table has email column" → MCP
  • "Use TypeScript strict mode" → Instructions
  • "Coordinate research then implementation" → Custom Agent
  • "Summarize this GitHub PR" → Skills

Version Control as Governance

These files live in git. Changes go through pull requests:

git checkout -b add-api-validation
# Edit .github/instructions/api.instructions.md
git commit -m "Add email validation requirement"
# Team reviews in PR, merges when approved

All four layers live in your repository as version-controlled files.

For regulated teams:

  • Compliance requirements live as code
  • Git provides audit trail (who changed what, when)
  • Review gates enforce governance through workflows
  • Rollback works like any infrastructure change

You can require security team approval for compliance instruction changes, just like production deployments.


Start Simple

20-30 lines ofcore standardsWhen you needreusable capabilitiesWhen workflowsrepeatWhen global filegrows largeWhen multi-phasepatterns emergeWhen externaldata neededStart Here1. Global Instructions.github/copilot-instructions.md2. Add Skills.github/skills/*.SKILL.md3. Add Agents.github/agents/*.agent.md4. Split Instructions.github/instructions/*.instructions.md5. Add OrchestrationMultiple specialized agents6. Integrate MCP.vscode/mcp.json

Begin with global instructions:

.github/copilot-instructions.md  (20-30 lines covering core standards)

Add skills when you need reusable capabilities:

.github/skills/
└─ github-pr-analyzer.SKILL.md

Add agents when repetitive workflows appear:

.github/agents/
└─ feature-builder.agent.md

Split instructions by context when global file grows:

.github/instructions/
├─ api.instructions.md
└─ components.instructions.md

Add orchestration when multi-phase workflows become common:

.github/agents/
├─ feature-builder.agent.md  (orchestrator)
├─ researcher.agent.md       (specialist)
└─ implementer.agent.md      (specialist)

Integrate external systems when runtime data is needed:

.vscode/mcp.json  (MCP servers)

Each stage solves a real problem. Build complexity incrementally.


Common Pitfalls

Mixing standards into agents: Keep workflow in agents, standards in instructions. If it applies to all work in a directory, it's an instruction.

Monolithic instructions: Don't put everything in one 3000-line file. Split by context using applyTo patterns.

Over-engineering early: Don't create 25 hyper-specific agents before you know what you need. Start with instructions, add agents as workflows emerge.

Duplicating skills unnecessarily: Check existing skills before creating new ones. Don't create five variations of the same operation.

Hardcoding credentials in MCP configs: Use environment variables (${env:VAR_NAME}) for sensitive data. Never commit credentials to version control.


Wrapping Up

The layered approach gives you separation of concerns, independent upgrades, and version-controlled governance.

Agents define workflow. Instructions enforce standards. Skills provide reusable capabilities. MCP accesses external data.

When these work independently, you can upgrade skills without rewriting agents, update standards without touching workflows, and change agent behavior while keeping rules intact.

Version control makes this infrastructure. Changes go through PRs. Git provides audit trails. Everything is reviewable and rollback-able.

For regulated teams, compliance lives as code with traceable changes and enforced review gates.

Start with instructions. Add agents when workflows repeat. Add MCP when external data is needed. Build incrementally.

The value comes from composability, not complexity.


References

Official Documentation:

Comments

Popular posts from this blog

Orchestration Modes with GitHub Copilot Custom Agents

Automate Import of Functions/WebAPI in Azure API Management as backend and using OpenAPI definition and Terraform