GitHub Copilot 是由 GitHub 开发的一款 AI 编程助手。它能够在Web浏览器、常见IDE、Windows 命令行中进行使用。本文介绍的功能将主要聚焦在 Github Copilot 在 Vscode 中的使用。
要在 VS Code 中使用 Copilot 需要先安装
- Copilot 插件 用于代码文件行间交互和代码补全等操作
- Copilot Chat 插件 支持完整功能的对话式的插件
在完成插件的安装后,需要登录Github的账号,开发者可以根据自己的实际情况选择购买对应的服务。
以下将着重介绍 Copilot 在使用中的常用功能。
1. 代码补全
在 VS Code 中使用Copilot的代码补全有两种方式:行内补全和会话补全。
1.1 基于行内交互的代码补全
在 Windows 中使用快捷键Ctrl + I
可唤起行内交互窗口,Copilot 会修改光标附近的代码内容,适用单行或小范围的代码优化操作。
提示语 “帮我生成一个复制文件夹的函数,要求把文件夹复制到目标文件夹下,同时内部嵌套的文件夹也可以复制”
1.2 基于对话窗口的代码补全
使用Chat对话窗口时,有三种 AI 工作模式可以选择:
-
问答模式(Ask)
问答模式适用于功能逻辑梳理、问题排查等使用场景,该模式主要聚焦在问答交互上,不会主动修改文档内容。提示语 “帮我生成一个复制文件夹的函数,要求把文件夹复制到目标文件夹下,同时内部嵌套的文件夹也可以复制”
-
编辑模式(Edit)
编辑模式根据会话的需求自动的编辑当前打开的文本,在 AI 完成代码编辑后,会有代码比对,开发者可以自行选择是否接受当前的内容变更。提示语 “帮我生成一个复制文件夹的函数,要求把文件夹复制到目标文件夹下,同时内部嵌套的文件夹也可以复制”
-
代理模式(Agent)
代理模式具备更强大的功能,可以执行命令行脚本,处理多个文件的内容,包括但不限于创建文件夹、新增项目、删除文件等操作,实现跨模块的联动,是具备完整项目能力的会话模式。提示语 “帮我修改一下 util.ts 文件,生成一个复制文件夹的函数,要求把文件夹复制到目标文件夹下,同时内部嵌套的文件夹也可以复制”
下图是Copilot Chat的工作窗口,在使用中,需要重点关注的内容有:
- 上下文管理
为会话预置详细的上下文环境,可以帮助 Copilot 的回答更加的准确,开发者可以点击Add Context
按钮或者使用#file
指令,将关联的文件引入对话上下文,这样的操作可以为 AI 的回答提供合理的约束。 - AI 工作模式
- 问答模式 聚焦在代码解释和一些知识获取的场景,例如,开发者只是想了解当前组件的业务逻辑,便于后续的功能拓展,问答模式会进行很好的解释,方便项目的新人上手;
- 当处于 编辑模式 开发者可能需要针对当前文件进行一些全面的修改,希望AI直接修改文档内容,在描述具体的需求后,文档的内容会自动的更新,并进行代码比对;
- 代理模式 将当前项目全权委托给AI,AI 可以进行文件的调整和命令行的调用等系统级操作。例如基于已有的模板文件,新建一个项目,又或在调整的过程中需要涉及到命令行中的联动,例如安装依赖等操作,代理模式可以自动化的处理好这一切。
- AI 模型
不同的AI模型回答的内容可能会各不相同,速度可能也不尽一样,开发者可以根据自己的实际需求,选择合适的模型进行开发。
1.3 提示词
除了上述的基础功能之外,Copilot 在 Chat 会话的提示词中为开发者提供了三种快捷指令,分别是:
- 变量指令
#
- 参与者指令
@
- 快捷指令
/
变量指令
在Chat对话框中使用 #
可以将目标变量引入到当前的对话上下文中,变量可以是选中的代码行、文件或者内容的变动等。常见的变量指令如下:
变量 | 说明 |
---|---|
#block | 将当前代码块包含在提示中。 |
#class | 将当前类包含在提示中。 |
#comment | 将当前注释包含在提示中。 |
#file | 将当前文件的内容包含在提示中。 |
#function | 将当前函数或方法包含在提示中。 |
#line | 将当前代码行包含在提示中。 |
#path | 将文件路径包含在提示中。 |
#project | 将项目上下文包含在提示中。 |
#selection | 将当前所选的文本包含在提示中。 |
#sym | 将当前符号包含在提示中。 |
参与者指令
参与者指令是针对 Copilot 扩展程序提供的一种快捷引入的方式,可以简单的理解成具备某一方面独特知识的 AI 助手,在使用的时候,使用 @
的方式,就可以把这些具备某些独特知识的 AI 助手引入到当前的会话上下文中。常见的参与者指令如下:
变量 | 说明 |
---|---|
@azure | 具有有关 Azure 服务及其使用、部署和管理方式的上下文。 需要有关 Azure 的帮助时,请使用 @azure 。 @azure 聊天参与者目前为 公共预览版,可能会更改。 |
@github | 使你能够使用 GitHub 特定的 Copilot 技能。 请参阅“在 IDE 中向 GitHub Copilot 提问”。 |
@terminal | 具有有关 Visual Studio Code 终端 shell 及其内容的上下文。 当需要帮助创建或调试终端命令时,请使用 @terminal 。 |
@vscode | 具有有关 Visual Studio Code 命令和功能的上下文。 当需要有关 Visual Studio Code 的帮助时,请使用 @vscode 。 |
@workspace | 具有有关工作区中代码的上下文。 当希望 Copilot 考虑项目的结构、代码的不同部分如何进行互动或者项目中的设计模式时,请使用 @workspace 。 |
使用 @
指令可以回答的更精准,更具体,例如,当开发者只是想快速的获取命令行中的一段指令应该如何输入时,使用 @
指令与否,会有明显的差别:
- 不使用
@
指令 - 使用
@
指令
在上面这个例子中,不使用 @
指令时,AI 的回答的内容更多,更加的普适;而使用 @
指令后,AI理解到当前的使用场景是需要在命令行中输入指令,因而回答的更加简单精确。
当开发者想要更加具体的了解当前整个项目的架构、模块关系、数据通信时,使用 @workspace
将整个工作区加入到当前的会话中,可以让 AI 更好的理解当前的问题是需要基于当前的项目的。
除了已有的 Chat 扩展,开发者也可以添加自己需要的会话参与者,点击 Install Chat Extensions...
可以看到有更多的 Copilot 扩展,这些扩展可能是在图形学或者测试或是数据库方面都预置了相当专业的知识,相比于宽泛的 AI 回答,当开发者明确的知道自己想要获取的回答内容时,使用 @
指令,将这些参与者 @
进来,可以让回答更加的凝练和实用。
快捷指令
快捷指令可以避免一些常用的提示语的编写,例如解释代码、修复问题、为部分函数生成单元测试等,开发者可以使用 /
的方式在对话输入框中快速唤起快捷指令,常见的一些快捷指令如下:
命令 | 说明 |
---|---|
/clear | 启动新的聊天会话。 |
/explain | 说明代码在活动编辑器中起到的作用。 |
/fix | 为所选代码中的问题建议修补程序。 |
/fixTestFailure | 查找并修复失败的测试。 |
/help | 使用 GitHub Copilot 的快速参考和基础知识。 |
/new | 创建新项目。 |
/tests | 为所选代码生成单元测试。 |
在下面的这个场景中,开发者想要理解选中行的意义,无需使用过多的自然语言描述,只需要调用 Copilot 的快捷指令(/
),并配合变量指令(#
),就可以快速的在会话中得到答案。
2. 代码 Review
Copilot 的另一个常用功能是在代码提交时的 Code Review。
使用 Copilot 进行代码审核有两种方式:
- 变更、提交阶段的审核:如上图,点击红色区域的图标,可以针对当前的改动进行代码审核
- 主动的代码审核:开发者可以使用
Ctrl + Shift + P
唤起快捷指令输入框,在输入框中输入Copilot Review
下拉选择,可以针对选中的内容进行代码的审核,如下图。
下面的操作使用Ctrl + Shift + P
唤起了指令面板,针对一个文件,主动的进行代码审核,代码审核会逐步的进行,并统计Copilot的评论数目,开发者可以点击 ↑ 或者 ↓ 的按钮切换代码审核的结果。
例如上面的代码审核中发现了一个潜在的问题
const [fontSize, setFontSize] = useState<Number>(0)
在 typescript 的基础类型中数字是 number
而 Number
是Javascript中的数字的构造函数,在typescript中<>
中间的泛型应该是一种数据类型,而不是一个构造函数,因此,在本次代码审核中,Copilot 给出了他的第一条建议。
如果在代码审核中,用户觉得某一条评论是不错的,可以点击右上角的 👍反馈给 Copilot,或者觉得某一条评论不合理可以点击👎,这样的操作有利于 Copilot 更好的理解项目代码,同时在后续的代码审核中进行改进和优化。
在查看代码审核结果后,用户可以选择左下角的采用或者废弃该条评论,如果采用该评论,代码中对应的文档会按照代码比对的结果进行修改。
3. 提交信息生成
在日常的代码提交中,commit 的信息也是比较重要的,可以帮助代码审核或者项目的其他参与者了解到某一次变更的内容和目的,对于后续的问题修复和功能扩展都有积极的作用。
在日常的开发中,需要尽量保持每一次提交的原子化,即:
- 单一目的性:每个commit只解决一个特定问题或实现一个功能
- 独立性:commit之间相互独立,不依赖其他commit也能正常工作
- 完整性:每个commit自身是完整可工作的,不会破坏代码库
- 可逆性:可以安全地回滚单个commit而不影响其他变更
在完成一次功能需求后,可以使用 Copilot 去分析本次修改,并生成对应的 commit 信息。
点击 commit 的✨标志,稍等片刻后,AI 会分析本次的改动,并生成对应的提交信息,如果某一次的总结不符合实际的改动目的,可以再次点击✨标志,AI会重新分析,并生成新的提交信息。
在一些团队内部,会存在自己的代码提交规范,Copilot 也支持生成自定义的 Commit 信息。在项目的 settings.json 中可以设置 Copilot 提交日志需要参考的格式,该文档相当于是会话的提示词,可以帮助AI更好的生成符合当前团队风格的提交记录。
在commit的提交示例文档中,没有固定的格式限制,但是我们需要较为明确的提供一些示例和约束:
当提供一些commit的规范文档后,AI再次生成commit信息就会以一种符合文档示例的形式呈现出来。
4. 使用建议
4.1 关注上下文
- 在会话中引入关联文件
如上,有一个 vue 的组件和一个工具函数,在工具函数中提供了一个计算两数之和,并返回结果的二进制的函数
getAddBinaryResult
,我们给出提示词 “创建两个输入框,计算两个输入之和的二进制结果”
当没有在会话中引入关联的文件时,AI会自己生成计算逻辑,而不会使用现有的工具方法进行计算
当使用 #file
变量指令,将工具函数文件引入对话后,再次生成,可以看到,AI生成的代码
- 进行一次模块的引用
- 使用已有的功能函数替代自己实现的求和逻辑。
- 管理好会话上下文的历史记录
在历史的会话中,会有一些让人不满意或者错误的回答,为了使未来的回答更加准确和贴近自身的需求,用户可以选择性的将一些无用会话从历史记录中删除,以此,使 Copilot 的后续回答和代码生成更加的准确。
4.2 关注注释
- 文件的头部注释
文件头部一个好的注释,可以帮助 Copilot 更好的理解当前的场景和上下文的环境,扮演了提示词的功能,一个良好的头部注释,可以包括:- 一个简短的描述介绍文件背景,例如什么样的架构、什么样的技术栈等
- 一个准确的目标介绍文件的用途,例如是做文件处理、还是做数据库的读写操作
例如上面的顶部注释,可以在生成代码的时候给 Copilot 更多的约束,告诉AI哪些函数是可以使用的,哪些配置是适用于当前项目的。
- 注释的示例代码
良好的注释应该包括一些简单的使用代码示例,让AI可以更好的理解当前文件的使用方式,同时需要包括一个好的输入和输出,就像写算法的单元测试一样,一个好的输出和输出,可以让AI生成的代码,更加符合用户的需求。 示例1: 注释简单,Copilot 的回答更加的宽泛,考虑的情况更多,提供了更多的可能性示例2:注释指向性更加的明确,有示例,有输入输出,Copilot 的生成速度更快,指向性也更加明确。
- 函数内的注释
除了函数定义时的外部注释,在编写函数内的代码时,也可以通过单行注释逐步实现 Copilit 的代码补全。 例如,针对具体的业务业务逻辑,无法通过一段提示词生成准确且可用的代码,而且提示词的编写也相对复杂的时候,可以通过逐行注释加代码补全的方式实现复杂的业务逻辑。
在上面的例子中,在一个函数内,逐行的注释一方面可以使代码的注释完善,更方便其他参与者的理解。相对复杂的功能时,提示词编写可能也会比较耗时,并且AI反馈的效果并不一定会很好,后续调整起来也会比较麻烦。
因此,在编写比较复杂的业务逻辑时,建议使用行内注释的方式,通过将业务逻辑逐行拆解注释,AI逐行生成的方式,将复杂的功能拆分,逐步通过AI来实现。例如,上面的例子是想实现一个简单的数字相加,返回结果的二进制的函数。我们逐行编写了以下注释:
// 判断数字a和数字b是否合法
// 将数字a和数字b相加
// 将result结果转化为二进制字符并返回
每一步的操作都是明确的,通过一行或者简单的多行代码即可实现,不涉及过多的业务逻辑。
通过这样的方式,很适合去做一些深度定制化的业务需求,逐步拆解业务的每一步,使用AI构建完整的业务代码。
4.3 更多的使用 Copilot 提供的指令
@
:例如,@workspace
可以了解你的整个项目,并回答与之相关的问题。因此,在尝试使用@
指令关联你希望涉及的知识范围,Copilot 就更准确的回答或者执行开发者需要的操作。#
:例如,#selection
可以在提示词中快捷注入选中的代码,#editor
可以让当前的会话聚焦在编辑器中鼠标当前聚焦的位置,#file
可以快速的把需要加入上下文的文件引入到当前的会话中。/
:例如,/clear
可以快速清除历史的会话内容,/new
,可以快速的新建开发者需要的内容,如图,提示中显示可以在当前项目中新建,或者是使用正则参与者,来创建一些新的内容。