介绍
在使用 GitHub Copilot 进行随意编码时,你可能经常会遇到不便。例如,可能会出现以下情况:
- 编码规范不匹配
// Copilot 生成的代码
function getUserData(id) { // ❌ 虽然要求 TypeScript 但没有类型
return fetch('/api/users/' + id) // ❌ 应该使用模板字面量
}
// 遵循团队规范的正确代码
async function getUserData(id: string): Promise<UserData> {
return await fetch(`/api/users/${id}`)
}
- 反复解释相同的内容
开发者:"创建一个 React 组件"
GitHub Copilot:"生成了一个类组件"
开发者:"不,使用函数组件,要有 TypeScript,并且要有 props 的类型定义……"
# 下一个组件也是……
开发者:"再创建一个组件……"
GitHub Copilot:"这是一个类组件……"
开发者:"我说了要函数组件!"
- 缺乏项目特定知识
开发者:"帮我实现用户认证"
Copilot:"我来建议使用 JWT 的通用实现"
开发者:"我们用 Auth0……"
Copilot:"明白了。我来实现 Auth0……"
开发者:"而且我们有内部认证流程……"
GitHub Copilot 是出色的编码助手,但使用默认设置时,它无法完全适应你的团队开发风格或项目特定需求。
本文将介绍 VS Code 中 GitHub Copilot 的自定义功能,包括自定义指令、提示文件、自定义代理、代理技能和 MCP 服务器集成,并附实用示例代码。
示例参考自:https://code.visualstudio.com/docs/copilot/customization/overview
自定义概述
VS Code 中的 GitHub Copilot 提供了六种主要自定义方法:
| 自定义方法 | 主要用途 | 特性与范围 |
|---|---|---|
| 自定义指令 | 定义编码标准和开发指南 | 所有聊天请求或特定文件类型 |
| 代理技能 | 传授专业工作流和能力 | 定义可复用的专业知识(可跨代理共享) |
| 提示文件 | 可复用的任务特定提示 | 按需执行 |
| 自定义代理 | 角色专用助手 | 选择聊天模式时应用 |
| 语言模型 | 任务优化的 AI 模型选择 | 通过模型选择器切换 |
| MCP 服务器 | 与外部服务及工具集成 | 在代理模式下可用 |
1. 自定义指令 — 统一编码规范
基本设置
自定义指令是为整个项目或特定文件类型定义 Copilot 行为策略的功能。
应用于整个工作区的设置
.github/copilot-instructions.md
# 项目范围编码指南
## 代码风格
- 使用语义化 HTML5 元素(header, main, section, article)
- 优先使用现代 JavaScript 特性(const/let, 箭头函数, 模板字面量)
- 始终包含 TypeScript 类型定义
## 命名规范
- 组件名、接口、类型别名:PascalCase
- 变量、函数、方法:camelCase
- 私有类成员:下划线前缀(_)
- 常量:ALL_CAPS
## 代码质量
- 使用有意义的变量和函数名
- 为复杂逻辑添加注释
- 为用户输入和 API 调用实现错误处理
- 优先使用 async/await 而非回调
## 安全性
- 永远不要硬编码敏感信息
- 始终验证输入值
- 使用占位符防止 SQL 注入
语言和框架特定设置
对于特定文件模式,在 frontmatter 中指定 applyTo。
.github/instructions/react.instructions.md
---
applyTo: "**/*.tsx"
---
# React 开发指南
- 优先使用函数组件而非类组件
- 利用自定义 hooks 分离状态管理逻辑
- 始终使用 TypeScript 接口定义 props
- 使用 Tailwind CSS 工具类进行样式设置
- 必要时使用 React.memo 进行记忆化
.github/instructions/backend.instructions.md
---
applyTo: "src/server/**/*.ts"
---
# 后端开发指南
- 将控制器放在 `src/controllers/`
- 将服务逻辑放在 `src/services/`
- 使用存储库模式实现数据访问
- 从 `.env` 加载环境变量
- 使用中间件集中处理错误
- 使用 Winston 进行日志记录
启用设置
- 在 VS Code 设置中启用
Chat > Use Instruction Files - 或在
settings.json中添加:
{
"github.copilot.chat.codeGeneration.useInstructionFiles": true
}
自动生成功能
VS Code 可以分析工作区并自动生成适当的指令文件:
- 在聊天视图中点击齿轮图标
- 选择 "Generate Chat Instructions"
- 审阅并编辑生成的文件
2. 提示文件 — 可复用的任务模板
提示文件允许你将频繁执行的开发任务模板化,并在团队中共享。
示例 1:React 组件生成
.github/prompts/create-react-component.prompt.md
---
agent: 'agent'
model: 'GPT-4o'
tools: ['search/codebase']
description: '生成 React 组件'
---
按以下要求生成 React 组件:
组件名称:${input:componentName:输入组件名称}
Props:${input:props:逗号分隔输入 props(例如:title, onClick, isDisabled)}
## 生成规则
- 使用 TypeScript 实现
- 使用函数组件
- 使用接口定义 props
- 使用 Tailwind CSS 进行样式设置
- 根据需要使用 React Hooks 管理状态
- 使用 JSDoc 注释记录 props
示例 2:API 路由生成
.github/prompts/create-api-route.prompt.md
---
agent: 'agent'
description: '生成 RESTful API 路由'
---
为以下实体生成 CRUD API:
实体名称:${input:entity:实体名称}
字段:${input:fields:逗号分隔指定字段}
## 实现要求
- 使用 Express.js
- 使用 TypeScript 实现
- 将路由器放在 `src/routes/`
- 将控制器放在 `src/controllers/`
- 使用 express-validator 进行验证
- 实现适当的错误处理
- 使用标准 JSON 响应格式
示例 3:测试用例生成
.github/prompts/generate-tests.prompt.md
---
agent: 'agent'
tools: ['search/codebase']
description: '自动生成单元测试'
---
选中的代码:${selection}
为上述代码生成全面的单元测试。
## 测试要求
- 使用 Jest
- 最大化测试覆盖率
- 覆盖正常和错误情况
- 考虑边界情况
- 适当使用模拟和存根
- 为每个测试用例编写描述性的 describe/it 语句
示例 4:代码审查
.github/prompts/code-review.prompt.md
---
agent: 'agent'
description: '进行代码审查'
---
选中的代码:${selection}
从以下角度进行代码审查:
## 审查角度
1. **安全性**:是否存在漏洞
2. **性能**:优化机会
3. **代码质量**:可读性、可维护性
4. **错误处理**:适当的异常处理
5. **可测试性**:易于测试
6. **编码标准**:是否符合项目规范
提供带有具体代码示例的改进建议。
如何使用提示文件
- 从命令面板:
Chat: Run Prompt→ 选择提示 - 在聊天输入中:使用
/create-react-component等斜杠命令执行 - 从编辑器:打开
.prompt.md文件,点击标题栏中的播放按钮
3. 代理技能 — 可移植的 AI 功能扩展
代理技能是可以在 VS Code、GitHub Copilot CLI 和 Copilot 编码代理中通用使用的开放标准。
代理技能结构
.github/skills/
├── webapp-testing/
│ ├── SKILL.md
│ └── example-test.spec.ts
└── github-actions-debugging/
├── SKILL.md
└── troubleshooting-guide.md
示例 1:Playwright 测试生成
.github/skills/webapp-testing/SKILL.md
---
name: webapp-testing
description: 使用 Playwright 生成 E2E 测试。当需要测试用户交互时使用此功能。
---
# 使用 Playwright 进行 Web 应用测试
此技能支持使用 Playwright 生成端到端(E2E)测试。
## 测试生成规则
1. **选择器优先级**:
- 优先使用 `getByRole`
- 其次 `getByLabel`
- 最后不得已使用 `getByTestId`
2. **测试结构**:
- 每个测试应可独立执行
- 实现适当的 setup/teardown
- 编写清晰的断言
3. **最佳实践**:
- 使用页面对象模型模式
- 等待是隐式执行的
- 仅在失败时截图
## 模板示例
基于以下 example-test.spec.ts 生成测试。
```typescript
import { test, expect } from '@playwright/test';
test('user can log in successfully', async ({ page }) => {
await page.goto('/login');
await page.getByRole('textbox', { name: 'Email' }).fill('user@test.com');
await page.getByRole('textbox', { name: 'Password' }).fill('password123');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL('/dashboard');
await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
});
### 示例 2:GitHub Actions 调试
`.github/skills/github-actions-debugging/SKILL.md`
```markdown
---
name: github-actions-failure-debugging
description: 调试 GitHub Actions 工作流失败。当 CI 失败时使用此功能。
---
# GitHub Actions 失败调试
此技能提供调试 GitHub Actions 工作流失败的高效流程。
## 调试流程
当调试 Pull Request 上失败的 GitHub Actions 工作流时,请按以下步骤操作:
1. **检查工作流执行状态**
- 使用 `list_workflow_runs` 工具检查 PR 的最近执行和状态
2. **获取日志摘要**
- 使用 `summarize_job_log_failures` 工具获取失败作业日志的 AI 摘要
- 不会占用大量上下文窗口即可了解问题
3. **确定根本原因**
- 从错误消息中分类问题类型:
* 依赖项问题
* 测试失败
* 构建错误
* 权限错误
* 超时
4. **提出解决方案**
- 为识别的问题提供具体修复
- 根据需要建议工作流文件修改
## 常见问题及解决方案
### 依赖项问题
- Node.js 版本不匹配
- 包安装失败
→ 检查 `package-lock.json`,清除缓存
### 测试失败
- 缺少环境变量
- 测试数据问题
→ 验证环境变量设置,校验测试种子数据
### 权限错误
- GITHUB_TOKEN 权限不足
- 密码配置不正确
→ 检查仓库设置中的权限和密码
代理技能的优势
- 可移植性:在 VS Code、CLI 和编码代理中通用
- 上下文理解:Copilot 自动加载相关技能
- 团队共享:将知识包含在仓库中进行共享
- 开放标准:符合 agentskills.io
4. 自定义代理 — 角色专用助手
自定义代理定义专门针对特定角色或任务的聊天模式。
示例 1:仅规划代理
.github/agents/planner.md
---
name: 'planner'
description: '专注于实施前规划的代理'
tools:
- 'search/codebase'
- 'githubRepo'
toolsets:
- 'read-only'
model: 'GPT-4o'
---
# 实施规划代理
你是专注于创建实施计划的代理。你不编写代码,只创建实施计划。
## 职责
1. **需求分析**:详细分析用户需求
2. **影响调查**:确定需要更改的文件和组件
3. **任务分解**:将实施分解为小任务
4. **风险识别**:识别潜在问题
## 计划格式
### 1. 概述
[实施目的和预期结果]
### 2. 影响范围
- 需要更改的文件列表
- 受影响的组件
### 3. 实施步骤
1. [步骤 1 的详情]
- 所需更改
- 注意事项
2. [步骤 2 的详情]
...
### 4. 测试策略
- 单元测试目标
- E2E 测试场景
### 5. 风险与对策
| 风险 | 对策 |
|------|----------------|
| ... | ... |
计划批准后,移交给实施代理。
示例 2:安全审查代理
.github/agents/security-reviewer.md
---
name: 'security-reviewer'
description: '从安全角度审查代码的代理'
tools:
- 'search/codebase'
model: 'Claude Sonnet 3.5'
---
# 安全审查代理
你是作为安全专家检测代码漏洞的代理。
## 审查项目
### 1. 认证与授权
- [ ] 适当的认证机制实现
- [ ] 无授权检查漏洞
- [ ] 会话管理安全性
### 2. 输入验证
- [ ] 净化所有用户输入
- [ ] SQL 注入对策
- [ ] XSS 对策
- [ ] CSRF 对策
### 3. 数据保护
- [ ] 无硬编码的敏感信息
- [ ] 适当使用加密
- [ ] 不向日志输出敏感信息
### 4. 依赖项
- [ ] 使用已知漏洞的包
- [ ] 建议更新到最新版本
### 5. API 安全
- [ ] 速率限制实现
- [ ] 适当的 CORS 配置
- [ ] 安全的 API 密钥管理
## 报告格式
对于每个检测到的问题,请报告:
- **严重性**:严重 / 高 / 中 / 低
- **描述**:问题是什么
- **影响**:被利用时的影响
- **修复方法**:具体代码示例
严重/高漏洞需要立即修复。
示例 3:前端开发代理
.github/agents/frontend-dev.md
---
name: 'frontend-dev'
description: '专注于前端开发的代理'
tools:
- 'search/codebase'
- 'terminal'
- 'edit'
model: 'GPT-4o'
---
# 前端开发代理
你是使用 React/TypeScript/Tailwind CSS 进行前端开发的专家。
## 开发原则
### 组件设计
- 优先考虑可复用性
- 遵循单一职责原则
- 保持 props 最小化
- 适当的抽象级别
### 状态管理
- 使用 useState/useReducer 管理本地状态
- 将全局状态保持在最低必要程度
- 防止不必要的重渲染
### 样式
- 使用 Tailwind CSS 工具类
- 最小化自定义 CSS
- 以移动优先实现响应式设计
### 性能
- 使用 React.memo 防止不必要的重渲染
- 使用 useCallback 记忆化回调
- 使用 useMemo 缓存重度计算
- 优化图片(next/image 等)
## 实施流程
1. 明确组件职责
2. 定义 props 接口
3. 设计状态管理
4. 实现 JSX 结构
5. 应用样式
6. 验证可访问性(ARIA 属性)
7. 实现响应式支持
实施后始终在浏览器中预览,验证功能。
如何使用自定义代理
- 在聊天视图中打开代理选择器
- 选择自定义代理
- 定义的工具和指令将被应用
5. MCP(Model Context Protocol)— 外部服务集成
MCP 是一个开放标准,用于 Copilot 与数据库和 API 等外部服务集成。
MCP 服务器配置
工作区配置
.vscode/mcp.json
{
"inputs": [
{
"type": "promptString",
"id": "github-token",
"description": "GitHub Personal Access Token",
"password": true
},
{
"type": "promptString",
"id": "db-connection",
"description": "Database Connection String",
"password": true
}
],
"servers": {
"github-server": {
"type": "http",
"url": "https://github-mcp.com",
"headers": {
"Authorization": "Bearer ${input:github-token}"
}
},
"database-server": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-postgres"],
"env": {
"DATABASE_URL": "${input:db-connection}"
}
},
"filesystem-server": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
}
}
}
用户配置
在 settings.json 中定义全局使用的 MCP 服务器:
{
"chat.mcp.servers": {
"perplexity-search": {
"type": "http",
"url": "https://perplexity-mcp.com/api",
"env": {
"PERPLEXITY_API_KEY": "${env:PERPLEXITY_API_KEY}"
}
},
"slack-integration": {
"command": "docker",
"args": ["run", "-i", "slack-mcp-server"],
"env": {
"SLACK_TOKEN": "${env:SLACK_BOT_TOKEN}"
}
}
}
}
实现示例 1:使用 GitHub MCP 服务器
# 提示示例
@agent 从 GitHub 仓库 contoso/my-app 获取最近的 issue,
并按优先级顺序列出。
# Copilot 的操作
1. 调用 GitHub MCP Server 的 `list_issues` 工具
2. 按优先级排序检索到的 issue
3. 以 markdown 格式响应
实现示例 2:使用数据库 MCP 服务器
# 提示示例
从数据库检索所有用户,
并汇总活跃用户数量。
# Copilot 的操作
1. 执行 Database MCP Server 的 `query` 工具
2. SQL: SELECT COUNT(*) FROM users WHERE is_active = true
3. 格式化并显示结果
实现示例 3:创建自定义 MCP 服务器
使用 Node.js 创建简单的 MCP 服务器:
// custom-mcp-server/index.ts
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new Server(
{
name: "custom-api-server",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// 工具定义
server.setRequestHandler("tools/list", async () => {
return {
tools: [
{
name: "fetch_user_data",
description: "获取用户数据",
inputSchema: {
type: "object",
properties: {
userId: { type: "string", description: "用户 ID" },
},
required: ["userId"],
},
},
],
};
});
// 工具执行
server.setRequestHandler("tools/call", async (request) => {
if (request.params.name === "fetch_user_data") {
const userId = request.params.arguments?.userId;
// API 请求实现
const response = await fetch(`https://api.example.com/users/${userId}`);
const data = await response.json();
return {
content: [{ type: "text", text: JSON.stringify(data, null, 2) }],
};
}
throw new Error("Unknown tool");
});
// 启动服务器
const transport = new StdioServerTransport();
await server.connect(transport);
package.json:
{
"name": "custom-mcp-server",
"type": "module",
"dependencies": {
"@modelcontextprotocol/sdk": "latest"
},
"bin": {
"custom-mcp-server": "./index.js"
}
}
MCP 服务器管理
- 服务器列表:命令面板 →
MCP: List Servers - 工具选择:在代理模式中点击工具图标
- 自动批准:为受信任的工具配置自动批准
6. 实际集成示例
用例:微服务开发项目
目录结构
my-microservice/
├── .github/
│ ├── copilot-instructions.md # 整体开发标准
│ ├── instructions/
│ │ ├── backend.instructions.md # 后端特定
│ │ ├── frontend.instructions.md # 前端特定
│ │ └── infra.instructions.md # 基础设施特定
│ ├── agents/
│ │ ├── planner.md # 规划代理
│ │ ├── implementer.md # 实施代理
│ │ ├── reviewer.md # 审查代理
│ │ └── deployer.md # 部署代理
│ ├── skills/
│ │ ├── api-testing/
│ │ │ ├── SKILL.md
│ │ │ └── sample-api-test.ts
│ │ └── k8s-deployment/
│ │ ├── SKILL.md
│ │ └── deployment-template.yaml
│ └── prompts/
│ ├── create-service.prompt.md
│ ├── add-endpoint.prompt.md
│ └── generate-migration.prompt.md
└── .vscode/
└── mcp.json # MCP 配置
工作流示例
1. 规划新功能
# 向 @planner 代理的请求
我想添加用户认证功能。
使用 OAuth 和基于 JWT 令牌的认证实现。
2. 委托实施
计划批准后,移交给实施代理:
# 使用 @implementer 代理实施
基于上述计划,实施认证中间件。
3. 自动生成测试
# 使用提示文件
/generate-tests
4. 安全审查
# 使用 @security-reviewer 代理验证
对实施的认证中间件进行安全审查。
5. 部署准备
# 利用 MCP + K8s 技能
@agent 使用 kubernetes-skill 为认证服务生成部署配置。
7. 语言模型 — 任务特定的模型选择
模型选择策略
在 VS Code 中,你可以为每个任务选择最优的 AI 模型。以下是一些示例(注意新模型每天都在发布,下面的信息可能会过时):
| 模型 | 推荐用途 | 特性 |
|---|---|---|
| GPT-4o | 复杂实施、架构设计 | 高推理能力 |
| Claude Sonnet 3.5 | 代码审查、重构 | 宽上下文窗口 |
| GPT-4o-mini | 简单代码生成、快速问答 | 快速且具成本效益 |
切换模型
- 点击聊天输入旁边的模型选择器
- 选择适合任务的模型
- 所选模型将应用于当前会话
使用自定义模型(BYOK:自带密钥)
settings.json:
{
"github.copilot.chat.models": [
{
"id": "my-custom-model",
"name": "Custom GPT-4",
"endpoint": "https://api.openai.com/v1/chat/completions",
"apiKey": "${env:OPENAI_API_KEY}",
"model": "gpt-4-turbo-preview"
},
{
"id": "local-llm",
"name": "Local LLaMA",
"endpoint": "http://localhost:8080/v1/chat/completions",
"model": "llama-3-70b-instruct"
}
]
}
8. 最佳实践
1. 逐步采用
第 1 周:设置自定义指令
第 2 周:将常见任务转换为提示文件
第 3 周:试验性引入自定义代理
第 4 周:通过 MCP 服务器进行外部集成
2. 团队共享
- 将自定义指令和提示文件提交到仓库
- 将代理技能放在
.github/skills/ - 在
.vscode/mcp.json中管理项目特定的 MCP 配置
3. 安全性
// 使用环境变量管理 API 密钥
{
"chat.mcp.servers": {
"secure-api": {
"env": {
"API_KEY": "${env:MY_API_KEY}" // 不要硬编码
}
}
}
}
4. 性能优化
- 禁用不必要的工具以节省上下文
- 将大型提示文件拆分为更小的文件
- 调整 MCP 服务器超时设置
5. 文档化
# team-wiki/copilot-usage.md
## 自定义代理使用方法
- `@planner`:实施前规划
- `@implementer`:代码实施
- `@reviewer`:代码审查
- `@deployer`:部署工作
## 提示文件快速参考
- `/create-component`:生成 React 组件
- `/add-api-route`:添加 API 端点
- `/generate-tests`:自动生成测试代码
总结
通过利用 GitHub Copilot 的自定义功能,你可以构建适合团队开发风格的 AI 助手。
此外,当前的功能选择策略大概是:
| 想要做的事 | 使用的功能 |
|---|---|
| 统一编码标准 | 自定义指令 |
| 自动化重复任务 | 提示文件 |
| 创建专业 AI 助手 | 自定义代理 |
| 跨 AI 工具共享技能 | 代理技能 |
| 与外部 API 和数据库集成 | MCP 服务器 |
| 为不同任务使用最优模型 | 语言模型 |
