ChrisKim
Do not go gentle into that good night.
颢天

GitHub Copilot 使用体验分享

对计算机技术感兴趣的朋友一定听说过 GitHub Copilot 吧,它是 GitHub 与 OpenAI 合作研发的人工智能代码编写辅助程序。2022 年 6 月 22 日,Copilot 正式上线,可惜当时我手上没什么项目,也没法深度体验它(白瞎了 2 个月的免费试用),现在寒假期间正好有些项目要完成,于是花 10 美元买了一个月再来实际体验体验。

咱们开门见山,先说结论:

GitHub Copilot 是一个增强版的代码补全工具,从学生角度来说非常实用。

下面我们来详细说说我为什么这么说。

增强版的代码补全工具

Copilot 刚出来的时候炒的沸沸扬扬,说是 AI 自动写代码都能淘汰掉程序员了。而我体验后不这么认为,一般 IDE 都会有代码补全工具,比如自动补全变量名、方法名之类的,我认为 Copilot 只是个增强版的代码补全工具。

结构相似的代码:好用

比如我们写前端的时候,会把 API 请求封装到一个对象里方便调用,这个对象里每个元素的结构就相似。下面给出的代码片段,我用注释代表 Copilot 给出的补全提示:

// 由于这个项目代码不能开源,下面的片段是源代码的删减版。
// 大家如果拿这个片段测试,因为信息量过少,可能比我的效果要差很多。

export const service = {
  ship: {
    add: (data) => {
      return axios({
        baseURL,
        method: "POST",
        url: "/admin/ship/add",
        data: {
          data
        },
      });
    },
    delete: // (shipID) => {
//    return axios({
//      baseURL,
//      method: "DELETE",
//      url: "/admin/ship/delete",
//      data: {
//        shipID  
//      },
//    });
//  },
  }
}

可以看出来,Copilot 通过上下文分析得出了你的代码结构,你输入 delete 后它就能帮你生成结构类似的代码。并且它不是生搬硬套,而是会帮你调整,比如变量名它知道换成 shipID,http 方法知道换成 DELETE,API 的路径也知道通过方法名推导。

重复程度高的代码:好用

我们再来看个后端的例子,比如后端使用数据库模型时,需要写一个类,这个类可能超级多成员变量,重复程度很高,此时 Copilot 就替你完成重复劳作:

class Apply(db.Model):
    applyID = db.Column(db.Integer, primary_key=True, autoincrement=True)
    userID = db.Column(db.Integer, db.ForeignKey('user.userid'))
    status = db.Column(db.Integer)
    statMsg = db.Column(db.String(255))
    date = db.Column(db.Integer)
    direction = db.Column(db.Boolean)
    lockPos = db.Column(db.Integer)
    lockType = db.Column(db.Integer)
    shipName = db.Column(db.String(255))
    shipID = db.Column(db.Integer, db.ForeignKey('ship.shipID'))
    goodsType = db.Column(db.String(255))
    actualWaterline = db.Column(db.Float)
    actualLoadWeight = db.Column(db.Float)

    def __init__ # (self, userID, status, statMsg, date, direction, lockPos, lockType,
                 #  shipName, shipID, goodsType, actualWaterline, actualLoadWeight):
      # self.userID = userID
      # self.status = status
      # self.statMsg = statMsg
      # self.date = date
      # self.direction = direction
      # self.lockPos = lockPos
      # self.lockType = lockType
      # self.shipName = shipName
      # self.shipID = shipID
      # self.goodsType = goodsType
      # self.actualWaterline = actualWaterline
      # self.actualLoadWeight = actualLoadWeight

可以看出来,Copilot 帮你一键生成了构造函数,非常省事。并且之后在业务逻辑要用到这个类的时候,Copilot 也能批量生成每个成员变量对应的代码逻辑,你就不需要手动一行行敲每个变量的代码了。

另外,如果一个代码结构重复得出现在你的项目多次,之后你甚至都不需要写了,一到你想要写这个代码的时候,Copilot 就能明白你要写啥,然后自动生成你想要的代码,并且准确率还不低。

(不过一个代码重复出现多次,应当提取为一个方法。我因为是自己的项目,所以就写得随性了)

