Clover - 通过闭环可验证的代码生成确保可信AI生成的代码 原创
尽管近年来大型语言模型(LLM)在代码生成方面取得了惊人的成功,但这种由人工智能生成的代码的可信性仍然是一个问题。为了解决这个问题,研究人员提出了Clover模式,即闭环可验证代码生成,通过检查代码、文档字符串和注释之间的一致性,强制执行AI生成的代码的正确性。
在软件开发中,利用大型语言模型(LLM)进行代码生成是一个快速发展的趋势。然而,如果没有有效的方法来确保AI生成的代码的正确性,这一趋势可能导致不可取的结果。在这项工作中,研究人员引入了一种名为Clover的模式,即闭环可验证代码生成,以解决这一挑战。Clover将正确性检查降低到更容易解决的一致性检查问题,并保护LLM驱动的代码生成免受可能造成昂贵错误的影响。
Clover的核心是一个检查器,它在代码、文档字符串和形式注释之间执行一致性检查。该检查器使用形式验证工具和大型语言模型的新颖集成实现。研究人员通过实证研究在一个手工设计的数据集(CloverBench)上验证了其可行性,该数据集包含在教科书水平的带注释语言中的注释程序。实验结果表明,对于该数据集,(i)LLM在自动生成形式规范方面取得了合理的成功;(ii)一致性检查器在正确实例上实现了一个有希望的接受率(高达87%),同时对于错误实例保持零容忍(没有误报)。
正式验证和人工智能是一对良好的搭档
大语言模型(LLM)最近展示了令人瞩目的能力。它们可以进行对话、检索和总结大量信息、生成和解释文本和代码等等。在众多可能的应用中,它们基于自然语言描述合成代码的能力令人惊叹,有可能极大地提高程序员的生产效率。
然而,在实现这一未来之前,必须克服一个根本性的挑战。目前还没有一种可靠的方法来确保AI生成的代码的正确性。目前对于AI生成的产物的最佳实践是让人参与其中,例如Copilot。虽然这比没有人工参与要好,但人工监督是昂贵且效率低下的,长期来看难以扩展。
可以预见,在未来几年中,策划AI生成内容的质量将成为最关键的研究问题之一。首先,生成的代码必须在功能上是正确和可靠的。代码中的错误或漏洞可能导致软件故障,尤其是在医疗软件、金融系统或自动驾驶车辆等关键系统中,这可能具有成本高昂、危险或两者兼而有之的后果。此外,如果生成的代码不可信,可能会在软件中无意中引入安全漏洞。这可能被恶意实体利用,导致数据泄露、侵犯隐私和其他安全事件。幸运的是,在代码生成的特定情况下,正式验证可以对任意代码的质量和正确性提供数学上严格的保证。如果有一种方法可以自动将正式验证应用于生成的代码,这不仅提供了可扩展的解决方案,还有可能为AI生成的代码比人工编写的代码更可靠的未来铺平道路。
目前,正式验证只能依靠人类专业知识实现。本研究的主要假设是,LLM能够生成所需的附属信息,以帮助正式验证成功,同时不损害正式方法提供的形式保证。
目前,正式验证只能在耗时的人类专业知识的帮助下实现。在典型的正式验证过程中,构建系统的数学模型后,人类专家提供了系统的正式规范(见清单1),该模型满足规范。对于代码,已经存在一些工具(例如Dafny),可以证明某个输入规范满足某个输入代码。传统上,需要大量的人类专业知识来创建正式规范,并确保规范在内部一致且准确捕捉到预期的功能。
基于基于AI的代码生成技术的输出应该包括代码、正式规范和自然语言文档字符串。然后,可以使用形式工具与生成的AI技术相结合,确保它们是一致的。这种方法被称为Clover,即闭环可验证代码生成。
Clover模式包括两个阶段。在第一阶段(生成阶段),创建带有正式规范(注释)和自然语言文档字符串(文档字符串)的代码。在第二阶段(验证阶段),对代码、注释和文档字符串进行了六个一致性检查。如果一致性检查通过,则表示(i)代码在功能上与其注释一致;(ii)注释完整地捕捉了代码的功能;(iii)文档字符串也准确地反映了代码的功能(见图1)。
这个想法是可以利用越来越强大的生成式AI技术在生成阶段,然后使用验证阶段作为一个强大的过滤器,只批准经过形式验证、文档准确、内部一致的代码。
Dafny
Dafny是评估中使用的编程语言。Dafny的后端包括一个编译器,能够生成可运行的二进制文件,以及一个验证器,可以形式化地检查代码是否符合其规范。清单1列出了一个用于找到自然数平方根的Dafny函数,包括三个组成部分(文档字符串、注释和代码)。
Clover 第一阶段:生成
研究人员首先展示了 Clover 中生成阶段可以生成带有注释和文档字符串的代码。具体而言,研究人员使用 OpenAI 的 GPT-4 进行实验。图2a展示了在不同条件下,当 GPT-4 被要求为 CloverBench 中的每个例子生成代码时的结果。第一个柱状图("one try")显示了单次尝试的结果。下一个柱状图允许 GPT-4 尝试三次,每次提供 Dafny 编译器和验证器的输出作为反馈。第三个柱状图类似,但只使用了 Dafny 编译器的输出。在最后一个柱状图中,允许三次尝试,并且还提供了文档字符串。图2b展示了当提供代码时,要求 GPT-4 生成注释的结果。虽然不是完美的,但 GPT-4 在大多数程序中可以生成正确的注释。这表明使用 LLM 进行规范生成是可行的。
Clover 第二阶段:验证
Clover 期望生成阶段的输出包含三个组成部分:代码、注释和文档字符串。它还期望每个组成部分提供足够的细节,以明确确定在任何给定输入上运行代码的唯一结果。验证阶段检查每对组成部分的一致性,如图1所示,只有当所有检查都通过时才会成功。
具体而言,总共有六个检查:
- (1)anno-sound:一种演绎验证工具(评估使用 Dafny)检查代码是否满足注释。
- (2)anno-complete:根据注释,使用 LLM 生成新的代码,然后检查生成的代码与原始代码的等价性。
- (3)anno2doc:要求 LLM 根据注释生成新的文档字符串,然后使用 LLM 检查新的文档字符串与原始文档字符串的语义等价性。
- (4)doc2anno:要求 LLM 根据文档字符串生成新的注释,然后使用形式工具检查新的注释与原始注释的逻辑等价性。
- (5)code2doc:要求 LLM 根据代码生成新的文档字符串,然后检查新的文档字符串与原始文档字符串的语义等价性。
- (6)doc2code:要求 LLM 根据文档字符串生成代码,然后检查新的代码与原始代码的功能等价性。
重构测试
在每个检查中,重构原始构件是关键。给定三个组成部分(代码、文档字符串、注释)作为输入,研究人员尝试从一个构件中重构出另一个构件,然后检查重构结果是否等价于原始构件。
在下图中,将屏蔽的函数签名和注释提供给 GPT4,并解析生成的代码。
等价性检查
用于代码的标准等价性检查包括输入输出比较、符号执行测试,甚至是完整的形式等价性检查。评估使用作为 CloverBench 数据集的一部分包含的单元测试。检查文档字符串的等价性是具有挑战性的,因为自然语言不是数学上精确的。在评估中,要求 GPT-4 检查两个文档字符串是否语义上等价。为了检查两个注释的等价性,将两个注释的等价性写成一个形式引理,并要求 Dafny 证明该引理。
在下图中,测试文档字符串的等价性。
在不同领域中有几个受欢迎的代码生成数据集,但没有一个包含注释或使用 Dafny 语言。研究人员引入了一个新的手工制作的数据集,称为 CloverBench。在撰写本文时,它基于60个小型手写示例程序,类似于标准计算机科学教科书中的示例,例如选择排序。对于每个程序,有四个变体:一个地面真实的变体,其代码、注释和文档字符串都是正确和一致的(经手工验证);以及三个不正确的变体。
评估一致性检查算法
主要实验评估了 Clover 一致性检查算法的能力。对于 CloverBench 中的每个示例,研究人员运行上述描述的所有6个检查。评估多次独立运行的效果,这意味着将每个6个检查重复 k 次。端到端的结果总结在表1中。当 k=1 时, Clover 实现接受了60个正确(地面真实)示例中的45个,并拒绝了所有不正确的示例。当 k=10 时,Clover 接受了60个正确示例中的52个,并拒绝了所有不正确的示例。
结论
本文介绍了 Clover,一个用于闭环可验证代码生成的框架。研究人员将检查正确性的问题简化为检查一致性的更容易解决的问题。
使用 GPT-4、Dafny 和一组简单的教科书示例的初步实验结果是令人鼓舞的。本文展示了87%的地面真实示例接受率和100%的不正确示例拒绝率。未来的工作可能集中在设计更好的验证工具、改进代码/注释/文档字符串生成质量、改进 LLM 对 Dafny 语法的理解,或者扩展到更具挑战性的示例上。
译自(有删改):https://ai.stanford.edu/blog/clover
本文转载自公众号AIGC最前线