开发者分享 Copilot 使用体验
个人体验和观点分享,缺乏系统的技巧指导,参考价值有限。
个人体验和观点分享,缺乏系统的技巧指导,参考价值有限。
这个周末,我花了些时间摆弄 GitHub Copilot,用的是 copilot-cli 工具。
前段时间,我做过一个小型 Electron 应用,用来搜索并显示 Unicode 字符的信息。当时无论是 Electron 还是 Javascript,我其实都不太清楚自己在做什么,而且也找不到多少正确、及时、适合初学者的文档,哪怕只是讲清楚如何把一个应用的各个部分串起来这么简单的事情——那些文档用来写个 “Hello World” 还算够用,再往后就不行了。顺带一提,我对许多语言和框架也有同样的抱怨——祝你好运,看看能不能只靠网上的 C 文档搞明白如何使用 make 和 linker。总之,我还是磕磕绊绊地做出来了,你可以在这里看到我手写的成果。它确实能用,而且同一套代码既可以生成 Electron 应用,也可以生成独立网页和 CLI 工具,但代码写得很糟糕,尤其是构建流程。
此后的更新在这里。除了一些非常小的手动调整,几乎所有内容都是 Copilot 写的。完成大部分工作的初始 prompt,大概是:“让这个项目更符合 Electron 和 Javascript 的惯用写法。”我和这个邪恶的幻觉引擎合作了几个小时,其中还用 prompt 要求它添加测试,以及用于 CI 的 GitHub workflow。大多数时候,我都放手让它想怎么做就怎么做,只有少数几个小地方,我要求它换一种方式处理。总体而言,结果给我留下了非常深刻的印象。以我对现代 HTML/CSS 和 Javascript 的了解程度,靠自己根本不可能完成这些工作。
然后我想到:“外面有那么多 Javascript/Electron 相关内容供它学习,不如试点别的。”于是,我从待办事项中挑出了下一个小工具改进任务,让它替我实现。之前我有一个 shell alias:alias highlight="ack --color --passthru"——你通过管道把内容传进去,再给它一个 perl regex,它就会高亮所有匹配项。我希望能够控制颜色,比如这样写:cal | highlight --red '25|26' --green '27|28'。于是,我给 Copilot 的 prompt 大致是:“写一个 shell script,接收一个可选的 --color_name 参数,后面跟一个 perl regex;从 STDIN 读取输入,再输出到 STDOUT,并用指定颜色高亮所有匹配项。它应该支持任意数量的此类匹配条件。”它尝试了几次才完成,主要是自己一边测试、反复测试已经写好的内容,一边逐步迭代出解决方案,几乎不需要我提供纠正意见。我让它写文档,它也写了。我想给它出一道即使经验丰富的 shell 脚本开发者也会觉得极其费解的题,于是让它支持输出自己的 shell tab-completion function,结果它也做到了。现在,我可以输入 highlight --gr<tab>,它会自动补全为 green。
我还给了它另一个 perl 小任务,要求它确保对现有代码库所做的所有修改都达到 100% 的测试覆盖率,包括 branch coverage 和 condition coverage。它转身就完成了。事实上,它还为一些我之前写过、但缺少测试的内容补上了测试。然后,它又写了一个测试:如果我以后修改代码,却没有达到 100% 覆盖率,这个测试就会失败。
在此期间,它有几次会说“我需要查阅文档”,然后在征得许可后,自己去阅读 Devel::Cover、Electron 等项目的文档。它甚至说:“我无法从 Electron 文档中搞明白这件事。”(太好了,原来不只是我觉得它的文档不怎么样!)接着,它直接去读 Electron 的源代码,弄清楚了到底是怎么回事。
做到这里,我已经有点停不下来了,于是又让它修复我的一个 perl module 中长期存在的 bug。这个 bug 会导致测试在 OpenBSD、NetBSD 和 OmniOS 上稳定失败,在 FreeBSD 上间歇性失败,但在 Linux 和 Mac 上始终能够通过。我已经为此苦苦折腾了一年多,向其他人求助,也没人能找出原因。Copilot 查看了代码,又检查了 GitHub 上 OpenBSD test workflow 中的失败报告,然后告诉我问题出在哪里,以及应该如何修复。我不相信它,于是说:“验证一下,这是一个可以通过 ssh 连接的 OpenBSD 机器地址。”于是它真的去验证了。
我对它建议的修复方案并不满意——那个方案确实能修好测试,却会悄悄破坏工具的交互式使用体验:它会一直缓冲 STDERR 输出,直到最后才一股脑全部吐出来。我向它解释了这一点,它便对我的代码进行了一次大规模重写。我对此相当怀疑,但在亲自测试,并且非常仔细地审查过它的修改之后——没错,它做对了。它生成的代码读起来有点费劲,但那是因为代码本身需要处理一些复杂的进程间通信和控制。它甚至没等我要求,就主动写了测试。也许我唯一的不满,就是它没有给代码添加注释。
这玩意儿简直他妈的是魔法。我会大量使用它来创建新东西,以及更新小型代码库。我认为,在维护大型 legacy application 时,它几乎不可能对 software archaeology 这部分工作起到多大作用——而这恰恰是大多数开发者在工作中耗费时间最多的事情——不过,一旦我搞清楚应该修改什么、在哪里修改,我至少会尝试用它来完成小规模更新。它生成的代码质量相当不错。当然,我们许多人都能写得更好,但它的产出通常是可读的。Copilot 的确需要有人稍微扶一把,它的输出也需要经过一轮简单编辑,才适合提交给其他人做 code review;不过,我自己写的代码同样如此,它并不需要更多额外照顾。
我强烈建议你亲自试试。
对于后续操作,你可以考虑屏蔽此人和/或举报滥用行为。