接口复杂的库:好用

对于 Python、JavaScript 等等第三方库众多的语言,传统 IDE 的自动补全功能基本上是废了,少数方法名能补全,大多数方法名尤其是到了第二层第三层的时候,啥都补全不出来了。

这个时候就会比较折磨,那么多方法接口,得用很多次才能熟悉名称和调用方式,不熟悉的话还得查文档,还有可能敲错单词,这个时候 Copilot 就能展现出它超强的补全能力了。

有了 Copilot,对于传统补全无能为力的接口,也能做到打一个首字母按 Tab 键就补全整个方法名了,还经常会获得额外惊喜:直接帮你把参数填好了(其实有时也会帮你把后面的代码也写了)

下面是 Python 的 SQLAlchemy 库的一个使用场景,这个库 PyCharm 是没办法补全任何方法名的,但 Copilot 能补全方法名并且根据上下文,填入参数实现了筛选功能。

try:
    applys = Apply. # query.filter(Apply.shipName.like(f"%{shipName}%"))
except Exception as e:
    abort(500, description=f"Database Operation Error. {e}")
    return

功能固定的函数:好用

Copilot 毕竟也是学习了那么多代码,基本上你要写的大多数逻辑都被学习到了。比如下面这个 Python 递归遍历当前目录生成文件路径列表的函数,我只输入了函数名,Copilot 就整个补全了:

def get_filepath(dir_path: str, res_list: list) -> list:
    for file in os.listdir(dir_path):
        file_path = os.path.join(dir_path, file)
        if os.path.isdir(file_path):
            get_filepath(file_path, res_list)
        else:
            res_list.append(file_path)
    return res_list

还有基础数据结构与算法的模板,什么二分、并查集、高精度、快速幂、最短路这种比较固定的模板,都可以通过注释来补全,只不过风格可能不是你最常用的那种。

含有复杂逻辑的代码:一塌糊涂

我曾好奇,尝试开着 Copilot 打了一场 CodeForces(不知道这算不算违规,以后不这么干了),想着这玩意做算法竞赛是个啥水准。结果发现这玩意一到复杂逻辑的时候,就一塌糊涂,开始瞎提示乱补全。

它瞎补全的时候,代码一眼看上去有模有样的,形状看起来好像是你心中所想,编译运行都没有报错,但实际上跟你写的题半毛钱关系都没有,输出的也是半毛钱关系都没有。这么搞还会干扰自己的思路,我写了两题就受不了给它关了。

可见 Copilot 只是学习了代码结构,只知道人类一般会在这种代码后面接着写什么代码。但是它一点都不懂为什么要这么写,这个代码的逻辑是什么,所以如果在含有复杂逻辑时它就废了。

并不完美对称的代码:一本正经胡说八道

有些时候,我们的代码并不是要写 x = f(a, b), y = f(c, d) 这种完美对称的代码,但是 Copilot 根据学习,人类写这种代码的可能性最大,你输入了 x = f(a, b) 后,它就会给你补全个看着很优雅对称的结构。

经过你仔细一想,发现其实跟自己想写的完全不一样。因为有时候,我们其实写的是 x = f(a, c), y = f(b, x) 这种奇奇怪怪的并不对称的结构。

总结

经过上面的例子,大家应该也能明白我为什么称其为增强版的代码补全工具而不是 AI 自动写代码了。Copilot 对于重复劳作非常合适,比如你的实验课作业、一些简单的前后端项目等等。但对于思维密集型的代码比如算法竞赛的代码,Copilot 就帮不上什么忙了,甚至还会捣乱。

适合学生群体

我做出这个评价,首先是因为学生要写很多无聊的实验课作业,有的作业一点营养都没有完全是浪费时间,不如赶快水过去把时间花到更有价值的事情上面。

但我觉得更重要的是,它能带你快速入门一门语言或一个第三方库,或者是帮你优化代码的写法。

快速上手一门语言或一个第三方库

比如下面的 Python 函数,用的 Pillow 库对图片做处理:尺寸限制为 2400,转码为 jpeg 格式。

