通过分层思维链引导和静态代码分析实现高级软件组件摘要

互联不一般哥 2024-03-28 08:56:37

Achieving High-Level Software Component Summarization via Hierarchical Chain-of-Thought Prompting and Static Code Analysis

Satrio Adi Rukmono1, Lina Ochoa2, Michel R.V. Chaudron3

1Mathematics and Computer Science Eindhoven University of Technology Eindhoven, The Netherlands s.a.rukmono@tue.nl

引用

Rukmono S A, Ochoa L, Chaudron M R V. Achieving High-Level Software Component Summarization via Hierarchical Chain-of-Thought Prompting and Static Code Analysis[C]//2023 IEEE International Conference on Data and Software Engineering (ICoDSE). IEEE, 2023: 7-12.

论文:https://ieeexplore.ieee.org/abstract/document/10292037

摘要

对软件系统的抽象理解是其成功维护和演化的关键。这种理解来自不同的抽象层次:在较低的层次上,人们必须专注于理解功能;而在高层,人们必须抽象和理解系统的需求。多元自动源代码摘要(ASCS)技术已经被提出来理解较低层次的系统。然而,用于抽象更高层次解释的技术存在不足。相关领域的研究,如软件架构恢复,试图通过尝试从源代码中检测设计决策的抽象来解决更高层次的系统理解。然而,这是一个持续的努力,过程中的许多步骤仍然没有得到解决。在本文中,我们利用大型语言模型(LLMs)的涌现能力,结合ASCS和静态代码分析领域的成就,设计了一种生成软件系统组件级摘要的方法。特别是,我们通过应用思维链提示策略来解决LLMs在执行推理时的不可靠性,这使我们能够模拟归纳推理。我们遵循一种自下而上的方法,从理解较低层次的软件抽象(例如,函数)开始,然后我们以级联的方式组合这些发现,以理解更高层次的(例如,类,组件)。我们通过将其应用于开源Java项目JHotDraw version 5.1来证明我们的方法的可行性。我们相信,我们的方法为开发健壮的自动化软件摘要方法提供了一个垫脚石,这种方法可以普遍应用于跨领域和软件系统类型。

1 引言

对软件系统的理解对于其有效的演化和维护是必不可少的。Biggerstaff等人指出,理解一个程序涉及到解释它的结构、行为、对它的上下文的影响以及它与它的领域的关系,这些术语与源代码的标记有质的不同。换句话说,理解一个软件系统需要处理超越代码结构(如表达式和语句)的抽象级别。除了语句之外,仍然处于较低的抽象层次,程序员可能需要理解函数级别的代码才能正确使用它。在更高的层面上,架构师可能需要掌握软件组件的用途,以满足不断变化的需求。随着软件的发展,理解,尤其是更高抽象的理解,变得更具挑战性。此外,随着系统的发展,它们的概念完整性会降低——由于遗留和技术债务的噪音而隐藏了意图。

自动化技术存在于分析和总结软件片段。这些代码摘要技术以较低的抽象操作,通常依靠静态分析从语法推断语义。虽然这些技术可以帮助验证一个函数是否满足其形式规范(例如,range(min, max, value)是否正确地将输入值限制在给定范围内),但它们对于争论高级规范(如“系统必须允许对几何形状执行操作”)的用途有限。软件的独特性质要求定制分析,阻碍了一般适用于不同领域和软件系统类型的高级摘要技术的发展。我们认为,这种更高层次的分析需要一种根本不同的方法。

大型语言模型(Large Language Models,LLMs)提供了健壮的文本摘要,包括源代码。然而,LLMs在推理方面遇到了困难,尤其是归纳推理。例如,OpenAI的CHATGPT经过预训练,可以使用公开可用和授权数据来预测文档中的下一个token。换句话说,它将输入的文本或指令(一个“提示”)映射到其最有可能的延续或响应,而不需要任何正式的推理,即使结果背后似乎有原因。这妨碍了它用于适当的更高层次的摘要。然而,思维链方法可以指导LLMs模拟推理。

本文提出了一个新的方向来实现软件系统的高层次自动摘要:一个结合自动化源代码中的发现摘要和静态程序分析领域,以及LLMs的“伪推理”。我们将软件源代码、标识符和模型作为输入,使用思维链提示来执行分层的、自底向上的汇总。这种方法在JHotDraw 5.1项目中进行了演示。我们相信这种方法可以成为推进分层软件组件摘要领域的坚实基础。

2 技术介绍

在本节中,我们将介绍我们执行模块级和组件级摘要的方法。我们的方法使用级联循环实现了思维链提示,以提供更高级别的摘要。图1描述了该方法的概述。该方法的细节将在以下小节中描述。

图1:所提出的“循环”方法概述

2.1 概念定义

软件操作表示具有定义良好的功能的细粒度代码片段,可供其他代码片段(重用)使用。例子包括子程序、函数、过程或方法。

一个软件模块表示包含软件操作集合的一段代码,表示这些操作属于一起。模块的可能实例是类或文件。

