当「软件研发」遇上 AI 大模型
作者:陈鑫(神秀)
大家好,我是通义灵码的产品技术负责人陈鑫。过去有八年时间,我都是在阿里集团做研发效能,即研发工具相关的工作。
我们从 2015 年开始做一站式 DevOps 平台,然后打造了云效,也就是将 DevOps 平台实现云化。到了 2023 年,我们明显感觉到大模型时代来了以后,软件工具将面临着彻底的革新,大模型和软件工具链的结合,使软件研发进入下一个时代。
那它第一个落脚点在哪?实际上就是辅助编程,所以我们就开始打造了通义灵码这款产品,它是一个基于代码大模型的的 AI 辅助工具。今天我借这个机会和大家分享通义灵码技术实现上的一些细节以及我们如何看待大模型在软件研发领域的发展。
我会分为三个部分来分享。第一部分先介绍 AIGC 对软件研发的根本性影响,从宏观上介绍当下的趋势;第二部分将介绍 Copilot 模式,第三部分是未来软件研发 Agent 产品的进展。为什么我会提到 Copilot Agent,稍后我给大家讲解。
AIGC 对软件研发的根本性影响
这张图是我过去几年画的一张图,我认为企业研发效能的核心影响因素是这三点。
第一点是人员技能。 人员技能决定了企业研发效能的一个非常大的因素,比如说谷歌可以招聘到个人能力强于他人十倍的工程师,一个人等同于十个人,那由一群十倍工程师组成的一个小团体,战斗力就很强,甚至可以实现全栈,他们的角色分工可能就非常简单,工作非常高效,最终的效能也非常大。
但是实际上我们企业内部,尤其是中国企业,没有几个能够达到谷歌的水平。这是客观影响因素,我们认为人员技能是效能基石,当然也是效能的破局点。
第二点是协同消耗。 在我们不可能要求每个工程师能力强大的基础上,每个人一定是有专业分工的,比如有些做软件设计,有些做开发、做测试、做项目管理。这些人组成的团队随着软件架构的复杂度越来越大,组织的复杂度也会正相关的变大,这就造成了协同消耗也会越来越大,最终拖慢了整体的研发效能。
第三点是成本控制。 我们发现做项目的时候人员不可能总是富裕的,永远是缺人手,也不可能有无限的资金去招到十倍工程师,所以这也是一个制约因素。
今天在 AIGC 的时代,这三个因素已经产生了一些根本性变化。
在人员技能上, 通过 AI 辅助可以快速将一些初级工程师的能力提升。这个其实在国外是有一些报道的,初级工程师使用了代码辅助工具的效果是明显高于高级工程师的,为什么呢?因为这些工具对于初级工作的替代,或者说它的辅助效果是非常好的,所以它可以快速补齐初级工程师的能力短板。
在协同消耗上, 如果今天 AI 能够变成一个超级个体,实际上它对流程协同消耗的降低是有帮助的。比如一些简单的工作就不需要跟人打交道了,AI 直接就可以做,也不需要给每个人都讲一遍需求应该怎么测试,AI 做简单测试就可以了,这样时间的效率就提升了。所以可以通过超级个体去有效的降低协同消耗。
在成本控制上, 实际上 AI 大量的用法就是代替事务性工作,包括现在用代码大模型去做代码辅助,也是希望代替 70% 的日常事务性劳动。
那具体来看的话,会有这四个挑战以及智能化的机会。
第一个是个体效率,刚刚也给大家介绍了,大量研发工程师的重复工作和简单沟通都可以通过 AI 来完成了,它是一个 Copilot 模式。
另外一个协作效率,一些简单的工作直接让 AI 做,可以使协同消耗降低,这点刚刚我已经讲述的比较清晰了。
第三个是研发体验,过去 DevOps 工具链关注的是什么?一个接一个拼成一个大的流水线,拼成整个的工具链。其实每个工具链在不同的企业里可能有不同的使用习惯,甚至有不同的账号体系、不同的界面、不同的交互、不同的权限。这种复杂度给开发者带来了非常大的上下文切换成本和理解成本,这在无形中让开发者其实很不爽。
但是在 AI 时代发生了一些变化,我们可以通过统一的对话入口,用自然语言的方式去操作很多工具,甚至在自然语言的窗口里解决很多的问题。
我举个例子,比如过去查一个 SQL 到底有没有性能问题,我们应该怎么办?可能先在代码里面把 SQL 语句抠出来,把它变成一个可执行的语句,再放到一个 DMS 系统里面诊断一下看看它有没有用索引,有没有问题,然后再人工判断一下到底要不要改这个 SQL 去优化它,最后再到 IDE 里把它变更掉,这个流程需要切换多个系统,要做很多的事情。
那在未来,如果我们有代码智能工具的话,就可以圈选一个代码,问大模型这个 SQL 有没有问题,这个大模型可以自主的调用一些工具,比如 DMS 系统去分析,并且拿到的结果可以直接通过大模型告诉我 SQL 应该如何优化,直接告诉我结果,我们只需要采纳它就可以解决,整个操作链路会被缩短,体验就会提升,从而提升研发效率。
第四个是数字资产,过去大家写了代码放在那都变成了屎山代码或者说是负债,当然里边有非常多优秀的金矿没有被挖掘出来,然后还有很多文档想要找的时候找不到了。
但是在 AI 时代,我们做的最重要的事之一就是需要去梳理我们的资产以及文档,通过 SFT、RAG 的方式去赋能给大模型,让大模型变得更聪明,更加符合企业的个性化理解,所以今天这种人机交互方式的变化,会带来体验上的变化。
人工智能从刚刚的几个影响因素再往下拆,它核心是带来了三种人机交互方式的变化。第一种是 AI 会变成一个 Copilot,和工具进行结合,然后人可以指挥它帮我们完成一些单点的工具。到第二阶段,实际上大家应该有共识了,它变成 Agent,也就是它具备了一些自主完成任务的能力,包括自主写代码或者做测试。其实工具扮演的是一个多领域专家,我们只需要给定上下文并完成知识对齐即可。第三个阶段我们判断 AI 可能会变成一个决策者,因为在第二阶段决策者还是人,在第三阶段有可能大模型会具备一些决策能力,包括更高级的信息整合分析能力。这时候人会更多的聚焦于业务的创意和纠偏,很多事情都可以交给大模型做。通过这种不同的人机模式的变化,让我们整体的工作效率会变高。
还有一点是我们刚刚讲到的知识传递形式也发生了根本性的变化。在过去是通过口口相传、通过培训,老带新去解决知识传递的问题。未来很有可能不需要这样,只需要让模型具备业务知识和领域经验,让每一个开发工程师都使用智能化工具,它的这些知识就可以通过工具传导到研发过程中,就会变成右边图上所示的现在 DevOps 的一站式工具链。积累了大量代码和文档资产后,将这些资产梳理清楚跟大模型放在一起,通过 RAG、SFT,模型嵌入到 DevOps 工具的各个链路,从而又产生更多数据,形成了这样的正向循环,一线开发者在这个过程中就能享受到资产带来的红利或者说能力。
以上就是我从宏观的角度介绍了现在大模型影响研发效率的核心因素,以及两个最重要的形态改变:第一个是人机交互的形态发生了改变,第二个是知识传递的方式发生了根本性变化。 现在由于各种各样的技术限制以及大模型发展阶段的问题,我们做的最好的还是 Copilot 人机交互模式,所以接下来就介绍下我们的一些经验,如何去打造最佳的这种 Copilot 人机交互模式。
打造最佳 Copilot 姿势
我们认为代码开发的人机交互模式,目前只能解决比如小任务的问题、需要人工采纳的问题、高频次的问题,像代码补全,AI 帮我们生成一段,我们接纳一段,再生成一段,再接纳一段,这种频次非常高的问题,还有短输出的问题,不会说一下子就生成一个工程,甚至不会一下就生成一个类,我们每次都是生成一个函数或者几行。为什么要这样来做呢?其实和模型本身能力的限制有很大关系。
因为我们现在上下文宽度还非常有限,假如要完成一个需求,没有办法把所有的背景知识全部交给它一次性搞定,所以要不就是通过 Agent 去拆成一堆的小任务,逐步解决。要不就在 Copilot 模式里让它完成一个最简单的工作,比如按照一个注释去生成一小段代码,这样我们叫做解决小任务。
在人工采纳上,人工现在必须对代码大模型生成的结果做判断。目前做的好的可能也就是 30%-40%的采纳率,也就是说我们有超过一半的生成代码实际上是不准确的,或者是不符合开发者预期的,所以要不断的消除幻觉问题。
但是让大模型真正能在生产级使用最重要的还是要人工确认,然后高频次是不要生成太多,每次生成一点,因为人工去确认这段代码是否 ok 的成本也是影响效能的,后文会讲一些我们的思考和我们做的事情,通过高频次去解决准确性率有限问题。另外短输出主要是考虑性能和成本问题。
现在代码助手这种模式,实际上是特别精确的命中了大模型的一些技术限制,才让这样的产品能够快速落地,它有一个非常好的时机。在我们看来,开发者最喜欢的 Copilot 模式,是以下四个关键词:高频刚需、触手可及、知我所想、唯我专属。
第一个是我们要解决高频和刚需的场景,这才能让开发者觉得这个东西是真的有用,而不是个玩具。
第二个是触手可及,也就是随时可以唤醒它,随时可以帮我们解决问题。不再像以前需要通过各种搜索引擎去搜索代码,它就像在我身边一样,随时可以唤醒它帮我解决问题。
第三个是知我所想,也就是它回答我问题的准确度,以及它在什么时机回答我的问题都是非常重要的。
最后还要为我所属,它能懂我私有的一些知识,而不是说只了解完全开源的东西。我们把这四点具体再展开讨论一下。
高频刚需
我们需要判断什么是软件研发最高频的场景。我这边有一些真实的数据,第一个数据来自 JetBrains 在 2023 年做的一个开发者的生态报告,整理了开发者最耗时的活动,其中可以看到百分之七八十都是编写代码,理解代码及互联网搜索、调试、写注释、写测试。这几个场景实际上就是代码智能工具的功能,像通义灵码这样的产品最核心解决的问题,其实就是最高频的问题。
后面这两个数据是通义灵码线上几十万用户的数据分析。我们现在线上采纳的代码, 73% 来自于补全任务,27% 来自于问答任务的采纳。所以今天大量的 AI 替代人去写代码,还是在 IDE 的行间生成,这是从真实的情况下反映出来的一个结果。后面是使用问答功能的比例,有 76% 的比例是来自于研发问答,剩下的 10% 是代码优化和解释代码等等一系列的代码任务。所以绝大部分的开发者还是在使用我们的工具去问一些常用的研发知识,或者通过自然语言的方式让代码大模型生成一些算法,解决一些小的问题。
其次的 23% 才是我们真正的一些细节的代码任务,这是给大家一个数据洞察。因此我们就有了核心的目标。第一,我们要解决好代码生成的问题,尤其是在行间生成。第二,要解决研发问题的准确度以及专业性问题。
触手所及
我们最终要讲的是打造沉浸式编程体验,我们希望今天开发者绝大部分的问题都可以在 IDE 里面解决,而不是需要跳出。
过去我们的体验是什么?是遇到问题去互联网搜索,或者问问别人,问了一圈以后再自己判断,最终写上代码复制放到 IDE 里面调试编译,不通过了再去查,这样的话就会非常耗时。我们希望能在 IDE 里面直接问大模型,让大模型帮我生成代码,这样体验就很爽。我们通过这样的一个技术选择,解决了沉浸式编程体验的问题。
补全任务是一个性能敏感型任务,它的输出需要在 300 到 500 毫秒,最好不要超过一秒,所以我们有一个小参数模型,它主要是用来生成代码的,而且它的大部分训练语料也来自于代码。它虽然的模型参数很小,但是在代码生成的准确度上非常高。
第二个我们要去做好专项任务,我们还有 20%~30% 实际上的任务是来自于这些,包括注释生成、单元测试、代码优化、运营错误排查等七项任务。
我们目前使用了一个中等参数模型。这里主要考虑的,一是生成效率,二是调优。一个非常大参数的模型,我们调优的成本是很大的,但是在这种中等参数模型上,它本身的代码理解和代码生成效果已经不错了,所以我们选择了中等参数模型。
然后在大模型上面,尤其是我们 70% 多的研发问题回答上,我们追求的是高精度,而且追求的是实时的一些知识。所以我们通过一个最大参数的模型,叠加了我们的 RAG 技术,让它外挂了一个近乎于实时的基于互联网的知识库,所以它回答的质量和效果就非常高,并且能大幅消除模型幻觉,提升回答质量。我们通过这样的三个模型支持了整个沉浸式编程的体验。
第二点是我们要实现多端,因为只有覆盖了更多的端,才可以覆盖更多的开发者。目前通义灵码支持 VS code 和 JetBrains,主要解决的是触发问题、展示问题,还有一些交互性问题。
最核心层次下面,我们本地 Agent 服务是一个独立的进程。这个进程跟上面的插件之间会进行通信。这个进程最主要解决的是代码核心的一些能力,包括代码智能补全的部分,会话管理的部分,智能体。
此外,语法分析服务也非常重要,我们要解决跨文件引用的问题等,都需要语法分析。如果我们要做本地的检索增强,我们还需要轻量级的本地向量检索引擎。所以整个后端的服务实际上是通过这样的方式就可以快速的实现扩端。
我们还有一个特色,我们有一个零点几 B 的本地离线的小模型,来实现个别语言的单行补全,这是可以脱网去做的,包括 JetBrains 最近也上了一个跑在本地的小模型。通过这种方式,也会保证我们的一些数据安全隐私问题,比如本地的会话管理、本地的存储,全部都放到了本地电脑上。
知我所想
知我所想对于 IDE 插件这个工具而言,我认为有几点。第一是触发时机,在什么时候触发,对于开发者体验的影响也非常大。比如我在空格的时候要不要触发?IDE 已经生成提示的时候要不要触发?在删除这段代码的时候要不要触发?我们大概有超过 30~50 个场景去梳理,到底在这个场景上要不要进行代码触发,这部分通过规则就可以搞定,只要一点点细心去摸索,去调研开发者体验,就可以解决,这不是很高深的技术。
但是在代码生成长度方面,我们认为是比较难的。 因为在不同的编辑区的不同的位置,它生成什么样长度代码,直接影响了我们的体验。如果开发者只是倾向于生成单行代码,带来的问题就是开发者不能理解整个生成的内容,比如生成一个函数,他不知道这个函数到底要干什么,生成一个 if 语句,他不知道 if 语句里边的业务逻辑是什么,就没有办法完整的判断功能单元,影响了他的体验。
我们用一些固定的规则去做,也会导致一个问题,即它会比较死板。所以我们的做法实际上是基于代码的语义信息,通过训练的方式,经由大量的样本,让模型理解了今天在什么场景下应该生成多长,我们实现了由模型自动判断类级别、函数级别、逻辑块级别及行级别的生成力度,我们把它叫做自适应的生成力度决策。我们通过做这项大量的预训练,让模型去感知,从而提升了生成的准确度,这块我们认为也是一个比较关键的技术项。
再往下最关键的就是如何去消除模型的幻觉,因为只有幻觉得到足够的消除,才能够提升我们的采纳率。所以我们一定要实现基于库内的跨文件上下文感知,在这里,我们做了很多的基于代码的语义分析,引用链追踪,相似代码以及动态语言类型推导等。
最关键的就是想方设法的去猜开发者在这个位置补全他可能需要什么样的背景知识,这些东西可能还会涉及到一些语言、框架、用户习惯等,我们通过各种各样的东西将它的上下文获取出来,并且进行优先级排序,把最关键的信息放到上下文里面去,然后给到大模型进行推导,让大模型去消除幻觉。通过这样的技术就可以实现跨文件上下文感知的测试集,我们的准确率从 22% 提升到了 66.9% ,我们还在不断的去精进提升补全的效果。
最后一个是我们本地的库内检索增强。刚刚其实也说了,上下文感知也只是猜测开发者在触发位置的上下文。更多的场景是今天开发者要问一个问题,让大模型基于本地的库内所有文件去帮我解决一个问题,比如帮我修复一个 bug,帮我增加一个需求,帮我填充一个文件,自动实现增删改查,甚至帮我的 Pompt 文件增加一个新的包的版本,类似这样的需求其实有很多,要实现的话实际上是要给大模型外挂一个检索引擎。因为我们不可能把整个工程的文件全部塞给大模型,因为上下文宽度的影响,我们必须使用到一个技术,叫做本地的库内检索增强。
这个功能就是来实现我们基于库内的自由问答的,在本地去建立一个库内的检索增强服务,我们判断这样的方式对于开发者的体验是最好的,安全性也是最高的。
代码不需要上传到云端,就可以完成整个链路。 从整个链路上来讲,开发者问一个问题以后,我们就会去代码库提取需求的关键信息进行任务拆解,拆解完了做本地的向量检索召回,然后再做检索的结果合并及重排,以及去企业内部的数据知识库检索,因为企业有统一的知识库管理,是企业级的。最终把全部的信息汇总起来发送给大模型,让大模型去生成和解决问题。
唯我专属
我觉得企业要想让代码大模型真的能实现一个非常好的效果,都逃不过这一关。比如如何实现企业数据的个性化场景,比如在项目管理阶段,如何能够让大模型按照需求/任务/缺陷内容的一些固有的格式和规范去生成,帮我们实现一些需求的自动拆解、自动续写、自动总结等等。
开发阶段可能是大家最关注的,经常有企业会讲要有符合企业自己的代码规范,引用企业自己的二方库,调用 API 生成 SQL,包括使用企业自研的一些前端框架、组件库等等,这些都属于开发场景。测试场景也要生成符合企业规范的,甚至是理解业务的测试用例。在运维场景,要时刻查找企业的运维知识,然后去回答,去获取企业的一些运维的 API 快速生成代码。这些都是我们认为要做的企业数据化个性化场景。具体的做法是要通过检索增强或者微调训练的方式来实现。
在这里我列了一些简单的场景和需要注意的事项,包括代码应该怎么处理,文档应该怎么处理,代码过来要进行过滤、清洗、结构化,然后才能够可用。
在我们训练的过程中,要去考虑开放域数据和私域数据的混入。比如我们要去做一些不同的参数调整,在检索增强上,我们要考虑不同的检索增强策略,我们其实也是在不断的进行探索,包括如何在代码生成场景里面命中我们所需要的上下文信息,以及我们在问答场景里面如何去命中我们需要的回答的上下文信息,这属于检索增强。
我们要做的就是企业级的检索增强方案,企业级的检索增强方案目前的架构图大概是这样。中间是知识库的管理服务,包括数据解析的调度、问题的理解、整理回答、结构化的解析、数据分块等等,核心的能力在中间这块,向下是我们比较常用的 Embedding 的服务,包括大模型的服务、向量的存储和检索。
向上是我们管理的一些后台,在这个场景下支持了我们关于文档的检索增强以及代码生成的检索增强。代码生成也就是补全这个场景的检索增强它所需要的处理方式和技术跟文档其实还是略有不同。
过去我们跟复旦大学也做过几年的学术研究,非常感谢他们的付出,我们也有一些论文在发表,当时我们测试集的结果也是用一个一点几 B 的模型,再配合检索增强,它实际上的准确率和效果就可以达到一个大概 7B 以上模型的同等效果。
未来的软件研发 Agent 产品演进
我们认为未来软件研发一定会进入到 Agent 时代,也就是说它具备一些自主性,并且它可以非常容易使用我们的工具,然后理解人类的意图,完成工作,最终会形成一个如图所示的多智能体的协同模式。
就在今年三月份,Devin 的诞生其实让我们感觉到这个事情真真实实的被加速了,我们从来没有设想到这个事情能够完成一个真实的业务项目,我们过去都没有想象到,甚至我们都觉得这个事情可能还要一年以后,但是它的出现让我们觉得,今天真的可以通过大模型拆解数百上千个步骤,并且一步一步执行,出现问题它还可以自我反思,自我迭代,有这么强的拆解能力和推理能力让我们非常意外。
随着 Devin 的诞生,各个专家学者就开始投入,包括我们通义实验室,马上发起的一个项目叫 OpenDevin。这个项目在短短的几周内 star 数就超过了 2 万,可以看到大家对这个领域非常的热情。然后马上开源了 SWE 的 Agent 项目,把 SWE- bench 的解决率又推升到了 10% 以上,过去的大模型都在百分之几,推升到 10% 已经接近了 Devin 的表现,所以我们判断在这个领域的学术研究会非常快,我们大胆猜测一下,很有可能在 2024 年年中左右的 6 到 9 月份,很有可能 SWE- bench 的解决率会超过 30%。
我们大胆猜测一下,如果能够达到百分之五六十解决率的话,它的测试集实际上是一些真实的 Github issue,让 AI 完成 Github 上面的 issue,可以去修复 bug,去解决需求的这样一个测试集。如果这个测试集能够让 AI 的自主完成率达到百分之五六十,我们认为真的是可以在生产级中落地了。至少一些简单的缺陷可以交给它来修复,这是我们看到的目前业界的一些最新的进展。
但是这张图也不是马上就能实现的,现在从技术路线上来讲,我们会沿着这四步逐步实现。
第一步我们现在还在做单库的问答 Agent,这个领域是非常前沿的,我们现在在做单库的问答 Agent,近期会上线。
下一步我们希望推出能独立完成编码任务的 Agent,它的作用主要是具备一定的自主规划能力,可以使用一些工具去了解背景知识,能够自主的完成单库范围内的编码任务,还不是跨库,可以想象一个需求有多个代码库,然后前端也改、后端也改,最终形成一个需求,我们觉得还很远。
所以我们先实现单库的编码 Agent,下一步我们会去做测试 Agent,测试 Agent 可以基于代码 Agent 的生成结果,自动完成一些测试任务,包括理解任务的需求、阅读代码、生成测试用例,并且自主运行。
如果这两步的成功率做的比较高的话,我们就会进入到第三步。让多 Agent 基于 AI 调度共同完成任务,从而实现从需求到代码到测试的全流程自主化。
从工程的角度来讲,我们会一步一步这么来走,确保每一步都达到一个比较好的生产级落地,最终去做产品。但是从学术来讲,他们研究的速度会比我们更快,现在我们是从学术、工程讨论的,我们还有第三个分支就是模型演进。这三条路就是我们现在阿里云和通义实验室一起联合在做的一些研究。
最终,我们会形成一个 Multi-Agent 概念架构,用户可以跟大模型进行对话,大模型可以进行任务的拆解,然后有一个多 Agent 协同系统。这个 Agent 可以外挂一些工具,它有自己的运行环境,然后多 Agent 之间可以互相协同,它们还会共享一些上下文机制。
这个产品图会分为三层。最下面是基础层,对于企业来讲,可以先把基础层做好。比如现在可以引入一个代码大模型,我们虽然没有马上实现 AI Bot,但是现在已经具备了 IDE 代码生成插件的这些能力,已经可以做一些工作了,就是 Copilot 的模式。
Copilot 模式在基建层上面,进化了 Agent 这一层,实际上基建是可以复用的。该做的检索增强、微调训练和知识库,现在就可以做起来了。这些知识的梳理,资产的积累,是来自于原来 DevOps 平台的积累。现在就可以通过一些提示词工程的方式,将现在基础的能力层跟整个 DevOps 工具链进行结合。
我们做了一些实验,在需求阶段要想让这个大模型来实现一个需求的自动拆解,我们可能只需要将过去的一些拆解数据,还有现在的需求拼成一个 prompt 给大模型,大模型就可以比较好的去完成拆解并且完成人员的分配。在实验中发现,结果的准确率还是蛮高的。
其实现在整个 DevOps 工具链,并不需要所有东西都要用 Agent 或者都要用 Copilot。我们现在用一些提示词工程,就有很多场景可以马上去赋能,包括我们在 CICD 过程中的自动排错,在知识库领域的智能问答等都可以实现。
在实现多 Agent 以后,这个 Agent 可以在 IDE 里面透出,也可以在开发者的门户,即 DevOps 平台透出,甚至在我们的 IM 工具里面透出。它实际上是一个拟人的智能体。本身这个智能体它会有自己的工作区,在这个工作区里我们的开发者或者说管理者可以去监控它到底是如何帮我们完成代码编写的,如何帮我们完成测试的,它到底在互联网上获取了什么样的知识去完成工作,会有一个它自己的工作空间,最终实现整个任务的完整流程。
版权声明: 本文为 InfoQ 作者【阿里巴巴云原生】的原创文章。
原文链接:【http://xie.infoq.cn/article/15e31f71a9c0985eeb4e901d9】。文章转载请联系作者。
评论