def resample_img(img_path: str, save_path: str, limit: int = 2400, quality: int = 100) -> None:
    with sem:
        img = Image.open(img_path)
        width, height = img.size
        if width > height and width > limit:
            img = img.resize((limit, int(limit / width * height)))
        elif width <= height and height > limit:
            img = img.resize((int(limit / height * width), limit))
        img.convert("RGB").save(save_path, quality=quality)
        print(f"[ ] 已处理: {img_path}")

其中 6、8 行的 .resize 方法是我不知道的,但我把 if 结构写出来后,Copilot 立马知道我想干嘛,给我把它全部补全了。这时我都不需要查询 Pillow 官方文档,就靠 Copilot 帮我写的代码片段作为示例,我就能快速掌握 .resize 这个方法。下面的 .convert .save 也是 Copilot 帮我补全的,节省了我许多学习时间。

优化代码的写法

比如这段代码,查询了数据库。因为这是我第二个后端练手项目,还很生疏,所以我刚开始是不知道要写合法校验的。那可想而知,要是用户查询了不属于自己的数据,那就是平行越权漏洞了,要是用户查了个不存在的船,那后面 apply 就是 None 肯定会抛一堆报错。

try:
    apply = Apply.query.filter_by(applyID=applyID).first()
except Exception as e:
    abort(500, description=f"Database Operation Error. {e}")
    return

好在我写完上面一段的代码后,按下回车,Copilot 立马提示了个 if 语句,我一思考立马懂了我自己的漏洞,然后根据提示把代码完善好了:

if apply is None:
    abort(404, description="Apply Not Found.")
    return
if apply.userID != userID:
    abort(403, description="Forbidden.")
    return

还有一次,Copilot 突然给我提示了个 .first_or_404() 方法,我还很纳闷这是啥,一查才发现是 .first() 和 abort(404) 的合体版,能让代码更简洁清晰,我因此也学习到了新的写法。

因此,Copilot 就像一个见多识广的伙伴,你写代码的时候,它就会说:“诶,我看见不少人是这么写的,你要不学学这样写?” 如果你一看发现很有道理,那你就会学习到大家都这么写的主流写法,提升自己的代码质量。

价格

最重要的,GitHub Copilot 对于高校学生免费啊!这不得白嫖!

(可惜我的学生认证怎么都通过不了,只能自费购买)

潜在缺点

代码合规性问题

由于 Copilot 学习了许多开源软件代码,你要是恰好用到了某个开源代码片段,那是得遵守开源协议的。因此如果是工作场景,Copilot 很有可能折腾出一些麻烦事。但对于学生群体,写自己的小玩意,这种事情完全不需要在意。

代码泄露风险

GitHub 官方说你的私有代码不会被 Copilot 学习,但是,谁知道呢?

但对于学生群体,这种事也是不需要在意。

程序员因此废了

这点其实我个人来说不是很担心,就 Copilot 现在这水平还能替代程序员?另外,Copilot 也不是完全正确,出错是很平常的,一般我是补全后扫一眼看是不是和我想的一样,有时候得改几个单词,因此让程序员不思维而水平变差也是不可能的。

总结

从我目前的学生视角来看,GitHub Copilot 是一个非常优秀的代码补全工具,能够有效提高学习、工作效率,解放程序员的重复劳作、让程序员更专注于代码逻辑而不是体力活。

目前人工智能技术开始从理论走向实践,很多让人耳目一新的产品开始落地,比如 NovalAI 人工智能绘图、OpenAI 的新产品 ChatGPT 语言模型。今后一定有更多前沿技术开始实践,真期待还会有什么精彩的新技术啊。

本文链接:https://www.zouht.com/3139.html
本文使用:CC BY-NC-SA 4.0 许可
# # #
首页      评测      GitHub Copilot 使用体验分享

发表回复

textsms
account_circle
email

颢天

GitHub Copilot 使用体验分享
对计算机技术感兴趣的朋友一定听说过 GitHub Copilot 吧,它是 GitHub 与 OpenAI 合作研发的人工智能代码编写辅助程序。2022 年 6 月 22 日,Copilot 正式上线,可惜当时我手上没什么项目…
扫描二维码继续阅读
2023-01-26