一个软件组件是一个软件模块的集合,由特定的标准确定,为了一个共同的目标而紧密地工作在一起。这些标准可以产生于设计,工程师在设计中对组件的目的做出决定,从而直接基于这些决定来实现模块。组件可能从开发的角度出现,其中模块被逻辑地组织成包或目录。反向工程也可能揭示组件,作为一起工作的模块集群,通过软件架构恢复技术确定。在协同作用下,软件组件相互作用形成一个完整的软件系统。

我们使用父子两个术语来表示相邻抽象层次之间的关系。当组件A包含模块X和Y时,我们将组件A指定为X和Y的父模块,而将模块X和Y指定为组件A的子模块。

因此,我们提出了软件抽象的层次结构。在最高层次上,软件系统由组件组成,这些组件包含模块,模块又反过来封装操作。

2.2 相关领域

当涉及到生成更高层次的软件系统摘要时,不同软件领域的研究可以作为实现这一目标的支架。在本节中,我们将介绍其中的一些领域,并说明它们与我们研究的关系。

自动源代码摘要(ASCS): ASCS是使用计算系统来提供代码片段的摘要,通常使用自然语言。这些摘要通常用于增加对软件系统的理解,从而方便其维护。ASCS输出可以用来提供软件系统的更高层次的解释。然而,一篇文献综述显示,大多数现有的摘要技术工作在语句、操作或模块级。据报道,只有Hammad等人的研究能够在组件级进行摘要。这种摘要是通过集成属于包的(Java)方法的摘要来实现的。然而,这种集成主要采取方法描述列表和附加统计信息的形式,如包内抽象方法和最终方法的计数;缺少组件的内聚的更高层次的描述。当使用ASCS提供软件系统的高级摘要时,文献中的挑战和现有差距是总结系统及其组件的总体远景,而不仅仅是关注粗粒度的代码模块。

大型语言模型(Large Language Models, LLMs)和思维链提示: LLMs是参数大小超过千亿的深度学习模型,可以执行一组自然语言处理任务。这些模型经过大量数据的训练,能够基于自监督学习预测句子中的下一个token。随着LLMs的出现,不同的研究提出了它们在ASCS中的应用。在ASCS方面,CodeBERT、CodeT5和CHATGPT等多种LLMs已经对代码摘要进行了微调。后者特别吸引人的特性之一是它能够开启对话,并考虑以前的聊天历史以获取未来的答案。特别是,有证据表明,可以通过提供思维链提示来模拟复杂的推理。思维链提示是LLM通过一系列中间步骤解决复杂问题的一种策略,类似于人类推理。因此,这种类型的提示技术可以用于编排ASCS技术,支持生成更高级别的软件系统摘要。

2.3 方法细节

2.3.1 准备阶段

准备阶段的初始步骤涉及确定所讨论的软件系统的抽象级别。一旦建立了层次结构,就可以使用静态分析技术,如Rascal或srcML (两者都支持多种语言,包括C、C++和Java)、CodeOntology或javapers (用于Java)等工具,从源代码中提取层次结构。

2.3.2 摘要循环

在这个阶段,我们在选定的LLM上执行思维链的级联循环提示。第一步是生成软件操作的摘要1。然后这些操作摘要被用来构造提示,以便LLM总结它们的封闭模块。这个过程在层次结构中继续向上:模块摘要用于总结它们的封闭组件。

LLM和静态分析之间存在相互作用:从源代码中提取的信息指导上下文,其中LLM必须响应查询。具体来说,这种提取的信息与标识符名称和系统的层次结构有关,例如哪些模块属于哪些组件。

1、原子摘要

在“原子”抽象级别,即软件操作,存在用于生成摘要的既定方法。LLMs可以生成基于源代码的摘要,展示出对操作特征的强大掌握。总结周期的初始步骤如图 2 所示。(后续图中提供的提示是说明性的,提供了向 LLM 询问什么内容的一般概念。我们建议在实际提示中使用特定于语言的术语。)

图2:生成软件操作摘要的提示模板。在大括号之间,我们放置从静态分析中提取的信息

2、组合摘要

我们的贡献始于这样一个前提:软件模块本质上应该构成一个有凝聚力的操作集合。因此,可以通过总结其组成操作摘要来构建模块摘要,如图 3 所示。此概念扩展到更高的抽象级别,例如组件是其模块的内聚集合。这个假设促进思维链提示策略的应用。

图3:从模块的组成操作的摘要中构建模块摘要的图示

图 4 中概述了此步骤的模块摘要。总结一下组件,就是用组件代替模块,用模块代替操作。

图4:提示模板,用于从其组成操作的摘要中生成软件模块的摘要。

3、聚类模块和操作

可选地,可以采取步骤将模块内的操作聚集到位于模块和操作之间的中间级类别中。这种方法通过建立“模块职责”集来增强摘要,每个“模块职责”由多个操作支持。

作为一个简化的示例,管理项目列表的软件模块可能具有四种操作:(1)“在列表前面添加项目”,(2)“在列表后面添加项目”,(3)“从列表前面删除一个项目”,(4)“从列表后面删除一个项目”。将这些操作分为两个职责(“添加项目”和“删除项目”)可以增强模块的摘要。

