A few months back I sat in a code review that made me stop and think. Nikhil, a strong developer on our team in Coimbatore, had used GitHub Copilot to scaffold a new Web API feature. The code compiled. Tests passed. But the folder structure was wrong, the logging was inconsistent with the rest of the service, and the error responses did not match our API contract.
I had explained all of that to Copilot myself, in chat, two weeks earlier, on a different feature. The knowledge existed. It just lived in my head and in a throwaway prompt that nobody could reuse.
That is the quiet tax most teams are paying right now. We explain the same architecture rules, the same coding standards, and the same patterns to our AI assistant every single day, in every session, and none of it sticks. GitHub Copilot Skills are the piece that finally fixes this — and they are different enough from prompts and instructions that most tutorials get the distinction wrong.
The real problem I kept hitting
Let me be specific about the pain, because the solution only makes sense once you feel it.
On a normal week I move between three kinds of work: a .NET Web API backend, a Flutter mobile app, and some Azure infrastructure. Each one has its own rules. The backend uses Clean Architecture with CQRS. The Flutter app is feature-first with Riverpod. The Azure side has cost and security rules I do not want anyone guessing about.
With plain Copilot chat, I was re-teaching all of this constantly. Type a long prompt describing our CQRS setup. Get good code. Close the tab. Next morning, start again from zero. The AI had no memory of the method my team had agreed on.
I first tried to solve it with one giant instructions file. That helped, and I still recommend it — I wrote about that in What Is GitHub Copilot Custom Instructions. But a single always-on file has a ceiling. Pack everything into it and two bad things happen: it gets ignored because it is too long, and it burns context tokens on every request even when most of it is irrelevant to the file you are editing.
In short: instructions are always loaded, so they must stay small. But real engineering knowledge is large. Something had to give.
What are GitHub Copilot Skills?
GitHub Copilot Skills are reusable, named capability files that teach Copilot how to do a specific job the way your team does it — loaded on demand, not on every request.
Think of a Skill as a short playbook. It has a name, a clear description of when to use it, step-by-step guidance, code examples, and a checklist of what “done correctly” looks like. In practice it is a SKILL.md file — Markdown with a small YAML header — that lives in your repo under a folder like .github/skills/.
Here is the part that matters and that most write-ups skip. Copilot does not read the full text of every Skill all the time. It reads only the one-line description of each Skill you have. When a task matches a description, it pulls in that full Skill and follows it. When the task does not match, the Skill stays out of the way.
That behaviour is called progressive disclosure, and it is the whole trick. You can have twenty detailed Skills in a repo and pay the token cost of only the two that actually apply to the file in front of you.
A minimal Skill looks like this:
---
name: dotnet-clean-api-feature
description: >
Use when creating or modifying a feature in the .NET Web API backend.
Covers Clean Architecture layers, CQRS handlers, API response contract,
logging, and the required unit tests. Trigger on "new endpoint",
"add feature", "controller", "command", "query".
---
# How we build a Web API feature
## When to use this
Any new or changed endpoint in the Backend.Api project.
## Steps
1. Add the request/response DTOs in Application/Features/{Feature}.
2. Create a Command or Query record plus its handler...
Notice that description field. In a Skill, the description is not decoration. It is the trigger. If it is vague, Copilot never activates the Skill and you will swear the feature is broken. This is the single biggest mistake I see, and I will come back to it.
Why do we need Copilot Skills?
Because knowledge that lives in one senior developer’s prompts is not knowledge the team owns.
Here is the value, stated plainly for both developers and the people who sign off on tooling budgets:
- Stop repeating yourself. Write the CQRS method once. Every developer, in every session, gets it applied automatically.
- Share engineering knowledge. The way Suresh handles idempotency, the way Sumathi structures widget tests — that becomes a file the whole team inherits, not tribal knowledge.
- Keep standards consistent. AI-generated code stops drifting away from your conventions, because the convention travels with the repo.
- Onboard faster. A new joiner’s Copilot already knows your patterns on day one. I have watched this cut the “why is my PR getting so many nitpicks” phase from weeks to days.
- Predictable AI workflow. Same input, same method, same output shape — across the team, not per person.
The business version of this is short: Skills turn AI-assisted software development from an individual productivity trick into an organisational asset.
The evolution: Prompt to Instructions to Skills to Agents
I find it easiest to explain Skills by showing where they sit in the timeline. Each layer solved a limit of the one before it.
PROMPT INSTRUCTIONS SKILLS AGENTS
"do this now" "here is who "here is HOW we "go do the whole
we are, always" do this job, job, and pull in
when relevant" the right skills"
───────────── ───────────────── ───────────────── ──────────────────
one-off always loaded loaded on demand autonomous, multi-step
not reusable small by necessity large & modular uses skills as tools
per developer per repo per capability per task
- Prompt — you type it, you get an answer, it is gone. Great for exploration, useless for consistency.
- Instructions — the always-on repo profile (
copilot-instructions.md/AGENTS.md). Tells Copilot who you are and your top-level rules. Must stay lean because it loads every time. If you want the full treatment on that layer, I covered it in the AGENTS.md pain-points article. - Skills — deep, specific, reusable know-how loaded only when the task matches. This is the missing middle layer.
- Agents — the autonomous worker that takes a goal, plans steps, and calls on Skills the way a senior engineer reaches for a runbook.
The mental model I give my team: Instructions describe your team. Skills describe your team’s methods. Agents do the work using both.
Copilot Skills vs prompts, instructions, AGENTS.md, agents, and extensions
This is the comparison I wish someone had handed me early, because these terms get used interchangeably and they should not be.
| Concept | What it is | Loaded when | Reusable? | Best for |
|---|---|---|---|---|
| Prompt | A single message you type into chat | Only when you send it | No | Quick, one-off questions and exploration |
| Copilot Instructions | Repo-level profile of conventions | Every request, automatically | Yes, but must stay small | Top-level rules: stack, style, hard “never do this” lines |
| AGENTS.md | Cross-tool instructions file for agents | Every agent run | Yes | Shared rules that many AI tools read, not just Copilot |
| Skill (SKILL.md) | Named playbook for one specific job | Only when task matches its description | Yes, and modular | Deep method knowledge: how to build a feature, review, migrate |
| AI Agent | Autonomous worker that plans and executes | When you give it a task | It is the actor, not the knowledge | Multi-step work: implement, test, open a PR |
| Extension | Connects Copilot to an external system/API | When invoked or matched | Yes | Bringing outside data or actions in (Jira, a database, internal API) |
The honest one-line summary of how they fit together: instructions set the baseline, Skills supply the specialised method, extensions bring in outside data or actions, and the agent orchestrates all of it to finish a task.
When would you not reach for a Skill? If the guidance is short and applies to everything, it belongs in instructions, not a Skill. Skills earn their keep when the knowledge is deep, specific, and only relevant sometimes.
Anatomy of a professional Copilot Skill
A weak Skill reads like a prompt someone saved. A strong Skill reads like a runbook a new engineer could follow without asking questions. After writing a fair number of these, here is the shape I settled on.
- Frontmatter —
name(lowercase, hyphenated) and a sharpdescriptionthat names the domain, the capabilities, and the trigger phrases. - Purpose — one sentence on what this Skill produces.
- When to use / when not to use — remove ambiguity so it activates at the right time and stays quiet otherwise.
- Inputs required — what Copilot needs before it starts (feature name, entity, target project).
- Rules and guidelines — the non-negotiables. Layer boundaries, naming, security.
- Workflow — numbered steps, in order.
- Code examples — real, from your codebase, not
Foo/Bar. - Validation checklist — how to confirm the output is correct.
- Expected output — the file list and shape of a correct result.
That checklist section at the end is what separates a Skill that “kind of helps” from one that produces reviewable code. It gives the agent a way to self-check.
Enterprise Skill examples that actually earn their place
Let me show three Skills close to what I run, so this stops being abstract.
A .NET backend Skill
This one enforces our Clean Architecture and CQRS method on the Web API. The pattern behind it is the same one I described in structuring a Minimal API project.
---
name: dotnet-cqrs-feature
description: >
Use when adding or changing a feature in the .NET 10 Web API.
Enforces Clean Architecture layers, MediatR CQRS, FluentValidation,
the ApiResponse<T> contract, structured logging, and xUnit tests.
Trigger: "new endpoint", "add command", "add query", "feature".
---
# Building a Web API feature the way we build it
## Rules (non-negotiable)
- Domain has NO dependency on Application or Infrastructure.
- Every write is a Command; every read is a Query. No logic in controllers.
- Validate inputs with FluentValidation, never inline `if` checks.
- All responses use ApiResponse<T>. Never return raw entities.
- Log with ILogger and structured properties, never string interpolation.
## Workflow
1. DTOs in Application/Features/{Feature}/.
2. Command/Query record + Handler (implements IRequestHandler).
3. Validator for the request.
4. Thin controller action that only sends the request via IMediator.
5. xUnit tests: one happy path, one validation failure, one not-found.
## Example handler
public sealed record CreateOrderCommand(Guid CustomerId, List<OrderLine> Lines)
: IRequest<ApiResponse<OrderDto>>;
public sealed class CreateOrderHandler
: IRequestHandler<CreateOrderCommand, ApiResponse<OrderDto>>
{
private readonly IOrderRepository _repo;
private readonly ILogger<CreateOrderHandler> _logger;
public CreateOrderHandler(IOrderRepository repo, ILogger<CreateOrderHandler> logger)
{
_repo = repo;
_logger = logger;
}
public async Task<ApiResponse<OrderDto>> Handle(
CreateOrderCommand request, CancellationToken ct)
{
var order = Order.Create(request.CustomerId, request.Lines);
await _repo.AddAsync(order, ct);
_logger.LogInformation("Order {OrderId} created for {CustomerId}",
order.Id, request.CustomerId);
return ApiResponse<OrderDto>.Ok(order.ToDto());
}
}
Why this works in production: the handler has one job, dependencies are injected so it is testable, logging uses structured properties (so it is queryable in Application Insights), and the response is wrapped in a contract the mobile app already understands. A common mistake this Skill prevents is business logic leaking into the controller, which is the first thing that makes a codebase hard to test.
A Flutter mobile Skill
Different stack, same idea. This Skill encodes our feature-first structure and state management method.
---
name: flutter-feature-riverpod
description: >
Use when building a screen or feature in the Flutter app.
Enforces feature-first folders, Riverpod state, a repository layer,
Firebase access only through repositories, and widget tests.
Trigger: "new screen", "add feature", "provider", "state".
---
# How we build a Flutter feature
## Rules
- Feature-first: lib/features/{feature}/{data,domain,presentation}.
- UI never calls Firebase directly. Always go through a repository.
- State lives in a Riverpod Notifier, not inside the widget.
- Every notifier has a widget test covering loading, data, and error states.
## Workflow
1. Model in domain/. Repository interface in domain/, impl in data/.
2. Notifier + provider in presentation/state/.
3. Widget consumes the provider with ConsumerWidget.
4. Widget test with ProviderScope overrides for the repository.
The performance rule I always add here: keep build methods cheap and push work into the notifier. I have debugged enough janky Flutter screens to know that most “Flutter is slow” complaints are really “we rebuilt an expensive widget tree on every state change” complaints.
An Azure cloud Skill
For infrastructure, the Skill is less about code and more about guardrails.
---
name: azure-service-baseline
description: >
Use when provisioning or reviewing Azure resources for a service.
Enforces private networking, Managed Identity over keys, cost tier
rules, and diagnostic logging. Trigger: "deploy", "bicep", "azure
resource", "app service", "storage".
---
# Azure baseline for a new service
## Security rules
- No connection strings in config. Use Managed Identity + Key Vault.
- Storage and databases: private endpoints, public access disabled.
- Every resource sends diagnostics to the central Log Analytics workspace.
## Cost rules
- Default App Service to B1 in non-prod; require sign-off for P-tier.
- Turn on auto-shutdown for non-prod compute.
That cost section has saved us real money. On one project we found a forgotten P-tier plan running in a test environment for months. A Skill that defaults non-prod to a cheap tier and flags anything higher would have caught it in the pull request. For the AI side of Azure work, I pair this with the patterns in building RAG on .NET with Azure OpenAI.
How to create effective Copilot Skills
The method that works for me is to build Skills backwards — from a real problem, not from a blank template.
- Start with a recurring engineering problem. Not “let me document CQRS” but “Copilot keeps putting logic in controllers.” The problem defines the Skill’s scope.
- Capture how your best people already solve it. Sit with the pattern that works today and write the steps down. You are converting tribal knowledge into a file.
- Write the description like you are telling a colleague when to grab this. Name the domain, the capability, and the trigger words. This is where activation is won or lost.
- Add real examples from your codebase. Copilot mirrors your examples closely, so use production-shaped ones.
- Define quality checks. A validation checklist turns “looks fine” into “meets our standard.”
- Keep it under about 500 lines. If it grows past that, split reference detail into separate files and keep
SKILL.mdas the map. - Maintain it. A Skill that describes a convention you abandoned is worse than no Skill, because it actively steers new code the wrong way.
Do’s and Don’ts
| Do | Don’t |
|---|---|
| Write a precise, trigger-rich description | Write a vague description and wonder why it never fires |
| Keep one Skill focused on one job | Cram backend, mobile, and cloud into a single mega-Skill |
| Use real code from your repo | Use Foo/Bar toy snippets the AI can’t map to anything |
| Add a validation checklist | Leave “correct output” undefined |
| Version and review Skills in PRs | Keep them on one laptop as personal prompts |
| Update the week a convention changes | Let Skills rot until they lie about your codebase |
Common mistakes developers make
I have made most of these myself, so this list is not theoretical.
Writing a Skill like a saved prompt. A prompt says “do X.” A Skill teaches a repeatable method with steps, examples, and checks. If your Skill is three sentences, it is a prompt wearing a costume.
A weak description. This is number one by a distance. Copilot only sees the description until it decides to activate. “Helper for backend stuff” will never trigger reliably. Name the domain and the trigger phrases.
No expected output. If the Skill never says what a correct result looks like, you get code that is confident and wrong. Always end with the file list and shape you expect.
One Skill trying to do everything. A 900-line Skill covering your whole platform loads slowly, triggers on the wrong tasks, and is painful to maintain. Split by job.
No validation and no testing. Treat Skills like code. Try them on a real task, see what the agent produces, and tighten the wording. A Skill you never tested is a guess.
Never updating them. Conventions move. If the Skill does not move with them, it becomes a source of bad code that looks official.
Before and after: the real workflow change
Here is the honest picture of how a feature gets built, on the same team, with and without Skills.
BEFORE
Developer → search internal docs → try to remember the pattern →
write code from memory → open PR → reviewer catches the drift →
rework → merge. (Knowledge lives in people. Consistency is luck.)
AFTER
Developer states the goal → Copilot Skill supplies the method →
agent generates the solution → validation checklist confirms standards →
PR matches conventions on the first pass → merge.
(Knowledge lives in the repo. Consistency is the default.)
The gain is not only speed, though the speed is real. The bigger win is that the review conversation moves up a level. Instead of “you put logic in the controller again,” we discuss the actual design. That is a better use of a senior engineer’s afternoon.
Production reality: what to watch
A few things I would tell any team before they roll Skills out widely.
- Token budget is finite. Skills help because they load on demand, but a badly scoped Skill that triggers on everything undoes that benefit. Watch which Skills activate.
- Skills are code you ship. Review them in pull requests. A wrong security rule in a Skill can spread a bad pattern faster than a human ever could.
- Ownership matters. Give each Skill an owner, the same way you own a service. Orphaned Skills rot.
- Measure activation, not just existence. A Skill nobody’s tasks trigger is dead weight. If it never fires, the description is wrong or the Skill is unnecessary.
The future I see coming
Here is where this goes, and it is closer than it sounds.
Skills turn into organisational knowledge assets. The way your company builds software — its architecture, its security posture, its testing culture — stops living only in senior heads and starts living in versioned files that every AI agent on the team reads. New services inherit the accumulated judgement of everyone who came before, automatically.
Teams will build their own libraries of Skills the way they build shared component libraries today. A platform team will publish Skills the same way it publishes SDKs. And the developers who thrive will not be the fastest typists. They will be the ones who are best at teaching machines how their team builds.
Key takeaways
- Skills are the missing middle layer between always-on instructions and autonomous agents.
- They load on demand via progressive disclosure, so deep knowledge no longer costs you tokens on every request.
- The description is the trigger — get it sharp or the Skill never fires.
- One Skill, one job. Split by capability, keep each under about 500 lines.
- Ship them like code: version, review, own, and maintain them.
- Skills convert tribal knowledge into a team asset the whole organisation inherits.
Frequently asked questions
What are GitHub Copilot Skills?
Reusable capability files, usually a SKILL.md with a small YAML header, that teach Copilot how to do a specific job the way your team does it. Copilot reads each Skill’s description and loads the full Skill only when a task matches.
How are Skills different from prompts and instructions? A prompt is one-off. Instructions are always loaded and must stay small. A Skill is deep, reusable, and loaded only when relevant — the specialised method between the two.
Can I use Skills in enterprise projects? Yes, and they shine there. Because they live in the repo, they are version-controlled, reviewed in pull requests, and shared across the team, which is exactly what enterprise standards need.
How do Skills work with AI Agents? The agent is the worker; the Skill is the playbook. An agent inspects available Skills, activates the ones whose descriptions match the task, and follows their steps to finish the job.
What is the best way to start? Pick one recurring problem your team keeps re-explaining to Copilot. Write a single focused Skill for it, with real code and a validation checklist. Test it on a live task. Then grow the library from there.
Conclusion
If you take one thing from this: stop paying the repetition tax. Every time you explain your architecture to Copilot in a throwaway prompt, that knowledge dies when you close the tab. A Skill makes it permanent, shared, and reusable.
Start small this week. One Skill, one real problem, tested on one feature. Watch how the review conversation changes. Then ask your team to add the next one.
Because the shape of this job is changing. Tomorrow’s developers will not only write code. They will teach AI systems how their teams build software — and the teams who learn that skill first will move differently from everyone else.
Sources and further reading: