|
| 1 | +--- |
| 2 | +name: make-custom-agent |
| 3 | +description: 'Create custom GitHub Copilot agents. Use when asked to create, scaffold, or configure a custom agent, declarative agent, or @-invokable chat participant for GitHub Copilot.' |
| 4 | +--- |
| 5 | + |
| 6 | +# Create Custom Agent |
| 7 | + |
| 8 | +This skill guides you through creating a custom GitHub Copilot agent — an `@`-invokable chat participant that extends Copilot with domain-specific expertise. Custom agents are distinct from Agent Skills: skills provide reusable instructions loaded on demand, while agents own the full conversational interaction and can orchestrate tools, call APIs, and maintain their own prompt strategies. |
| 9 | + |
| 10 | +## When Not to Use |
| 11 | + |
| 12 | +- Adding reusable, invokable workflows — use Agent Skills (`.agents/skills/`) instead |
| 13 | +- Adding background coding guidelines — use file-based instructions (`.github/instructions/`) instead |
| 14 | +- Adding project-wide context for Copilot — use `.github/copilot-instructions.md` instead |
| 15 | +- Creating reusable prompts — use .prompt.md instead |
| 16 | + |
| 17 | +## Workflow |
| 18 | + |
| 19 | +### Step 1: Choose the agent type |
| 20 | + |
| 21 | +| Type | Location | Best for | |
| 22 | +|---|---|---| |
| 23 | +| Declarative (prompt file) | `.github/agents/<name>.md` | Simple prompt-driven cross-surface agents with no code | |
| 24 | +| Extension-based (chat participant) | VS Code extension project | Full control, tool calling, VS Code API access | |
| 25 | +| GitHub App (Copilot Extension) | Hosted service + GitHub App | Cross-surface agents (github.com, VS Code, Visual Studio) | |
| 26 | + |
| 27 | +If the agent only needs a scoped system prompt and doesn't require custom code, start with a declarative agent. |
| 28 | + |
| 29 | +### Step 2: Create a declarative agent (prompt file) |
| 30 | + |
| 31 | +Declarative agents are Markdown files in `.github/agents/`. VS Code and GitHub Copilot discover them automatically. |
| 32 | + |
| 33 | +``` |
| 34 | +.github/agents/ |
| 35 | +└── <agent-name>.md # Agent definition |
| 36 | +``` |
| 37 | + |
| 38 | +Template: |
| 39 | + |
| 40 | +```markdown |
| 41 | +--- |
| 42 | +name: my-agent |
| 43 | +description: A short description of what this agent does and when to use it. |
| 44 | +--- |
| 45 | + |
| 46 | +# <Agent Title> |
| 47 | + |
| 48 | +You are an expert in <domain>. Your job is to: |
| 49 | +- <behavior 1> |
| 50 | +- <behavior 2> |
| 51 | + |
| 52 | +## Guidelines |
| 53 | + |
| 54 | +- <guideline 1> |
| 55 | +- <guideline 2> |
| 56 | + |
| 57 | +## Workflow |
| 58 | + |
| 59 | +1. <step 1> |
| 60 | +2. <step 2> |
| 61 | + |
| 62 | +## Constraints |
| 63 | + |
| 64 | +- <constraint 1> |
| 65 | +- <constraint 2> |
| 66 | + |
| 67 | +``` |
| 68 | + |
| 69 | +Supported frontmatter fields: |
| 70 | + |
| 71 | +| Field | Required | Description | |
| 72 | +|---|---|---| |
| 73 | +| `name` | Yes | Lowercase, hyphens allowed. Used for `@`-mention. | |
| 74 | +| `description` | Yes | What the agent does and when to use it. Shown in the participant list. | |
| 75 | +| `target` | No | Target environment: `vscode` or `github-copilot` (defaults to both) | |
| 76 | +| `tools` | No | List of allowed tools/tool sets | |
| 77 | +| `model` | No | LLM name or prioritized array of models | |
| 78 | +| `user-invocable` | No | Show in agents dropdown (default: true) | |
| 79 | +| `disable-model-invocation` | No | Prevent subagent invocation (default: false) | |
| 80 | +| `mcp-servers` | No | MCP server configs for GitHub Copilot target | |
| 81 | +| `metadata` | No | Key-value mapping for additional arbitrary metadata. | |
| 82 | +| `argument-hint` | No | Hint text guiding user interaction (VS Code only) | |
| 83 | +| `agents` | No | List of allowed subagents (`*` for all, `[]` for none, VS Code only) | |
| 84 | +| `handoffs` | No | List of next-step agent transitions (VS Code only) | |
| 85 | + |
| 86 | + |
| 87 | +Tips for instructions: |
| 88 | +- Use Markdown links to reference other files |
| 89 | +- Reference tools with `#tool:<tool-name>` syntax |
| 90 | +- Be specific about agent behavior and constraints |
| 91 | + |
| 92 | +### Step 3: Configure tools |
| 93 | + |
| 94 | +Specify which tools the agent can use: |
| 95 | + |
| 96 | +```yaml |
| 97 | +tools: |
| 98 | + - search # Built-in tool |
| 99 | + - fetch # Built-in tool |
| 100 | + - codebase # Tool set |
| 101 | + - myServer/* # All tools from MCP server |
| 102 | +``` |
| 103 | +
|
| 104 | +Common tool patterns: |
| 105 | +- **Read-only agents**: `['search', 'fetch', 'codebase']` |
| 106 | +- **Full editing agents**: `['*']` or specific editing tools |
| 107 | +- **Specialized agents**: Cherry-pick specific tools |
| 108 | + |
| 109 | +### Step 4: Add handoffs (optional, VS Code only) |
| 110 | + |
| 111 | +Configure transitions to other agents: |
| 112 | + |
| 113 | +```yaml |
| 114 | +handoffs: |
| 115 | + - label: Start Implementation |
| 116 | + agent: implementation |
| 117 | + prompt: Implement the plan outlined above. |
| 118 | + send: false |
| 119 | + model: GPT-5.2 (copilot) |
| 120 | +``` |
| 121 | + |
| 122 | +Handoff fields: |
| 123 | +- `label`: Button text displayed to user |
| 124 | +- `agent`: Target agent identifier |
| 125 | +- `prompt`: Pre-filled prompt for target agent |
| 126 | +- `send`: Auto-submit prompt (default: false) |
| 127 | +- `model`: Optional model override for handoff |
| 128 | + |
| 129 | +### Step 5: Create an extension-based chat participant (VS Code only) |
| 130 | + |
| 131 | +For full control, implement a VS Code extension with a chat participant: |
| 132 | + |
| 133 | +1. **Define the participant** in `package.json`: |
| 134 | + |
| 135 | +```json |
| 136 | +"contributes": { |
| 137 | + "chatParticipants": [ |
| 138 | + { |
| 139 | + "id": "my-extension.my-agent", |
| 140 | + "name": "my-agent", |
| 141 | + "fullName": "My Agent", |
| 142 | + "description": "Short description shown in chat input", |
| 143 | + "isSticky": false, |
| 144 | + "commands": [ |
| 145 | + { |
| 146 | + "name": "explain", |
| 147 | + "description": "Explain the selected code" |
| 148 | + } |
| 149 | + ] |
| 150 | + } |
| 151 | + ] |
| 152 | +} |
| 153 | +``` |
| 154 | + |
| 155 | +2. **Register and implement the request handler** in `extension.ts`: |
| 156 | + |
| 157 | +```typescript |
| 158 | +export function activate(context: vscode.ExtensionContext) { |
| 159 | + const agent = vscode.chat.createChatParticipant('my-extension.my-agent', handler); |
| 160 | + agent.iconPath = vscode.Uri.joinPath(context.extensionUri, 'icon.png'); |
| 161 | +} |
| 162 | +
|
| 163 | +const handler: vscode.ChatRequestHandler = async ( |
| 164 | + request: vscode.ChatRequest, |
| 165 | + context: vscode.ChatContext, |
| 166 | + stream: vscode.ChatResponseStream, |
| 167 | + token: vscode.CancellationToken |
| 168 | +) => { |
| 169 | + const model = request.model; |
| 170 | + const messages = [ |
| 171 | + vscode.LanguageModelChatMessage.User(request.prompt) |
| 172 | + ]; |
| 173 | + const response = await model.sendRequest(messages, {}, token); |
| 174 | + for await (const fragment of response.text) { |
| 175 | + stream.markdown(fragment); |
| 176 | + } |
| 177 | +}; |
| 178 | +``` |
| 179 | + |
| 180 | +3. **Declare the extension dependency** in `package.json`: |
| 181 | + |
| 182 | +```json |
| 183 | +"extensionDependencies": ["github.copilot-chat"] |
| 184 | +``` |
| 185 | + |
| 186 | +4. **Add tool calling (optional)** |
| 187 | + |
| 188 | +Agents can invoke language model tools registered by other extensions: |
| 189 | + |
| 190 | +```typescript |
| 191 | +const tools = vscode.lm.tools.filter(tool => tool.tags.includes('my-domain')); |
| 192 | +const result = await chatUtils.sendChatParticipantRequest(request, context, { |
| 193 | + prompt: 'You are an expert in <domain>.', |
| 194 | + tools, |
| 195 | + responseStreamOptions: { stream, references: true, responseText: true } |
| 196 | +}, token); |
| 197 | +return await result.result; |
| 198 | +``` |
| 199 | + |
| 200 | +### Step 6: Create a GitHub App (Copilot Extension) for cross-surface availability (optional) |
| 201 | + |
| 202 | +If the agent should be available on GitHub.com, Visual Studio, JetBrains, and VS Code simultaneously, implement a GitHub App that acts as a Copilot Extension. The app registers a webhook endpoint, receives chat requests, and streams responses back. |
| 203 | + |
| 204 | +Key considerations: |
| 205 | +- The GitHub App must be installed on the user's account or organization |
| 206 | +- Responses are streamed via Server-Sent Events (SSE) |
| 207 | +- Use the [GitHub Copilot Extensions documentation](https://docs.github.com/en/copilot/building-copilot-extensions/about-building-copilot-extensions) for the full integration guide |
| 208 | +- For VS Code-specific features (editor access, file trees, command buttons), prefer an extension-based participant instead |
| 209 | + |
| 210 | +### Step 7: Validate |
| 211 | + |
| 212 | +After creating or modifying an agent, verify: |
| 213 | + |
| 214 | +- [ ] `name` is lowercase, uses hyphens (no spaces), and is unique |
| 215 | +- [ ] `description` clearly describes what the agent does and when to invoke it |
| 216 | +- [ ] Frontmatter YAML is valid (no syntax errors) |
| 217 | +- [ ] Declarative agent file is in `.github/agents/` |
| 218 | +- [ ] Tools list contains only available tools |
| 219 | +- [ ] Extension-based agent: participant ID matches in `package.json` and `createChatParticipant` call |
| 220 | +- [ ] Agent does not duplicate functionality of built-in agents (`@workspace`, `@vscode`, `@terminal`) |
| 221 | +- [ ] Handoff agent names match existing agents |
| 222 | +- [ ] Agent instructions don't include secrets, tokens, or internal URLs |
| 223 | + |
| 224 | +## Common Pitfalls |
| 225 | + |
| 226 | +| Pitfall | Solution | |
| 227 | +|---------|----------| |
| 228 | +| Agent name conflicts with built-in participants | Use a unique prefix (domain name) | |
| 229 | +| Description is too vague | Include specific keywords users would naturally say | |
| 230 | +| System prompt is too long | Keep instructions to essential behaviors; move reference material to Agent Skills | |
| 231 | +| Agent requires VS Code API but is authored as declarative | Switch to extension-based participant | |
| 232 | +| Using `isSticky: true` unnecessarily | Only set sticky if the agent should persist between turns by default | |
| 233 | +| No `extensionDependencies` on `github.copilot-chat` | Add it; otherwise the contribution point may not be available | |
| 234 | +| Agent invoked as subagent unexpectedly | Set `disable-model-invocation: true` | |
| 235 | +| Subagent appears in the dropdown | Set `user-invocable: false` | |
| 236 | + |
| 237 | +## References |
| 238 | + |
| 239 | +- [VS Code Chat Participant API](https://code.visualstudio.com/api/extension-guides/ai/chat) |
| 240 | +- [VS Code AI Extensibility Overview](https://code.visualstudio.com/api/extension-guides/ai/ai-extensibility-overview) |
| 241 | +- [VS Code Extension Samples – chat-sample](https://github.com/microsoft/vscode-extension-samples/tree/main/chat-sample) |
| 242 | +- [GitHub Copilot Extensions documentation](https://docs.github.com/en/copilot/building-copilot-extensions/about-building-copilot-extensions) |
| 243 | +- [GitHub Copilot Custom agents configuration](https://docs.github.com/en/copilot/reference/custom-agents-configuration) |
| 244 | +- [Agent Skills Specification](https://agentskills.io/specification) |
| 245 | +- [make-skill](../make-skill/SKILL.md) |
| 246 | +- [make-instructions](../make-instructions/SKILL.md) |
0 commit comments