Six scenes, sixty seconds. The full playbook — calculator, real workflows, pricing — is one click away.
Or scroll through the six scenesEach turn, Copilot quietly assembles a packet and sends it to the model. The thing you typed is the thin slice on the right. Everything else is automatic — but you pay for all of it.
copilot-instructions.mdEach switch is one habit. Flip it on and its impact rolls up into your ESTIMATED BENEFITS on the right. Try the first switch — benefits climb as you stack habits.
The chat habits in Scene 2 are the half you control by hand. The other half is the customization system itself —
instructions, prompts, skills, agents, hooks.
They sort into six tiers by when they load — i.e. how often they get sent to the model. Top tier rides along on every request; bottom tier may never be sent at all.
instructionsMarkdown files Copilot reads as standing rules. copilot-instructions.md loads every turn; *.instructions.md with applyTo: loads only when matching files are in context.
promptsReusable prompt templates you trigger with /name in chat. Think saved macros for recurring tasks — loaded only when you call them.
/review-pr, /write-test, /refactor-to-hooksskillsBundled know-how (a short description + a longer body). The model reads the description on every turn and pulls in the body only when it decides the skill is relevant.
agentsCustom chat personas with their own system prompt + tool set, invoked via @name. Subagents are spawned by the model; only their summary returns — cheap context-wise.
@security-reviewer, @db-migration-experthooksScripts that run on editor events (save, commit, edit) — outside the model. Never sent to the model; great for lint, format, or auto-running tests.
prettier on save, pytest on commit.MCP toolsExternal tools (servers) the model can call mid-conversation — databases, GitHub, browsers, your own APIs. Like skills but they do things instead of just adding context.
copilot-instructions.md, skill descriptions*.instructions.md with applyTo:/name), custom agents (@name)copilot-instructions.md sent every turn can easily cost less than
a giant skill body the model pulls in occasionally. Use this ladder to decide where to put something; measure
your own usage to know what it costs.
copilot-instructions.md (or *.instructions.md for specific files)/name) or custom agent (@name)The single highest-leverage habit is also the easiest: attach the narrowest scope that lets the model answer.
#codebase only when narrower scopes have actually failed.
Both snippets do the same job: give the model less to read, and keep it the same each turn. Save one as a file so it gets cached and reused. Paste the other into chat to point the model at just this task. Steal them.
# Project: payments-service Stack: TypeScript · Node 20 · Fastify · Postgres · Vitest Style: Functional core, async/await, no classes unless modelling an entity. Prefer `Result<T,E>` over throwing. Tests: Vitest, co-located `*.test.ts`. Aim for behavioural tests, not implementation. Use builders, not fixtures. Don't: - Don't add new dependencies without flagging it. - Don't generate migrations — I write those by hand. - Don't touch `src/legacy/*` unless explicitly asked. Do: - When fixing a bug, write the failing test first. - When unsure, ask one clarifying question.
# Task <one sentence: what should be true when you're done> # Scope - Files I think are relevant: #file:... #file:... - Don't touch: ... # Constraints - <any non-obvious behaviour, perf budget, API surface> # Plan first Outline your approach in 3–5 bullets before writing code. If anything is ambiguous, ask one question and stop.
# Task Webhook retries should give up after 5 attempts instead of looping forever. # Scope - Files I think are relevant: #file:src/webhooks/retry.ts #file:src/webhooks/retry.test.ts - Don't touch: src/legacy/*, the queue config. # Constraints - Must keep the existing exponential backoff. - No new dependencies. # Plan first Outline your approach in 3–5 bullets before writing code. If anything is ambiguous, ask one question and stop.
.github/instructions/typescript.instructions.mdFrontmatter-scoped via applyTo. Only loaded when matching files are in context, so it doesn’t ride every turn.
--- applyTo: "**/*.ts" --- # TypeScript rules - Always include explicit return types on exported functions. - Prefer `readonly` arrays and `Readonly<T>` for function parameters. - Use discriminated unions over enums. - Errors at module boundaries return `Result<T, E>`. Throw only in top-level HTTP handlers and test setup. - No `console.log` in committed code — use the shared `logger`.
You can have several: python.instructions.md (applyTo: "**/*.py"), sql.instructions.md (applyTo: "**/migrations/**/*.sql"). Narrow globs > broad ones.
.github/prompts/review-pr.prompt.mdFor bulky reusable how-tos. You invoke it deliberately with /review-pr, so it doesn’t ride every turn.
---
mode: agent
description: Review the current diff against project conventions.
---
You are reviewing the working copy of this repository.
Focus on:
1. Conformance to TypeScript rules in `.github/instructions/typescript.instructions.md`.
2. Test coverage for new behaviors.
3. Error handling — anything thrown that should be a `Result` instead.
Procedure:
- Read `#changes`.
- For each modified file, list issues as `- file:line — issue — suggested fix`.
- End with a 1–2 sentence summary verdict.
Do not propose edits outside the scope of the diff.
Fix the bug in #selection. Expected: <one sentence> Actual: <one sentence> Don't change unrelated code. Don't add error handling for cases that can't happen.
Refactor #file to extract the validation logic into a separate function. Keep the public API unchanged. Run nothing — just propose the diff.
Review #changes. Flag: bugs, accidental scope creep, missing tests. Skip: style nits the linter already catches.
Summarize what we've decided so far in this chat in <=10 bullet points. I'm going to paste that into a fresh chat. Don't propose further changes.
Official docs. Behavior changes; these stay current.
copilot-instructions.md, *.instructions.md, .prompt.md.Don't memorise rules — internalise principles. These four cover the bulk of token waste; everything else is a refinement.
One toggle, set once. Copilot routes each turn to the best-fit model and applies a documented ~10% token-multiplier discount — the single highest-leverage thing you can do.
MODELAttach the file or selection that matters, not the whole repo. Less for the model to read = fewer input tokens, less reasoning effort, tighter answers.
CONTEXTA sub-200-line copilot-instructions.md that doesn't change between turns gets cached — you stop paying full price for the same prefix every message.
History compounds — every old turn rides along on the new one. Start a new chat when the task changes, or run /compact to summarise and shed tokens without losing the thread.
You've seen the levers. Now build the muscle. Start with the official GitHub course — it walks you through the same patterns hands-on, in a real repo, in about an hour.
This page is the quick guide. The advanced scenarios walk through real workflows, an interactive token calculator, the full lever playbook, pricing comparisons, and a live diagram of how context flows. This is not optional reading.
Open advanced scenarios