引言
随着大规模软件开发的普及,对可扩展且易于适应的静态代码分析技术的需求正在加大。传统的静态分析工具,如 Clang Static Analyzer (CSA) 或 PMD,在检查编程规则或样式问题方面已经展现出了良好的效果。然而,这些工具通常是为了满足特定的目标而设计的,往往无法满足现代软件开发环境中多变和多元化的需求。这些需求可以涉及服务质量 (QoS)、各种编程语言、不同的算法需求,以及各种性能需求。例如,安全团队可能需要复杂的算法,如上下文敏感的污点分析,来审查较小的代码库,而项目经理可能需要一种相对较轻的算法,例如计算圈复杂度的算法,以在较大的代码库上测量开发人员的生产力。
这些多元化的需求,加上大型组织中常见的计算资源限制,构成了一项重大的挑战。由于传统工具采用的是问题特定的计算方式,往往无法在这种环境中实现扩展。因此,我们推出了 CodeFuse-Query,这是一个专为大规模静态分析设计的集中式数据平台。
在 CodeFuse-Query 的实现中,我们把源代码和分析结果看作数据,把执行过程看作大数据处理,这与传统的以工具为中心的方法有着显著的不同。我们利用大型组织中的常见系统,如数据仓库、MaxCompute 和 Hive 等数据计算设施、OSS 对象存储和 Kubernetes 等灵活计算资源,让 CodeFuse-Query 能够无缝地融入这些系统中。这种方法使 CodeFuse-Query 高度可维护和可扩展,能够支持多元化的需求,并有效应对不断变化的需求。此外,CodeFuse-Query 的开放架构鼓励各种内部系统之间的互操作性,实现了无缝的交互和数据交换。这种集成和交互能力不仅提高了组织内部的自动化程度,也提高了效率,降低了手动错误的可能性。通过打破信息孤岛,推动更互联、更自动化的环境,CodeFuse-Query 显著提高了软件开发过程的整体生产力和效率。
此外,CodeFuse-Query 的以数据为中心的方法在处理静态源代码分析的领域特定挑战时具有独特的优势。例如,源代码通常是一个高度结构化和互联的数据集,与其他代码和配置文件有强烈的信息和连接。将代码视为数据,CodeFuse-Query 可以巧妙地处理这些问题,这使得它特别适合在大型组织中使用,其中代码库持续但逐步地进行演变,大部分代码在每天进行微小的改动同时保持稳定。CodeFuse-Query 还支持如基于代码数据的商业智能 (BI) 这类用例,能生成报告和仪表板,协助监控和决策过程。此外,CodeFuse-Query 在分析大型语言模型 (LLM) 的训练数据方面发挥了重要作用,提供了增强这些模型整体效果的深入见解。
在当前的静态分析领域,CodeFuse-Query 带来了一种新的范式。它不仅满足了大规模、复杂的代码库分析需求,还能适应不断变化和多元化的静态分析场景。CodeFuse-Query 的以数据为中心的方法,使得其在处理大数据环境中的代码分析问题时具有独特优势。CodeFuse-Query 的设计,旨在解决大规模软件开发环境中的静态分析问题。它能够将源代码和分析结果视作数据,使得其可以灵活地融入大型组织的各种系统中。这种方法不仅可以有效地处理大规模的代码库,还可以应对各种复杂的分析需求,从而使得静态分析工作变得更加高效和准确。
特点和优势
高度可扩展:CodeFuse-Query 可以处理大规模的代码库,且能够适应不同的分析需求。这种高度的可扩展性使得 CodeFuse-Query 可以在大型组织中发挥重要作用。
以数据为中心:CodeFuse-Query 将源代码和分析结果视作数据,这种以数据为中心的方法使其在处理大数据环境中的代码分析问题时具有独特优势。
高度集成:CodeFuse-Query 能够无缝地融入大型组织的各种系统中,包括数据仓库、数据计算设施、对象存储和灵活计算资源等。这种高度的集成性使得 CodeFuse-Query 在大型组织中的使用变得更加方便和高效。
支持多元化的需求:CodeFuse-Query 不仅可以处理大规模的代码库,还可以应对各种复杂的分析需求,包括服务质量分析需求、跨编程语言分析需求、算法需求和性能需求等。
CodeFuse-Query 是一种强大的静态代码分析平台,适合大规模、复杂的代码库分析场景。它的以数据为中心的方法和高度的可扩展性使得它在现代软件开发环境中具有独特的优势。未来,随着静态代码分析技术的不断发展,CodeFuse-Query 有望在这个领域中扮演更加重要的角色。
架构
从整体上来说,CodeFuse-Query代码数据平台分为三大部分:代码数据模型、代码查询DSL、平台产品化服务。主要工作流程如下图所示:
代码数据化和标准化:COREF
我们定义了一种代码数据化和标准化的模型:COREF,要求所有代码都要能通过各种语言抽取器转化到该模型。
COREF主要包含以下几种信息:
COREF = AST (抽象语法树) + ASG(抽象语义图) + CFG(控制流图) + PDG(程序依赖图)+ Call Graph(函数调用图) + Class Hierarchy (类继承关系)+ Documentation(文档/注释信息)
注:由于每种信息的计算难度不一,所以并不是所有语言的COREF信息均包含以上全部信息,基础信息主要有AST、ASG、Call Graph、Class Hierarchy和Documentation,其他信息( CFG 和 PDG )仍在建设中,后续会逐步支持。
代码查询DSL
基于生成的COREF代码数据,CodeFuse-Query 使用一种自定义的DSL语言 Gödel 来进行查询,从而完成代码分析需求。
Gödel是一种逻辑推理语言,它的底层实现是基于逻辑推理语言Datalog,通过描述“事实”和“规则”, 程序可以不断地推导出新的事实。Gödel也是一个声明式语言,相较于命令式编程,声明式编程更加着重描述“要什么”,而把如何实现交给计算引擎。
既然代码已经转化为关系型数据(COREF数据以关系型数据表的形式存储),相信大家会有疑问,为什么不直接用SQL,或者是直接使用SDK,而是又要专门去学习一个新的DSL语言呢?因为Datalog的计算具备单调性和终止性,简单理解就是,Datalog是在牺牲了表达能力的前提下获得了更高的性能,而Gödel继承了这个特点。
1. 相比较SDK,Gödel的主要优点是易学易用,声明式的描述,用户不需要关注中间的运算过程,只需要像SQL一样简单描述清楚需求即可。
2. 相比较SQL,Gödel的优点主要是描述能力更强、计算速度更快,例如描述递归算法和多表联合查询,而这些对于SQL来说都是比较困难的。
平台化、产品化
CodeFuse-Query 包括Sparrow CLI 和CodeFuse-Query在线服务Query中心。Sparrow CLI包含了所有组件和依赖,例如抽取器,数据模型,编译器等,用户完全可以通过使用Sparrow CLI在本地进行代码数据生成和查询(Sparrow CLI的使用方式请见 第3节 安装、配置、运行)。如果用户有在线查询的需求,可以使用Query中心进行实验。
分析语言
截止到目前,CodeFuse-Query支持对11种编程语言进行数据分析。其中对5种编程语言( Java、JavaScript、TypeScript、XML、Go )的支持度非常成熟,对剩余6种编程语言(Object-C、C++、Python3、Swift、SQL、Properties )的支持度处于beta阶段,还有进一步提升和完善的空间,具体的支持情况见下表:
注:以上语言状态的成熟程度判断标准是根据COREF包含的信息种类和实际落地情况来进行判定,除了OC/C++外,所有语言均支持了完整的AST信息和Documentation信息,以Java为例,COREF for Java还支持了ASG、Call Graph、Class Hierarchy、以及部分CFG信息。
使用场景
查询代码特征
小开发同学想知道 Repo A 里面使用了哪些 String 型的变量,所以他写了一个 Godel 如下,交给 CodeFuse-Query系统给他返回了结果。
类似需求:查询:类,函数,变量,返回值,调用图,类继承等等。
输出静态分析能力
小安全是 XX 团队的安全同学,他做了一套系统交叉验证日志数据和代码数据是否一致。为了完成某个分析任务,他计划通过写 Godel 查询出来静态数据 D1,合并动态数据 D2,联合分析得出结论 C。小安全通过在 CodeFuse-Query 上面编写 Godel Query 测试技术上可行之后,使用 CodeFuse-Query 提供的标准 API 将系统对接了起来。
类似需求:通过静态分析进行系统的卡点,提高测试的效率,通过分析出来的数据合并成说明文档。
代码规则检查器
小 TL 同学发现团队总是写出很多类似的 Bug A,他想针对 Bug A 制定一个代码规则和其检查器,并在 CodeReview 阶段做个卡点。小 TL 通过在 CodeFuse-Query 平台上面编写了一段分析 Query,在平台上面测试符合要求,把这段分析 Query 固化下来作为一个代码规则,并上线到了 CodeReview/CI 阶段。从此这个 Bug 再也没发生过了。
类似需求:编写静态缺陷扫描规则进行代码风险拦截。
分析代码特性
研发部同学小框架想知道目前代码仓库中Spring工程和Spring Boot工程比例。好量化新框架的推广情况。小架构通过编写 Godel Query 描述不同项目分析特征,然后一次性 Query 了 11 万个代码仓库,过了几十分钟后就拿到了所有代码的数据,开开心心做 KPI 去了。
类似需求:应用画像,代码画像,架构分析。
获取统计数据
小研究发现传统的代码复杂度指标很难准确地衡量代码的复杂情况,通过学习国际先进经验加上自我灵光一闪,设计了一套复杂度指标和算法。通过 Godel 实现出来以后,发现不怎么优化就已经性能非常高了,很快就应用到了 10 几种语言,11+万个仓库当中去了。马上就对代码仓库整体的复杂度有了深入的了解。相比较以前需要自己解析代码,分析语法树,对接系统,不知道方便了多少。
类似需求:代码统计,代码度量,算法设计,学术研究。
架构分析
小架构同学最近推行了一种新的基于 txt 文件的消息中间件,目前已有的分析平台都不能支持分析此类系统的上下游依赖。小架构通过 Godel快速建模了该消息格式,并马上获取到了目前系统中不同组件的依赖关系。
类似需求:系统 Overview,架构治理,血缘分析。
模型验证
小促销设计的系统里面要求用户一定是先玩游戏再领券。他通过 Godel 描述了该模型的验证逻辑,然后通过 CodeFuse-Query 系统保障当前以及未来系统的代码实现,都是完全符合该模型的。从此再不担心游戏出资损~
类似需求:系统验证,网络验证,权限验证。
应用领域
目前,CodeFuse-Query在蚂蚁集团已经支持 CodeFuse大语言模型数据清洗、代码度量评估、研发风险控制、隐私安全分析、代码智能、终端包大小治理等多个场景的落地应用,服务月均调用量超过百万。
高质量代码数据清洗 - CodeFuse代码大模型
CodeFuse代码大模型是蚂蚁集团对外开源的处理代码相关问题的模型,对于CodeFuse大语言模型而言,训练的数据质量直接影响模型的推理结果。低质量的代码数据会直接污染语言模型的输出,例如:模型可能会学习到错误的代码模式,从而生成错误的代码;数据中只包含某种编程语言的代码,模型可能无法很好地适应其他编程语言的代码。
为了把控进入模型的代码数据质量,进而提升模型的推理能力。我们基于蚂蚁程序分析团队多年的实践积累结合业界共识,梳理了高质量代码的定义方式,并利用已有程序分析技术实现了自动化、大规模的代码数据清洗。
CodeFuse-Query为CodeFuse代码大模型提供了以下数据清洗能力:
1. 高质量代码数据清洗:对代码数据进行清洗,包括对 Python,Java,JavaScript,TypeScript,Go,C,C++ 7 种语言进行漏洞扫描,对语言种类 / star 数进行筛选,过滤有效代码行数为 0 的数据等。目前已沉淀清洗后的 GitHub 和蚂蚁内部代码数据总共约 2TB。
2. 代码画像:实现对大规模代码进行高性能多维度的自动标注,支持 Java, Scala, Kotlin, JavaScript, JSX, TypeScript, TSX, Vue, Python, Go 等 10 种语言,77 种通用标签,40 种蚂蚁特有标签,共 117 种标签。目前自动标注性能能够达到 40MB/s。
3. 其他原子能力:
a. 高级代码特征提取,包括提取 AST(抽象语法树),DFG(数据流图)数据等。目前 AST 信息已用于 SFT 训练,准确率 97% 左右。
b. 代码片段识别,用于针对文本数据中的代码进行提取,方便进行代码格式化或加上 Markdown 格式:
§ 文本提取代码:从文本中提取代码块信息,支持主流语言的解析,函数及类定义,仅验证二分类问题,就是说仅验证文本是否含有代码块准确率 83% 左右。
§ 识别代码片段的编程语言种类:识别任意代码片段的编程语言种类,支持 30+ 种语言,准确率80%左右。
c. 代码注释对提取:支持提取方法级别的注释-代码对信息,覆盖 15 种 GitHub 最流行的语言,用于 Text To Code/Code To Text 的 SFT 训练。
变更分析-优酷服务端研发效能
优酷质量保障团队从2023年开始针对服务端精准测试的探索,经过半年的技术沉淀和体系搭建,形成了具备变更内容识别、变更影响分析、测试能力推荐、测试覆盖评估的精准测试体系。
在此过程中,CodeFuse-Query能提供的能力主要有:
1. 根据代码变更内容(文件+行号),分析出影响的对象:方法、入口(http入口、hsf入口)、调用链路(从入口到变更方法的所有调用链路)、数据库操作(表、操作类型)。
2. 结合线上动态调用链路(方法链路)、CodeFuse-Query静态分析调用链路的影响面精准分析能力,提升变更分析影响面的有效性、准备率。
到目前为止,优酷已通过CodeFuse-Query接入所有核心应用,并基于静态分析采集数据,构建了服务端完整的代码知识库和流量知识库。
想了解更多CodeFuse详情和互动交流,欢迎访问CodeFuse官网:https://codefuse.alipay.com