引言
最近一段时间,AI 技术的进步则让代码补全有了更上一层楼的机会。接下来,我们为大家介绍的 Github Copilot 就是这样一款基于 AI 的代码补全工具。
我们编程时写出的代码,在未编译前通常以纯文本格式存在。因此,实际上我们能使用任何文本编辑器来编写代码,包括系统自带的记事本。但是,好的工具能够让我们事半功倍。面对复杂的工作任务,我们需要 IDE(集成开发环境)这样的生产力工具。IDE 本质上就是更高级的文本编辑器,集成了许多人性化功能来提升效率,比如:自动补全变量,提示可能会用到的函数列表,语法高亮,显示语法错误等等。
IDE 本身也在不断进化。我的第一门使用 IDE 的编程语言是 Java,使用的是 Eclipse,当时自动补全功能还比较简陋,局限于符号的提示与选单,我也没有对 IDE 究竟有多强大建立起概念。后来,开始学习开发框架后,我慢慢接触到 JetBrains 出品的 IDEA。IDEA 的提示更智能,例如:可以在数组后输入「.for」自动构成 foreach 循环,也可以使用快捷键自动生成 Getter/Setter、构造函数、重载函数等等。毫无疑问,JetBrains 系列产品为编码工作带来了更高的效率,提供了更加全面、智能的补全功能。
GitHub Copilot 是什么
Github Copilot 是 GitHub 和 OpenAI 合作开发的人工智能工具,可以在编辑代码时帮助你自动生成可能会需要的代码。
GitHub Copilot 能够提取代码上下文,给出整行代码或整个函数的补全建议。它可以帮助我们完成下列任务:
- 将注释转化为代码;
- 自动填充重复代码;
- 编写测试;
- 快速发现解决问题的替代方法;
- 无需网络搜索即可快速探索新的 API;
- 适应用户编写代码的方式,帮助用户更快地完成工作。
原理是什么?
我们先介绍一下 GPT-3。GPT-3(Generative Pre-trained Transformer 3)是一个用于处理自然语言的 AI 模型,由 OpenAI 训练开发。GPT-3 通过阅读几乎一切人类可阅读的内容来进行训练,理论上,它能够完成一切通过语言完成的工作,而且完成效果还非常接近人类。已经有实验证明 GPT-3 可用于撰写文章、回答问题、编写代码生成应用程序、设计表格、开发游戏、将文字描述便携为成型的网页等等。
而 OpenAI Codex 则是基于 GPT-3 开发的一款针对编程所设计的 AI 模型。Codex 从公共代码仓库学习人类编写的代码,其代码来源包括 Github 上的公共代码仓库。官网原文如下:
OpenAI Codex is a descendant of GPT-3; its training data contains both natural language and billions of lines of source code from publicly available sources, including code in public GitHub repositories. (OpenAI Codex 是 GPT-3 的衍生项目;它的训练数据包括自然语言和数以亿计来自公开可用来源的源代码,其中包括 Github 公开仓库的代码。)
最后,GitHub Copilot 则是使用了 Codex 进行研发的一款商业产品。Github 将算法进行包装,做成了插件和网页,进行应用分发。现在 GitHub Copilot 支持在 Visual Studio Code、Visual Studio、JetBrains Rider 上通过插件形式集成进 IDE,以便我们使用。
使用 & 体验
要想使用 GitHub Copilot,首先需要注册一个 Github 账号。有了帐号后,按下面的步骤可以找到并启用 GitHub Copilot:
- 找到设置页面:在任何页面的右上角,单击个人资料照片,然后单击“设置”。
找到 GitHub Copilot 设置页面:在边栏的「代码、规划和自动化」部分,单击「GitHub Copilot」。
启用 GitHub Copilot:在 GitHub Copilot 设置页面上,单击「启用 GitHub Copilot」。
- 选择付费方式(月付/年付):GitHub Copilot 可以免费试用 60 个自然日,随后需要以 $10/月 的价格订阅。如果你是学生的话,可享受教育优惠,免费使用 GitHub Copilot。
在 Rider IDE 进行设置
- 在偏好设置里安装 Github Copilot Plugin;
- 重启 IDE;
- 登陆 Github 完成验证。
设置完成后,IDE 提示可以使用「Tab」来自动补全代码,使用「⌥ + ]」或者「⌥ + [」来选择其他候选的补全选项。
体验如何
在编写代码的过程中,Github Copilot 会自动提示可能的补全方案,此时按下「Tab」即可完成补全。
有时,AI 并不会一次给出完整的提示代码,例如,图示的代码就并非一次性生成的,而是逐行自动补全,最终生成了一个可以实际使用的函数(甚至包括注释)。下图的例子在 Unity3D 中绘制了一条射线用于检测前方是否有物品,只有第一行注释是我写下的。
下面的例子很有趣:当我尝试把乐谱的音高编写成数组时,Github Copilot 也给出了他所理解的音乐:
在这样的例子中,对重复的流行乐片段,Github Copilot 有时可以给出不错的答案。比如预先输入《卡农》的重复性模进片段,Github Copilot 往往可以完全正确地补全乐谱。可见,在面临重复性较高的功能开发,或是使用一些常用的算法时,依靠 AI 补全是一个称得上非常可靠的选择。不过,如果需求非常复杂,大部分情况下,它并不能独立地给出完美的解决方案。GitHub 团队在对一组 Python 函数进行基准性测试后发现尝试十次后,大约 57% 情况下可以给出正确的答案。部分情况下,Github Copilot 也会给出无法通过编译的代码。
Github Copilot 的不足之处
使用 Github Copilot 很久后,Reddit 大佬 Colin Eberhardt 指出了几点不足:
- Github Copilot 很多时候响应得不够快。虽然它已经快到秒出答案,但这对快速输出状态的程序员来说仍然是不够的。要么它的提示还没出现你就继续输入了,要么你会因为等它而暂时停下思路。
- Github Copilot 总是会自动提示。这种提示和输入存在冲突:有时,当你需要等等看提示怎么说另一些时,会不断有内容弹出,接着消失。或许,自动模式并不是 Github Copilot 的「最佳打开方式」?
- Github Copilot 生成代码质量不足。它生成的代码可以满足大部分简单且重复的功能需求,但对于熟练的程序员,可能会额外浪费很多精力来校验它自动生成的代码是否正确。
Github Copilot 版权问题
许多人指出 Github Copilot 会使用有版权的代码作为提示内容(参见 Jacob Crume 的文章“GitHub Copilot is Now Available for All and Not Everyone Likes It”)。少数派作者 100gle 在《GitHub Copilot:革命未竟,未来可期》中更是举出了很多例子。最为出名的莫过于,如果你在编辑器中输入 Fast inverse square root
,便会得到一段代码,它和当年《雷神之锤》使用的算法完全一致。
现代开源软件多使用 GPL (GNU General Public License)协议,这个协议要求你也将代码开源,且使用 GPL 协议。而通过 Github Copilot 补全时我们并不确定这段代码的作者为它指定的协议。开源许可证的主要作用是对软件的使用、复制、修改和再发布等进行限制。而显然使用 AI 补全显然会破坏这一点。
可以预见的是,同当今各种 AI 作画工具面对的种种争议一样,Github Copilot 也一定会因为版权问题,难以被大型企业所用,至少短期内如此。
使用建议
- Github Copilot 能帮助初学者面对不那么熟悉的编程语言或开发框架时,快速学习常用的接口调用方式和简单的实现方案。这意味着我们可以不用为了某些基础问题反复翻找 API 手册,或体验 CSDN 这样的技术博客网站的层层传送门。
- Github Copilot 可以帮助我们在不熟悉的领域快速上手,只需要一些注释便可快速生成部分业务逻辑,然后进行测试。当然,最终代码的可靠性还是需要开发者人为辨别和控制。
- Github Copilot 可以在重复性劳动时显著提升效率。比如你需要写一大堆单元测试,它们无法靠复制/粘贴批量生成,同时有一些细微的逻辑变化需要处理。又或是你需要开发一些重复性功能,比如批量声明一些数据类型好几十次。这时 Github Copilot 补全的代码往往很可靠。
总结
Github Copilot 或许并不能承载类似“AI 即将取代程序员”的想象,但在当下,它无疑是程序员的好帮手。作为辅助,它提供的补全并没有智能到让完全不会编程的用户完成开发,但也并不只是简单的提示工具。合理运用 Github Copilot 能够为开发者的学习成长带来很大帮助。
与此同时,它不可避免地存在一些缺陷,代码的版权问题也限制了它商业化的应用前景。不够熟练的程序员可能也会对它失望——就像它名字中的 Copilot 一样,Github Copilot 更接近优秀的副驾驶角色,但工作总归还是需要一位优秀的主驾驶领导。
最好的旅行靴已经送到我们手中,走出什么样的路还需要开发者自己去定夺。