LLMs擅长文本聚类和分类。可以通过列出操作及其摘要,然后提示LLMs形成相关操作组来利用此功能。生成的操作簇可以成为在生成组件摘要的摘要周期中提供给LLM的单元摘要的一部分。聚类操作的步骤如图5所示。

图5:提示模板将模块的操作聚类为职责

遵循级联思想链的思想,将模块聚类为子组件同样可以通过用组件代替模块、用模块代替操作、用子组件代替职责来实现。

3 实验评估

3.1 实验设置

为了证明我们方法的可行性,我们将其应用于Java项目JHotDraw版本5.1。我们选择这个项目是因为我们对它的熟悉,因为它经常作为软件工程研究中的案例研究。所选择的抽象层次在表I中概述。我们专注于公共方法而不是所有方法,因为私有方法包含类如何工作的细节,我们可以将其省略为高层次的总结。我们考虑在类中定义的公共方法,排除没有被覆盖的继承方法。

表I JHotDraw项目的抽象级别

JHotDraw项目包含11个组件、146个模块和942个操作,平均每个模块执行大约13个模块,每个模块执行大约6个操作。关于组件中的模块和模块中的操作的详细分布,请参考表II。

表II JHotDraw的操作、模块和组件的描述性统计

3.2 实验过程

我们使用javapers提取项目的层次结构,生成带有我们需要的信息的标记属性图:包、类和方法作为节点,父子关系作为边。节点包含摘要生成所需的属性:包、类和方法名称,以及方法源代码。

随后,我们启动摘要循环。我们选择OpenAI的GPT-3.5模型作为其已知的文本摘要能力。具体来说,我们通过聊天完成API使用gpt-3.5-turbo-0613版本,温度参数为0,用于集中和确定的结果2。我们从方法总结开始,如图6中的一个示例所示。

图6:用于总结方法的提示和响应示例,以及实际的文档注释

为了确保摘要完全基于实现,我们在构造提示之前排除了源代码注释。此外,代码中的Java类引用被替换为完全限定的名称(例如,List变成Java .util.List),以便为LLM提供上下文。

该提示指示法学硕士以祈使语气提供一句话文档注释,限制长度并保持风格一致性。图中提供了程序员的实际文档注释,以供对比。对于类级别摘要,我们将摘要和聚类合并到单个提示中(图 7)。该提示请求类文档注释和按职责分组的方法。我们以一种思维链的方式指导法学硕士以计算机可读的格式构建响应,以帮助组织我们的实验结果。在 Geom 类的示例提示中,LLM 从 15 个方法中生成了 4 个职责。

图7:总结一个类并一次性聚类其方法的提示和响应示例,以及实际的文档注释说到包摘要,我们排除了类聚类。图8提供了一个示例提示、响应和实际文档注释。

图8:一个总结包的提示和响应的例子,以及实际的文档注释。

3.3 未来展望

我们提出了一种自动化软件组件摘要的方法,将静态分析与大型语言模型(LLM)的新兴能力相结合。我们在一个Java项目上的概念证明演示的初步结果已经产生了软件操作(方法)、模块(类)和组件(包)的摘要。我们将这种方法定位为迈向普遍适用的、层次化的软件组件摘要的初始步骤。

对于增强软件理解的后续阶段,我们即将进行的工作概述如下。

摘要评估:鉴于自动摘要的主要目标是增强理解能力,我们建议通过让参与者参与基于这些摘要的理解任务来评估生成的摘要。这与Stapleton等人在研究中概述的方法一致。在组件级别,可以向参与者提供组件列表及其描述,而不泄露项目的背景。随后,他们可以被赋予以下活动的任务:制作一个一句话的项目描述,确定与实现特定功能或解决特定bug相关的组件,以及处理类似的查询。

组件的选择:经过更仔细的检查,很明显,在案例研究JHotDraw中有几个不同的包展示了类似的文字摘要,包括“创建”、“操作”、“绘图”和“图形”等术语。我们认为这是由于JHotDraw的原始开发人员所定义的包中缺乏内聚。一些包包含的类与来自其他包的类交织在一起。例如,在CH.ifa.draw.contrib中的类被分组在一起仅仅因为它们是由主开发者以外的开发者贡献的。再举一个例子,包CH.ifa.draw.util由于包含了主要是“杂项”类,所以有很长的总结。为了进一步加强我们的调查,我们打算对使用逆向工程方法识别的组件进行实验,旨在评估当组件表达更大内聚时摘要的质量。

集成到工作流程中:我们提出的方法,连同其他源代码摘要技术,有可能帮助程序员编写和维护文档注释。采用的逻辑进程将涉及开发集成开发环境(IDE)插件,该插件包含此类技术。这个插件可以无缝地集成到软件开发人员的工作流程中,使他们能够根据需要创建或更新文档注释,同时仍然保留手动编写注释的能力。

转述:朱民笑

0 阅读:0

互联不一般哥

简介:感谢大家的关注