GitHub Copilot
GitHub Copilot 是 GitHub 开发的 AI 编程助手,提供智能代码补全、聊天辅助和代码解释功能,帮助开发者更快地编写代码。
概述
GitHub Copilot 是一个 AI 编码助手,帮助你更快、更省力地编写代码,让你将更多精力集中在问题解决和协作上。
Copilot 擅长的任务:
- 编写测试和重复性代码
- 调试和纠正语法错误
- 解释和注释代码
- 生成正则表达式
Copilot 不适合的场景:
- 回答与编程和技术无关的问题
- 取代你的专业知识和技能
功能特性
代码补全(Inline Suggestions)
在编辑器中输入代码时,Copilot 会自动提供建议。这是最常用的功能,适合:
- 补全代码片段、变量名和函数
- 生成重复性代码
- 从自然语言注释生成代码
- 为测试驱动开发生成测试
Copilot Chat
聊天界面让你可以用自然语言提问编程相关问题。适合:
- 用自然语言询问代码问题
- 生成大段代码,然后迭代优化
- 使用关键词和技能快速完成特定任务
Copilot Edits
可以从单个聊天提示跨多个文件进行编辑。有两种模式:
- 编辑模式:精细控制 Copilot 提议的编辑,适合快速、特定的更新
- 代理模式:让 Copilot 自主编辑代码,适合复杂的多步骤任务
Copilot Code Review
AI 生成的代码审查建议,帮助你写出更好的代码。
Copilot CLI
命令行界面让你可以在终端中使用 Copilot,获取问题答案或请求修改本地文件。
安装与配置
支持的编辑器
- Visual Studio Code
- Visual Studio
- JetBrains IDEs
- Vim/Neovim
- Azure Data Studio
- Xcode
- Eclipse IDE
VS Code 安装
- 在扩展市场搜索并安装 GitHub Copilot 扩展
- 安装 GitHub Copilot Chat 扩展(可选,用于聊天功能)
- 使用 GitHub 账号登录授权
配置选项
在 VS Code 设置中配置:
{
"github.copilot.enable": {
"*": true,
"yaml": false,
"plaintext": false
},
"github.copilot.editor.enableAutoCompletions": true,
"github.copilot.editor.enableCodeActions": true
}
代码补全使用
基本操作
在编辑器中输入代码时,Copilot 会自动提供建议:
- 灰色文本 为建议代码
- 按
Tab接受建议 - 按
Esc拒绝建议 - 按
Alt + ]查看下一个建议 - 按
Alt + [查看上一个建议 - 按
Ctrl + Enter打开建议面板,查看多个建议
注释驱动开发
通过编写清晰的注释让 Copilot 生成代码:
// 计算固定利率贷款的月供
// 参数: principal(本金), rate(年利率), years(贷款年限)
// 返回: 每月还款金额
function calculateMonthlyPayment(principal, rate, years) {
const monthlyRate = rate / 100 / 12;
const numberOfPayments = years * 12;
const monthlyPayment =
principal * monthlyRate * Math.pow(1 + monthlyRate, numberOfPayments) /
(Math.pow(1 + monthlyRate, numberOfPayments) - 1);
return Math.round(monthlyPayment * 100) / 100;
}
上下文理解
Copilot 会分析以下内容来提供更准确的建议:
- 当前文件内容
- 相关导入语句
- 项目结构
- 编码风格
选择最佳建议
当 Copilot 提供多个建议时:
// 输入函数签名后,按 Ctrl+Enter 查看多个建议
function formatDate(date, format) {
// Copilot 会根据上下文提供多个实现方案
}
Copilot Chat 使用
打开聊天
- 按
Ctrl + Shift + I打开内联聊天 - 点击侧边栏 Copilot 图标打开聊天面板
- 在 GitHub 网站上点击 Copilot 图标
斜杠命令
斜杠命令让你可以快速完成常见任务:
| 命令 | 说明 |
|---|---|
/clear | 开始新的聊天会话 |
/explain | 解释当前编辑器中的代码 |
/fix | 为选中的代码提出修复建议 |
/tests | 为选中的代码生成单元测试 |
/help | GitHub Copilot 使用帮助 |
/new | 创建新项目 |
/doc | 为符号添加文档注释(VS/JetBrains) |
/optimize | 分析并改进代码性能(VS) |
/simplify | 简化当前代码选择(Xcode) |
聊天变量(VS Code)
使用 # 前缀的变量可以包含特定上下文:
| 变量 | 说明 |
|---|---|
#file | 包含当前文件内容 |
#selection | 包含当前选中的文本 |
#function | 包含当前函数或方法 |
#class | 包含当前类 |
#project | 包含项目上下文 |
#path | 包含文件路径 |
示例:
解释 #selection 中的代码逻辑
这个 #function 和 #file 中其他函数有什么关系?
聊天参与者(VS Code)
使用 @ 前缀指定专业领域的助手:
| 参与者 | 说明 |
|---|---|
@workspace | 了解工作区代码,适合分析项目结构和代码交互 |
@terminal | 了解终端 shell 内容,适合创建或调试终端命令 |
@vscode | 了解 VS Code 命令和功能 |
@github | 使用 GitHub 特定的 Copilot 技能 |
@azure | 了解 Azure 服务(预览版) |
实际对话示例
解释代码:
/explain 这段代码做了什么?
// 或使用自然语言
请解释这个函数的工作原理
修复问题:
/fix 这个函数有内存泄漏问题
// 或
这段代码的性能可以优化吗?
生成测试:
/tests 为这个函数生成单元测试,使用 Jest 框架
添加文档:
为这个类添加 JSDoc 文档注释
内联聊天
选中代码后按 Ctrl + I(VS Code)可以打开内联聊天,直接在代码中进行交互:
// 选中的代码
function oldFunction() {
// ...
}
// 内联聊天提示
将这个函数改为 async/await 异步函数
最佳实践
编写清晰的提示
好的提示示例:
// 创建一个防抖函数
// 参数: func(要防抖的函数), wait(等待毫秒数)
// 返回: 防抖后的函数
// 要求: 在最后一次调用后 wait 毫秒才执行
function debounce(func, wait) {
let timeout;
return function executedFunction(...args) {
const later = () => {
clearTimeout(timeout);
func(...args);
};
clearTimeout(timeout);
timeout = setTimeout(later, wait);
};
}
不好的提示示例:
// 写一个防抖
function debounce() {
// Copilot 无法理解具体需求
}
使用有意义的命名
好的命名帮助 Copilot 理解意图:
// 好的命名
function calculateTotalPrice(items, taxRate) {
return items.reduce((sum, item) => sum + item.price, 0) * (1 + taxRate);
}
// 不好的命名
function calc(arr, x) {
return arr.reduce((s, i) => s + i.p, 0) * (1 + x);
}
提供上下文
在文件开头添加上下文注释:
/**
* 用户认证模块
* 使用 JWT 进行身份验证
* 依赖: jsonwebtoken, bcrypt
*/
分步处理复杂任务
将复杂任务分解为多个步骤:
第一步: 创建用户模型,包含 name, email, password 字段
第二步: 添加密码加密方法
第三步: 实现 JWT 令牌生成
第四步: 创建登录验证中间件
检查 Copilot 的工作
始终审查 Copilot 生成的代码:
- 理解代码逻辑后再使用
- 检查功能正确性和安全性
- 考虑代码的可读性和可维护性
- 使用自动化测试验证
常见用例
生成样板代码
// 创建一个 Express 路由,包含 CRUD 操作
const express = require('express');
const router = express.Router();
// GET /items - 获取所有项目
router.get('/', async (req, res) => {
try {
const items = await Item.find();
res.json(items);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// GET /items/:id - 获取单个项目
router.get('/:id', async (req, res) => {
try {
const item = await Item.findById(req.params.id);
if (!item) return res.status(404).json({ message: 'Item not found' });
res.json(item);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// POST /items - 创建新项目
router.post('/', async (req, res) => {
const item = new Item(req.body);
try {
const savedItem = await item.save();
res.status(201).json(savedItem);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
module.exports = router;
编写正则表达式
// 匹配有效邮箱地址的正则表达式
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
// 匹配中国手机号的正则表达式
const phoneRegex = /^1[3-9]\d{9}$/;
// 匹配 URL 的正则表达式
const urlRegex = /^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/;
实现算法
// 实现快速排序算法
function quickSort(arr) {
if (arr.length <= 1) return arr;
const pivot = arr[Math.floor(arr.length / 2)];
const left = arr.filter(x => x < pivot);
const middle = arr.filter(x => x === pivot);
const right = arr.filter(x => x > pivot);
return [...quickSort(left), ...middle, ...quickSort(right)];
}
// 实现二分查找
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
生成 API 请求
// 使用 fetch 封装 API 请求
async function fetchAPI(url, options = {}) {
const defaultOptions = {
headers: {
'Content-Type': 'application/json',
},
};
const response = await fetch(url, { ...defaultOptions, ...options });
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return response.json();
}
// 使用示例
const data = await fetchAPI('https://api.example.com/users', {
method: 'POST',
body: JSON.stringify({ name: '张三', email: '[email protected]' }),
});
编写测试
describe('formatDate', () => {
test('应该正确格式化日期', () => {
const date = new Date('2024-01-15T10:30:00');
expect(formatDate(date, 'YYYY-MM-DD')).toBe('2024-01-15');
});
test('应该处理无效日期', () => {
expect(() => formatDate(new Date('invalid'), 'YYYY-MM-DD')).toThrow();
});
test('应该支持不同格式', () => {
const date = new Date('2024-01-15T10:30:00');
expect(formatDate(date, 'DD/MM/YYYY')).toBe('15/01/2024');
});
});
隐私和安全
代码隐私
- 代码片段发送到 GitHub 进行处理
- 企业版不会将代码用于训练模型
- 可以配置排除特定文件
配置排除
创建 .copilotignore 文件:
secrets/
*.env
credentials.json
private/
config/local.*
禁用特定语言
{
"github.copilot.enable": {
"python": false,
"plaintext": false
}
}
不复制公共代码
可以在设置中关闭与公共代码匹配的建议。
定价计划
| 版本 | 价格 | 适用场景 |
|---|---|---|
| Individual | $10/月 | 个人开发者 |
| Business | $19/月/用户 | 团队协作 |
| Enterprise | $39/月/用户 | 企业级功能 |
免费使用资格:
- 学生(通过 GitHub Student Developer Pack)
- 开源项目维护者(活跃项目)
- GitHub Teacher
引导 Copilot 输出
提供有用的上下文
- 打开相关文件,关闭无关文件
- 在聊天中删除不再有用的请求
- 使用关键词聚焦特定任务
重写提示
如果 Copilot 没有提供有用的响应,可以:
- 重新表述提示
- 将请求分解为多个更小的提示
- 使用斜杠命令而非自然语言
提供反馈
- 对内联建议,接受或拒绝
- 对聊天响应,点击拇指向上或向下