审校 | 重楼
对于开发人员来说,逐行仔细地检查代码并试图掌握算法背后的复杂逻辑可能是一项繁重乏味的任务,特别是在处理大型和复杂的代码库时。由于大型代码库使得识别所有潜在的测试场景变得困难重重,因此这种方法既耗时又令人不堪重负。幸运的是,代码图形工具可以将这个过程实现自动化,并通过图形方式呈现代码,从而简化了任务并提高整体效率。
本文将探讨代码图的概念,它们如何增强代码分析、简化调试和促进影响分析,以及介绍一些能够简化这些任务的工具。还将讨论当前代码分析解决方案面临的挑战,以及使用知识图相对于向量数据库在代码分析方面的优势。
什么是代码图?
代码图直观地表示代码库中的结构关系。它将函数、类和变量映射为节点,并将它们之间的关系(例如函数调用、类继承和变量依赖)映射为边。这种结构化表示通过使复杂的代码库更容易理解和导航来增强代码分析。
代码图可以作为路线图,清晰地展示代码的不同部分如何组合在一起。为了帮助实现这一概念,一些工具能够更轻松地实现可视化和导航代码。例如,Visual Studio(2012-2017版)的可视化工具就使用代码图使用户能够更方便地探索代码。
将代码表示为图形已在编译器和集成开发环境(IDE)中广泛用于各种任务。将代码的图形结构呈现给任何Graph ML算法都会创建SOTA结果。函数、类和变量可以是代码库中的节点。边可以表示函数调用、变量使用或类继承。例如,表示函数的节点可能有指向表示它所使用变量和它所调用函数的节点的边。如图1所示:
图1 链接到两个函数的代码图节点
代码图表示允许对代码的结构和行为进行详细的分析,从而便于完成代码导航、影响分析和调试等任务。通过将代码表示为图形,捕获了关于代码的不同部分如何交互的复杂细节,从而使分析和理解复杂的代码库变得更加容易。这是如何实现的?
将代码分为以下元素:
- 定义:定义事物(如函数、类、变量)的地方。
- 引用:这些事物被使用或调用的地方。
- 符号:代码中元素的名称(例如函数名和类名)。
- 文档注释:解释代码的注释,通常以特定格式编写。
接下来,将看到如何为给定代码生成图形的示例。
代码图如何增强代码分析
代码图为代码分析提供了几个好处:
依赖关系可视化
使用代码图,开发人员或测试人员可以可视化代码不同部分之间的依赖关系。这样就很容易看出函数、类和模块是如何相互依赖的。
想象一个大型的代码库,其中有一个函数calculate_volume,还有一个calculate_area函数,并依赖于辅助函数来获取长度和宽度。代码图将清楚地说明这些依赖关系,允许开发人员快速识别潜在的问题或需要优化的领域。
简化调试
代码图通过显示函数和类如何交互来简化调试。假设开发人员正在调试calculate_volume函数的问题。通过查看代码图,他们可以很快发现问题可能是由calculate_area函数(称为calculate_volume)中的问题引起的。然后,开发人员可以将调试工作集中在calculate_area及其依赖项get_length和get_width上。
影响分析
开发人员可以快速评估代码一部分的更改对其他部分的影响。这是因为他们可以检查哪些函数或类依赖于他们要修改的代码。因此,他们可以做出明智的决定。
改进代码质量
识别和理解代码关系有助于维护和改进代码质量,但是如何实现呢?现在,开发人员可以找出代码重复的地方,然后可以重构代码以改进代码库。
代码分析RAG解决方案面临的挑战
大型代码库
由于代码量巨大,检索增强生成(RAG)模型难以检索相关的代码片段。当处理一个庞大的软件系统时,RAG模型会得到1000个代码片段,为了选出最好的一个,可能会阅读数百个看起来相似的代码片段。
代码冗余
RAG模型可能产生冗余的代码,导致代码重复,并可能降低效率。例如,在为某个任务生成不变代码时,RAG模型可能会提供多个看起来相似的解决方案,而比较它们并找出最佳方案似乎非常困难。
在代码分析中使用知识图优于向量数据库的优势
对于代码分析,知识图与向量数据库相比具有几个优势。可以通过一个例子来理解这一点。假设开发人员给出了这个提示。
- 提示:搜索有关updateInventory()的代码。
以下查看知识图谱和向量数据库将提供什么结果。
知识图谱(Knowledge Graph)
查询返回一个详细的图表,突出显示直接或间接调用updateInventory()的每个方法、类和服务。因此,在将结果提供给查询之前,知识图谱将检查所有相关的函数、类和服务以及它们与updateInventory()的关系,如下所示:
订单服务(OrderService):调用updateInventory()来更新库存水平。
- 退货服务(ReturnService):该函数用于在处理退货时重新补货。
- 审计服务(AuditService):它记录库存更改以用于审计。
- 外部API(ExternalAPI):该函数与外部API交互以同步库存数据。
- 性能指标(PerformanceMetrics):该图表包括性能数据,显示updateInventory()在高峰时段存在瓶颈。
这将确保返回的结果准确可靠,因为考虑了与updateInventory()相关的所有组件及其与它的关系。这有助于代码图表示准确的代码可视化。
向量数据库
向量数据库对于查找相似的代码片段很有用,但不能有效地表示详细的场景关系。搜索返回的函数在结构和内容上都类似于updateInventory。为什么? 向量数据库可以基于相似性搜索或欧几里德距离提供结果。
Plain Text
[FunctionX] --similar_to--> [updateInventory]
[FunctionY] --similar_to--> [updateInventory]
[FunctionZ] --similar_to--> [updateInventory]
采用代码图可视化代码
示例1
其中一个示例演示了Python中的基本函数定义和调用。它显示了简单的算术运算,例如乘法、加法和打印结果。
示例2
另一个示例演示了一个简单的递归函数,用于计算数字的阶乘,以及如何在主函数中调用它。
网上有许多代码图工具,您可以简单地粘贴整个代码。另一种选择是使用Lucidchart手工制作图表。
理解代码图工作流
可以利用一个例子来理解它。假设一个Python项目有几个文件,包括包含函数calculate_area()的math_utils.py和包含类Circle的shapes.py。索引步骤将提取函数和类定义及其关系,例如Circle使用calculate_area()。代码图的工作流程通常包括:
步骤1:索引
在这一步骤中,源代码文件解析代码库,提取相关信息,例如函数、类、变量及其关系。
步骤2:构建代码图
这一示例的代码图将包含calculate_area()和Circle的节点,其中一条边将Circle连接到calculate_area(),表明Circle使用calculate_area()函数。
步骤3:查询代码图
用户可以查询代码图来查找Circle类使用的所有函数。该查询将通过检查与函数连接的节点和实体返回一个函数列表。这可以使用图形查询语言(如Cypher或Gremlin)来完成。
步骤4:可视化和探索
可视化可能会显示Circle的节点,其边指向calculate_area(),表示依赖关系。这种可视化帮助开发人员快速识别代码实体之间的关系。
步骤5:分析和洞察
通过分析代码图,可能会发现Circle类与calculate_area()函数紧密耦合,这可能会导致维护问题。还可以确定calculate_area()函数在代码库的另一部分重复。
与OpenAI交互转换查询
有时,还可以使用OpenAI Codex模型与查询转换进行交互,该模型可以针对多种代码转换任务进行微调,例如使用OpenAI代码采样重构现有代码,并使用SQL Codex Art转换表。例如,给定CSV文件中的数据集,编写SQL查询从数据集提取一些信息。
- 自动补全:OpenAI的模型可以使用机器学习补全不完整的代码,减少开发人员的时间。
- 代码转换:模型可以将代码从一种编程语言转换为另一种编程语言,这使得在语言之间重新定位项目变得很简单。
- CodeOpt:OpenAI公司开源了他们的代码优化模型,从而有助于提高代码的性能。总的来说,这节省了大量的计算资源,以换取更高的效率。
- 代码解释:它帮助模型将晦涩的代码片段转换为更简单的单词,这使得开发人员更容易理解和相互学习代码。
详尽的知识图谱模式
知识图模式是对数据所在位置的本质的理解。它定义了所有细节、实体之间的关系、属性或概念,以及知识图谱中呈现的所有内容。它提供了一种组织和连接数据的标准化方法,允许机器解释这些信息的意义和关系。
以下利用一个关于电影的假设知识图来理解这一点:
实体
(1)电影:表示一个电影实体。
- 属性:片名(字符串)、上映日期(日期)、导演(人物)、类型(字符串)、评分(浮动)、票房收入(浮动)、剧情简介(文本)
(2)人物:代表从事电影行业的人。
- 属性:姓名(字符串),出生日期(日期),出生地点(字符串),传记(文本),图片(URL)
(3)类型:代表一种电影类型。
- 属性:名称(字符串),描述(文本)
(4)工作室:代表电影制作工作室。
- 属性:名称(字符串)、总部(字符串)、成立(日期)、描述(文本)、图片(URL)
(5)奖项:表示授予电影的奖项。
- 属性:名称(字符串),类别(字符串),年份(日期),收件人(人物或电影)
构建代码图
首先,克隆FalkorDB代码图存储库。
Plain Text
git clone https://github.com/FalkorDB/code-graph.git
运行FalkorDB。
Plain Text
docker run -p 6379:6379 -it --rm falkordb/falkordb
将OpenAI API密钥设置为环境变量。将需要它为知识图谱生成密码查询,并回答与代码图相关的RAG问题。
Plain Text
export OPENAI_API_KEY=YOUR_OPENAI_API_KEY
启动FalkorDB代码图工具。
Plain Text
npm run dev
这将在http://localhost:3000/上启动一个服务器。可以输入任何存储库的GitHub URL,它将生成代码图。
还可以在侧边栏中询问有关代码图的问题,它将以自然语言回答。在浏览编程框架复杂而庞大的代码库时,这个功能非常有用。
未来的改进
代码图有很大的改进空间,特别是在加强与各种开发工具和平台的集成方面。一个关键方面在于确保实时更新,使代码图与代码库中的变化保持同步。另一个重要的开发领域是扩大支持的编程语言范围,使代码图更加通用,并适用于不同的开发环境。此外,利用机器学习进行预测分析和代码推荐,在进一步提高代码图的实用性和有效性方面具有巨大的潜力。
这些改进可以帮助开发人员更全面地了解他们的代码库,使他们能够进行更彻底的代码分析,并最终提高整体代码质量。
原文Enhancing Code Analysis With Code Graphs,作者:Balaji Dhamodharan