通义灵码是基于阿里巴巴通义大模型研发的AI 智能编码助手,在通义灵码 1.0 时代,我们针对代码的生成、补全和问答,通过高效果、低时延,研发出了国内最受欢迎的编码助手。
在通义灵码 2.0 发布会上,阿里云通义实验室自然语言处理方向负责人黄非分享了代码大模型的演进。过去一年来,随着大模型技术的发展,特别是智能体技术的深入应用,通义灵码也在智能体的基础上研发了针对于整个软件研发流程的不同任务的智能体,这里既包括单智能体,也包括多智能体合并框架,在这样的基础上我们研发了通义灵码2.0。
我们首先回顾软件工程的发展历史。1960年代中期,软件开发进入危机时代,因为那个时候软件开发并没有固定的方法可循,整个的软件设计是在开发人员头脑中完成了一个隐藏的过程,而且软件维护的成本居高不下,产品质量也比较低。
1968年以来通过 NATO 会议,正式提出了软件工程这样一个术语,人们提出了结构化的开发方法,也包括瀑布式的软件生命周期流程,软件测试和验证成为软件开发的重要环节。
1983年 C++ 正式发布以来,推动了面向对象的程序设计方法,面向对象程序设计方法意味着对象的编程、软件开发的工具都得到了改进,包括软件开发的环境 IDE 和版本控制的工具也得到了广泛的使用。同时也有一些 ISO9000、SPICE 等质量标准体系的形成,确保软件工程的开发满足标准化的流程。
在90 年代末,进入互联网时代,由于软件的快速发展催生了敏捷开发的革命,需要更紧密的团队协作,需要不同团队之间有效地应对不同需求的变化,需要软件的持续构建、持续集成、持续迭代和持续交付。
到2023 年以来,随着 GPT-4 的推出,大模型对于整个开发带来革命性地变化。比如说基于大模型的智能辅助开发系统逐渐成为主流,大模型驱动的软件智能开发助手已应用到软件开发流程的各个环节中来,也推动了软件工程以更为智能高效的方式去推动、去发展。
如果仔细来看一下智能软件工程的详细流程,我们会看到在2020 年生成式大模型发布之前,其实已经有了一些针对于软件开发的小模型的工作,包括 CodeBERT、GraphCodeBERT,这些是以 BERT 为框架,但还只主要针对于代码理解这样的任务。
到了2021 年,以 CodeX 为代表的生成式大模型为特色,针对于代码的生成,代码的补全,已经开始得到了应用。在此基础上的话,一个非常重要的衡量代码生成的榜单,HumanEval 也被提了出来。
到了2023 年我们看到包括 ChatGPT、GPT-4,包括 Qwen 这样的通用模型,以及在此基础上的 CodeQwen、CodeLlama 等代码专用模型更广泛地应用到了软件开发的过程中,包括代码的生成、补齐、注释的生成、单元测试的生成等等,都应用了这方面的能力。
我们也看到在2023 年底,SWE-bench 这样一个更真实的模拟软件开发流程的一个 benchmark 也被提了出来,在这个 benchmark 上提供的一些评估能力,也能更准确地评估大模型或者是 AI 编码助手在真实软件开发过程中的一个效果。
到了2024 年,我们可以看到更多的代码模型不断涌现出来,也更完整地融入到整个端到端的软件开发流程,从用户需求的理解,到软件的设计,到软件的开发、调试、生成、交付文档等等一系列流程,都能够用到智能大模型的技术。
总结来看的话,以大语言模型为基座带来了整个软件工程开发新的范式,从早期的智能助手的阶段,LLM+Copilot的结合,到中期的基于智能体,每个智能体成为一个单独的智能专家,能够自主地用工具完成一个特定的任务。
到第三个阶段即多智能体的阶段,以大模型为基础,能够更好地完成整个软件流程开发的不同任务,配合来完成更复杂的开发任务。
我们的通义灵码是在QwenCode2.0 的基础上建立的,Qwen2.5-Coder 是在 Qwen 的基础上研发而成,这里包括了适应多场景的全尺寸的代码大模型。
我们发布了包括7B、32B 等共六款 Qwen2.5-Coder 模型,这六款代码模型在同等尺寸下均取得了业界最佳的效果,包括代码生成、代码推理、代码修复等等核心场景,其中 32B 的旗舰代码模型在 10 余项基准评测中都取得了开源模型的最佳成果。同时,代码模型还在代码生成关键能力上对齐了闭源模型 GPT-4o。
具体来说,Qwen2.5-Coder是基于 Qwen2.5 的基础大模型进行初始化,使用了包括源代码、文本代码混合数据以及代码合成数据等总共 5.5T tokens 的数据进行持续地训练,实现了代码相关下游任务的显著提升,特别是针对非常有挑战性的真实世界的软件工程任务,我们提出了两阶段的文件级别预训练及仓库级别的预训练,增强了 Qwen-Coder 对于仓库上下文的依赖和理解。
此外,为了适配开发者的多语言需求,Qwen-Coder在接近百种编程语言上进行了预训练和对齐。在实际评测中,Qwen2.5-Coder 32B 的模型在 40 余种编程语言中表现优异,在 MC-EVAL 基准上取得了所有开闭源模型的最高分,并斩获了考察多种编程语言代码修复能力的 MD-EVAL 基准的开源冠军。
在通义灵码产品化落地阶段,我们看到有两个步骤,第一阶段的话就是 Copilot 的阶段。代码模型作为一个编码助手能够帮助程序员在编码过程中,针对特定任务完成特定的工作。
第二阶段的话就是 AI 程序员,更深入地融合到软件开发的整个流程中来,能够起到更大的作用。
我们以Test Agent 测试智能体为例来解释一下,Test Agent 专注于单元测试的相关任务,用户只需要说出单测的需求,Test Agent 就会自动地帮助你完成单元测试生成的全部流程。
它具备多项能力,比如说用户需求的分析、计划的制定、完整分析被测函数中的代码依赖、使用工具与 code base 进行交互,比如说搜索的工具、编辑器工具等,结合编译器、执行器的环境反馈完成单元测试的生成和 bug 的修复。
通义灵码2.0 的 AI 程序员采用的是多智能体的框架,这个框架分为两个主要的部分,一个是环境的部分,一个是智能体的部分,环境的部分包括代码仓库、各种软件工程工具和 Reward Model 等等。
智能体的部分是系统的核心,这里由 5 个专门的 AI 智能体组成,包括规划智能体、搜索、生成、单测、调试智能体等等。这些智能体通过 Action 和环境进行交互执行各自的任务,同时它们也能够接受来自于环境的反馈进行不断地学习和改进。这种多智能体的架构使得通义灵码 AI 程序员能够处理复杂的软件开发任务,从方案设计到代码调试,全面覆盖了开发流程的各个环节。
此外,考虑到现实软件开发流程中的复杂性,现实软件开发流程也包括需求分析、系统设计、软件开发和软件测试,而且还涉及到开发者自己的思考以及开发者和外部工具的使用,以及不同职能的人之间的交流,这样一个流程也需要更复杂的一个软件开发大模型。
我们看现有的代码大模型,它是在预训练语言模型基础上增加了比如说Github 的静态代码和文档数据、网页代码问答数据等等,进行了持续地预训练,形成代码预训练模型,同时针对于代码生成的一些任务,比如说代码的指令生成数据、注释、单测等多任务指令、通用问答指令等等数据来进行有监督地微调,进一步地针对代码的相关任务偏好数据进行对齐,最后生成代码对齐模型。
这些代码对齐模型由于缺乏解决实际软件过程中需要的推理过程数据,所以难以应用到真实的端到端的软件工程的任务中来,比如说它缺乏解决问题所需要的一个过程数据,比如说针对用户需求的一个规划、反思,也缺乏和外部工具的交互的数据,比如说和编译器的交互和执行器的交互等等。
在此基础上,我们就提出了面向软件工程的数据合成的思路,来训练面向软件工程的代码模型,这个过程不仅能够学习问题和答案之间的映射,更关注学习如何解决问题的过程。
过程数据合成主要包括三个阶段,现实软件工程的理解、故障的定位,包括边界点的定位以及代码的生成这三个部分,每个部分通过React 的形式合成解决过程的数据来改进现有模型在实际软件开发中的应用。
具体来说,仓库理解阶段旨在分析和理解软件仓库的结构、文件和相关代码,形成相应的分析和规划,为后续步骤提供基础。而故障定位阶段,通过自主调动搜索工具、迭代细化搜索结果并定位引发Issue 的潜在代码位置,而基于这些故障的位置和数据合成链路,可以在补丁生成的阶段生成可以直接应用的代码补丁,交给用户审查和确认。
我们可以看到上述整个过程,在仓库环境下,通过React 的形式合成了解决过程的数据,这种方法能够改进现有模型在实际开发过程中的应用,使得 AI 系统不仅能够给出答案,还能够模拟软件工程师解决问题的思路。
基于这种软件工程的过程数据合成方法,我们训练了Lingma-SWEGPT 软件工程大模型,这个模型旨在解决需要复杂推理的软件工程任务。Lingma-SWEGPT 接收真实的 Github Issues 和 Reports 作为输入,通过仓库理解、故障定位和补丁生成这三个阶段,最终输出了提交的补丁。该模型采用迭代训练的方法,利用合成数据不断地优化,模型在每个阶段都用了 Chain-of-Thought 推理和观察行动循环,实现了从问题到解决方案的全流程智能化。
同时通过整合仓库的导航、精确的搜索这样的工具,以及使用的 Git 的相关命令和 Pylint 等代码质量检查工具,模型能够处理越来越复杂的软件工程问题,并且在每个阶段生成中间结果,也供进一步地分析和改进,最终模型生成的补丁由人工进行审查和确认,确保其正确性和实用性。
这种端到端的智能化的流程,使得Lingma-SWEGPT 在复杂软件工程任务中表现出色,能够模拟专业开发者解决问题的过程,为软件开发和维护提供强大的 AI 辅助能力。
我们举一个例子,比如说在单元测试的生成场景中,通义灵码Test Agent 会在识别到生成单元测试需求之后开始分析你的项目环境,逐一检查生成单元测试所必要的依赖项是否通过,在前置依赖项检查通过之后,Test Agent 会列出生成单测计划待用户确认,用户确认之后,Test Agent 会开始按照计划为每个测试函数开始生成单元测试的代码,并自动修复其中存在的错误,在生成和修复完成之后,Test Agent 会合并生成好的单元测试用例,将合并后的文件作为呈现给用户的最终结果。
基于用户的代码仓库对用户的问题进行分析之后,我们可以看到多文件生成也使用了类似的框架,首先,它需要定位需要修改的一个或多个文件代码或片段,再次,它会给出整体的修改说明,这样的目的是使得用户的交互更加友好。第三,生成每个文件的具体代码修改方案,主要是因为要缓解模型生成速度的慢的问题,不是生成全部的修改代码,而只是修改方案中仅包括被修改的部分。第四步是根据修改的方案能够快速生成完整的修改后的代码文件,这样的话工程根据修改前后的代码文件进行渲染,生成Diff 的可视化效果,给用户友好的交互体验。
我们下一步来展望一下未来的代码大模型的发展,首先根据SWE-bench 的这个结果我们来看,在过去一年多以来,这个结果的数据集的评分从 0.4 快速上升到 71.7,它的解决率的速度远远超过我们的想象,我们来看代码的数据其实储备非常丰富,从第一天开始就是数字化的数据,此外代码的流行的过程本身就是一个思维链的过程,它就是一个解决问题的方法、步骤和过程,这样的话我们的大模型的推理能力、思维链能力,在代码任务上能够得到很好地体现和应用。此外代码本身也有很好的环境交互,比如说编译器、执行器等等都可以用来判断代码的正确性。
所以综合来看的话,代码的智能开发很有可能是AGI 最先突破的方向,我们也在业界看到了在这个方向的广泛地应用和落地,以及大量的产品,如果我们看 Gartner 对于不同技术的发展趋势来看,我们可以看到,基于 AI 的智能代码目前正处在发展的顶峰阶段,我们可以预见现在和今后未来很近的时间内,基于 AI 的代码辅助和智能软件工程的模型和产品会得到巨大的爆发和发展,我们也要积极拥抱人机共生的软件工程的新的范式。
最后我们来总结,以智能体为核心的AI Agent 将成为用户和编程过程之间的智能中介,它不仅能够通过观察,学习到大模型处理和执行操作来完成更为复杂的编程任务,更重要的是,这个系统能够持续学习和进化,通过数据飞轮不断地改进自身的能力。
未来我们期待看到更加智能的、自主的编程助手,它不仅能够被动地解决现有的编程需求,还能够持续学习、主动发现并解决可能存在的问题,极大地提升编程的效率和代码质量。更进一步,以自然语言为交互,它可以让更多不具备代码开发能力的泛编程人员通过自然语言和多框架的编程模式,能够灵活地开发更多的、更个性化的代码或者是Task 引擎,在广泛的场景中得到应用。