“人工智能生成的代码需要更多测试吗?”
人工智能生成的代码需要进行更多的测试吗?
AI 助力编写代码的工具,如 GitHub Copilot,在软件开发中越来越受欢迎。这些工具承诺提高生产力,但也有人声称它们通过允许非程序员编写应用程序,实现了编程的民主化。
但我们如何实际上知道由 AI 工具编写的代码是否适合其目的呢?
在接下来,您将了解“适合其目的”是什么意思,以及您可以使用哪些工具来评估它。我们将看到,AI 助力编写代码的工具不能保证代码的功能正确性和安全性。然而,我们也将看到,实际上有一些 AI 工具可以支持您回答上述问题。
回顾历史
值得一提的是,我们先回顾历史一点,因为这个问题并不陌生:我们一直都必须问自己,“我们如何实际上知道由人类编写的代码是否适合其目的?”人们在软件工程领域一直苦恼地寻找解决办法,解决这个根本问题。
- Google DeepMind揭示了Lyria:一款具有突破性的AI音乐生成器和创意游乐场
- SnapLogic如何利用Amazon Bedrock构建了一个文本转换应用程序,将商业意图转化为行动
- 通过自动关闭空闲应用程序来优化Amazon SageMaker Canvas的成本
从可编程计算机系统的早期阶段开始,当程序无法按照意图运行时,工程师们就经历了一些令人不快的惊喜。那时,通过试错来获得正确的程序花费很高。低级别的代码需要手工编写并打孔到卡片上。无需重复试错是节约成本的主要对策。代码审查就是让专家阅读并试图理解代码的作用,以便发现错误并提出改进建议-这是一种成功的技术,如今仍被广泛应用。然而,随着程序规模和复杂性的增长,审查的效果以及彻底进行审查所需的努力都大幅降低,成本则大幅上升。
很快,一个问题出现了,即如何以更严谨的方式判断程序是否按照其预期运行。挑战是如何表达程序应该达到的预期。需要以某种方式向机器传达用户的实际需求。这是一个非常具有挑战性的问题,如今仍然没有完全解决。
这个问题是产品工程领域的共同问题,并分为两个步骤,通常形式化为以下问题:
- 我们是否构建了正确的产品?
- 我们是否正确地构建了产品?
验证和验证
评估是否构建了正确的产品被称为验证。最终用户验证产品是否实现了其预期的目的。验证始于需求规格说明,它作为产品开发者与用户或客户之间的沟通手段。规格说明应该被双方理解:用户(领域专家)和工程师(可能不是领域专家)。验证相当于评估产品的实现是否符合需求规格说明。验证显然是更困难的问题。什么是“正确”的产品在很大程度上是主观的,并且很难自动化。
好消息是,验证部分可以完全自动化:在原则上,符合计算和复杂性理论的限制。简而言之,可以在数学上证明实现满足规格说明。这门学科称为形式方法或形式验证,依靠基于逻辑的形式化方法编写规格说明,并使用自动推理进行证明。
尽管听起来很有希望,但主要问题依然是谁编写规格说明。这需要一个既是领域专家又是写作规格说明专家的人,而这类人很难找到且非常昂贵。即使找到这样的人并成功验证了实现,仍然需要面对问题的验证部分,即规格说明实际上是否从用户的角度描述了正确的产品。
通常有人观察到规格说明相比实现来说常常“更错误”,因为编写准确的规格说明极为困难。将自动推理应用于大型系统仍然是巨大的挑战。实践中,形式验证已在嵌入式控制、加密、操作系统内核和智能合约等小型、复杂且关键(安全、保密、金融)软件领域找到了一席之地。
不同视角
上世纪70年代,有一种从不同角度解决该问题的思路,即N 版本编程。基本思想是由于编写程序和甚至规格说明都非常困难,因此让多个独立的团队实现系统,然后对输出进行投票。基本假设是不同的团队会犯不同的错误;他们可能对需求规格说明也有不同的理解。因此,总体而言,结果在验证和甚至验证方面预期会比单个实现更“正确”。然而,后来的研究发现这一假设是错误的:即使是独立的团队也会犯相同的错误。
这种方法的遗产是验证可以被视为2版本编程:需求规范和实现是同一枚硬币的两面。它们以不同的形式和观点以不同的方式描述相同的系统。此外,它们通常由不同的人或团队编写。规范在任何意义上都不比实现“更正确”,反之亦然。这种思维方式可以引导我们对实践中可以实现的内容有一个现实的认识。
那么,为什么我们需要同时拥有规范和实现呢?好处来自于2版本编程:比较相同系统的两个描述允许我们在它们彼此一致的地方增加信心,并在它们冲突的地方发现错误,使我们能够反思两个描述,并最终得到“更正确”的描述。
测试是一种验证技术
现在,一些读者可能会插话:我们没有规范,所以我们做不到。这与我们何干?您可能没有一个完整的需求规范,但您可能会对软件进行测试。确实,我们还没有讨论过测试。在我们的讨论背景下,测试实际上在做什么?
测试是一种验证技术。测试检查您的实现,您测试中的断言就是规范。有多少次你发现错误并不在实现中,而是在测试中?这不足为奇,因为测试就是2版本编程。因此,具有良好的测试实践,包括对高级需求进行端到端测试和对低级需求进行全面的单元测试,确实增加了交付正确产品的信心。那关于基于模型的工程呢?是的,它也是具有相同属性的2版本编程。
那么,我们需要更多地测试由AI编写的代码吗?
评估由AI工具编写的应用程序是否真正符合目的与评估人类编写的代码的情况一样困难 – 虽然生成的AI代码创建工具绝对需要开发人员进行审核。困难的部分在于回答验证问题:进行此评估的人必须是应用领域的专家。
自动编写测试的工具可以在这个过程中帮助您,因为它创建的测试为您提供了代码的行为输入输出视图。例如,我是一个名为Diffblue Cover的自动化测试编写解决方案的合著者。它不猜测 – 它直接告诉您代码实际在做什么,从而帮助您评估验证和验证问题。这些测试可以作为回归测试的基准,当您对代码进行更改时 – 无论是由人还是机器编写的。
非程序员在他们的应用领域专家将很有可能从用于编程应用的AI工具中获益。但是,他们需要意识到,例如GitHub Copilot等工具编写的实现并不是通过构建“正确”完成的 – 功能正确性和安全属性并没有内置到它们使用的底层模型中。即使对“正确”的代码进行了训练(我们现在知道这意味着很少,因为企业开发人员不会没有仔细审查AI生成的代码就将其推到生产中),以及安全代码,这些属性也不会通过训练和模型评估保留。
AI来拯救AI
AI驱动的工具使得编写有功能的应用程序变得容易。然而,应该预料到应用程序代码将遭受与人类编写的代码类似的问题。因此,您需要在测试和质量保证方面采用和人类编写代码一样的严谨程度。结合自动编写测试的AI工具,可以增加对进程的信心,该工具可以保证其产生的测试描述了代码的实际行为。


