声明:本文来自于微信公众号 新智元(ID:AI_era),作者:新智元,授权Soraor转载发布。

【新智元导读】6月,IEEE刊登了一篇对ChatGPT代码生成任务进行系统评估的论文,数据集就是程序员们最爱的LeetCode题库。研究揭示了LLM在代码任务中出现的潜在问题和能力局限,让我们能够对模型做出进一步改进,并逐渐了解使用ChatGPT写代码的最佳姿势。

有了ChatGPT,还需要人类程序猿编码吗?

上个月,一项发表在IEEE TSE期刊(Transactions on Software Engineering)上的研究评估了ChatGPT所生成的代码在功能性、复杂性和安全性方面的表现。

结果显示,ChatGPT生成可用代码的能力差异很大。

其成功率从0.66%到89%不等,这主要取决于任务的难度、编程语言等多种因素。

image

论文地址:https://ieeexplore.ieee.org/document/10507163

具体来说,研究人员测试了GPT-3.5在5种编程语言(C、C++、Java、JavaScript和Python)中,解决LeetCode测试平台上的728个编码问题,以及应对18个CWE(常见缺陷枚举)场景的能力。

虽然在某些情况下,AI能够生成比人类更优质的代码,但分析也揭示了,一些AI生成代码的安全性问题。

论文作者、格拉斯哥大学助理教授Yutian Tang指出,「AI代码生成一定程度上,可以提升开发效率,自动化软件工程。然而,我们必须认识这类模型优势和不足,以便合理应用」。

「通过全面的分析,可以发现ChatGPT生成代码过程中,出现的潜在问题和局限性,进而改进生成技术」。

image

有网友庆幸地发出疑问,所以我还没有被解雇?另一人对此表示,至少不是今天。

image

还有人指出,这项研究是关于GPT-3.5的评估。要是GPT-4早就在编码能力上大幅提升,Claude3.5更是如此。

image

image

确实,现在我们有了更好的模型,对于GPT-3.5模型的评估,并没有太大的意义。

image

0.66%-89%,惊人反差率

总体而言,ChatGPT在不同编程语言的问题上表现相当不错——特别是在尝试解决2021年之前LeetCode上的编码问题时。

例如,它能够为简单、中等和困难的问题生成可运行代码,成功率分别约为89%、71%和40%。

然而,当涉及到2021年之后的算法问题时,ChatGPT生成正确运行代码的能力受到影响。即使是简单级别的问题,它有时也无法理解问题的含义。

比如,ChatGPT在生成「简单」编码问题的可运行代码方面的能力,在2021年后从89%下降到52%。

而它在生成「困难」问题的可运行代码方面的能力也在此时间后从40%下降到0.66%。

Tang对比表示,「一个合理的假设是,ChatGPT在2021年之前的算法问题上表现更好的原因是这些问题在训练数据集中经常出现」。

接下里,具体看看研究者们对ChatGPT进行了哪些方面的评估。

实验评估

评估的整体流程如图2所示。

首先为给定的LeetCode问题或CWE场景构造合适的提示并发送给ChatGPT,让它根据提示和上一轮对话的上下文信息给出响应。

之后,研究人员将模型响应中的代码片段提交给LeetCode平台,利用其在线判断功能来检验代码的正确性,CWE漏洞则使用CodeQL进行手动分析。

如果测试结果通过,则生成结束,否则就需要利用LeetCode和CodeQL的反馈继续建立新的提示、输入给ChatGPT,再次进行代码生成。

如果ChatGPT在对话轮数限制(5轮)之内始终没有生成出通过测试的代码,则认为生成任务失败。

image

ChatGPT生成的代码在功能上是否正确?

研究动机:

给定提示,ChatGPT生成相应的文本,这种能力可能会提高开发者的生产力。首先去评估ChatGPT在单轮对话中,自动生成功能正确代码的能力。

研究方法:

  • 让ChatGPT阅读问题描述,在单轮对话中生成相应代码。(最大对话轮数设为1)

  • 使用LeetCode平台上的编程问题作为数据集,截止研究时,有2500个难度不等的问题。

  • 将LeetCode所有问题分为2021年之前(Bef.problems)和2021年之后(Aft.problems)两类,因为ChatGPT的训练数据截止于2021年。

  • 考虑到2021年之前的问题可能已存在于ChatGPT的训练集中,这可能使代码生成任务退化为简单的数据库查询(即代码复用)。为了进行全面评估,研究中同时考虑了这两类问题。

具体而言,研究人员重点关注LeetCode上的算法问题,因为算法问题是该平台上最重要、最多和最多样化的问题。

Bef.problems和Aft.problems的总数分别为1624个和354个。此外,两者的难度分布为难、中、易,比例为1:2:1。

在所有Bef.problems中,作者随机抽取了374个问题,其数量与Aft.problems相似,难度分布也与Aft.problems相同。

同样,在354个Aft.problems和Bef.problems中,难、中、易问题的数量比例也是1:2:1,与LeetCode平台上所有问题的难度分布一致。

此外,研究人员还检查了Bef.problems和Aft.problems之间是否存在显著差异。

如果Aft.problems只是Bef.problems的重构,那么ChatGPT很可能可以轻松解决这些问题,这可能会影响实验结果在区分时间段方面的可靠性。

论文中,作者总共找到了142对问题。然后,再让2名研究生独立检查这些问题对。

通过仔细核对和讨论,结果发现这些相似的问题要么情景相似,但求解目标完全不同;要么情景和条件不同,但可以使用类似的算法(如动态编程)求解。

经过仔细的人工分析,作者没有发现在任何情况下,Bef.problems可以很容易地重新表述为Aft.problems。

因此,作者认为Aft.problems和Bef.problems之外,对于每个问题,都要求ChatGPT用5种不同的语言生成代码:C、C++、Java、Python3和JavaScript。

此外,他们还使用相同的提示模板为每个 < 问题、语言> 对创建了相应的提示。

Bef.problems和Aft.problems分别共有1,870和1,770个提示。由于ChatGPT的查询速度有限,研究者将每条提示输入一次,要求生成代码。

然后,研究者将解析后的解决方案,提交给LeetCode进行功能正确性判断,并得到提交状态,包括接受、回答错误、编译错误、超过时间限制和运行错误。

它们分别对应于A.、W.A.、C.E.、T.L.E.和R.E.。一个问题对应一个唯一的对话,以避免从其他问题触发ChatGPT的推理。

实验中,作者以状态率(SR)来评估 ChatGPT 的代码生成能力。其中和

image

image

分别是根据状态生成的代码片段数和输入的提示数。

image

提示:

所设计的提示模板由4个部分组成:它们分别是