GitHub CopilotVS CodeAIProductivityMCP

在 VS Code 中自定义 GitHub Copilot

Sloth255
Sloth255
·4 min read·744 words

介绍

在使用 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 进行日志记录

启用设置

  1. 在 VS Code 设置中启用 Chat > Use Instruction Files
  2. 或在 settings.json 中添加:
{
  "github.copilot.chat.codeGeneration.useInstructionFiles": true
}

自动生成功能

VS Code 可以分析工作区并自动生成适当的指令文件:

  1. 在聊天视图中点击齿轮图标
  2. 选择 "Generate Chat Instructions"
  3. 审阅并编辑生成的文件

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. **编码标准**:是否符合项目规范

提供带有具体代码示例的改进建议。

如何使用提示文件

  1. 从命令面板Chat: Run Prompt → 选择提示
  2. 在聊天输入中:使用 /create-react-component 等斜杠命令执行
  3. 从编辑器:打开 .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. 实现响应式支持

实施后始终在浏览器中预览,验证功能。

如何使用自定义代理

  1. 在聊天视图中打开代理选择器
  2. 选择自定义代理
  3. 定义的工具和指令将被应用

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 服务器管理

  1. 服务器列表:命令面板 → MCP: List Servers
  2. 工具选择:在代理模式中点击工具图标
  3. 自动批准:为受信任的工具配置自动批准

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 简单代码生成、快速问答 快速且具成本效益

切换模型

  1. 点击聊天输入旁边的模型选择器
  2. 选择适合任务的模型
  3. 所选模型将应用于当前会话

使用自定义模型(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 服务器
为不同任务使用最优模型 语言模型

参考资料