外链论坛

 找回密码
 立即注册
搜索
查看: 9|回复: 1

AI 自动编程的智能体语言与框架构建?IDE 插件 AutoDev 示例

[复制链接]

2886

主题

2万

回帖

9997万

积分

论坛元老

Rank: 8Rank: 8

积分
99979645
发表于 2024-10-2 20:51:29 | 显示全部楼层 |阅读模式

上周微软发布了自家的 AI 编程和软件研发智能体框架:AutoDev,其与咱们研发的 IDE 插件 AutoDev 有颇多的类似之处,尤其有些设计思路,以及在针对辅助软件研发任务的智能体以及有些基本设备上。

稍有区别的是:

交互介质咱们的 AutoDev 构建基于 IDE API 体系构建的,而微软的 AutoDev 则是构建以 CLI 为主。隔离环境咱们设计了 DevIns 语言来构建隔离环境,而微软的 AutoDev 则是基于 Docker 隔离环境。

当危,咱们的 AutoDev 研发人数比较有限,因此相比于微软的 AutoDev 成熟度上是相对比较低的。思虑咱们的 AutoDev 是一年前开源的,而微软的 AutoDev 是近期发布的,她们这取名有点不厚道。

AI 驱动软件研发的本质:“人类—AI—代码”的桥梁

针对 AI 驱动的自动编程来讲,无非便是让 AI 能理解好人类的需要而后实现 AI 与代码环境的自动交互。更仔细来讲,便是:

人类经过自然语言交互描述软件研发任务,如解释代码、生成代码、运行测试等。AI 结合智能体与上下文理解人类的需要,并生成对应的指令文本。代码环境接收指令文本,并执行对应的操作,再返回结果给人类 AI。

因此呢咱们所要构建的上是一个基于 “人类—AI—代码环境” 的沟通桥梁。实现让 AI 能理解人类的需要,并不是一件繁杂的事情,经过额外的需求澄清、展开, 就有初步得到格式化后的需要。而让 AI 与代码环境进行交互,则是一件更繁杂的事情,即怎样经过指令文本来实现的。

方式 1:基于文本的函数调用

函数调用(Function calling)能够研发人员声名一系列的函数,将其与对应的说明传递给语言模型,让语言模型按照这些说明来生成格式化的结果。随后, 在对应的工具中,调用对应的 API 来实现对应的操作。诸如于 Google AI 中语言模型生成的返回结果示例:

{"functionCall": {"name": "find_theaters","args": {"movie": "Barbie","location": "Mountain View, CA"}}}

类似的方式,还有让 AI 生成对应的代码,如 shell 等,而后执行对应的代码。

方式 2:语言抽象的研发环境

咱们针对自动化的探索是来自于 AutoDev 第1需要,针对 Spring 框架的 AutoCRUD。在这个需要中,咱们发掘繁杂的软件研发任务中,需要动态生成 高质量上下文,以让 AI 能在对应的问题域中生成对应的代码。诸如于,生成 Controller 代码,需要晓得现有 Controller,规范,以及对应的 Service、Repository 等代码。这一系列的信息,寓意着,咱们需要一个更高级别的语言来描述这些信息。

随后,咱们在 AutoDev 中构建了一系列 Auto 功能(针对 React 的 AutoPage、针对鸿蒙操作系统的 AutoArkUI 等),以探索更合适的语言抽象来描述 “人类—AI—代码环境”,即 DevIns 语言。经过语言来做为人机接口,并做为可执行的代码,来实现对代码环境的操作。诸如于:

/patch ```patch // the patch to apply ```

经过形式化的方式来描述对 IDE 的操作,易于让 AI 理解,易于让代码环境执行。

设计基于 IDE 的编程智能体研发

在设计 AutoDev 的自动编码功能时,咱们依旧是根据在 Unit Mesh 架构范式下的设计思路来设计的, 即 AI 生成的都是可验证的代码。因此呢,在咱们设计 AutoDev 的自动测试功能时,是基于这个思路来设计的。当然了,在有了 DevIns 语言后,就能实现 更加多的自动化(理论上)。

接下来,让咱们实质需要出发,以三个例子来瞧瞧平常的编码能够怎样设计:

验证生成代码是不是工作?进行安全的代码信息提交?探索自动化问题辅助修复?

当然了,还能够更加多区别示例,这儿就不一一列举了。

示例过程 1:经验证可工作的代码

不论是人类,还是 LLM,要验证一段代码是不是工作正确,最简单的方式便是运行它。运行它,一般有多种方式:

直接起步应用。通用 IDE CLI 来起步应用程序,经过交互界面 API 来验证代码的正确性。单元测实验证代码。即经过生成单元测试,以验证生成业务代码的正确性。构建 REPL 环境。而交互环境针对繁杂应用的依赖管理并非易事,因此并非那样容易。

起步应用的效率相比,显然经过测试驱动研发(TDD)来验证代码的正确性更加有效因此呢,在结合 IDE 时,则需要多思虑一步:如何运行测试以验证代码。

于是,咱们设计了一个简单的测试运行指令:

/run:src/test/java/cc/unitmesh/MathHelperTest.java

这般咱们成为了代码后,便能够经过运行测试来验证代码的正确性。因为 Intellij IDEA 支持区别的语言,然则区别的语言运行方式等是区别的。而因为 JetBrains IDE 运用了统一的底层抽象:RunConfiguration因此呢咱们构建了一个 RunService 来封装区别语言的运行方式:

interface RunService { fun createConfiguration(project: Project, virtualFile:VirtualFile): RunConfiguration? = nullfun runFile(project: Project, virtualFile: VirtualFile): String? { } }

仔细能够参见 RunService.kt 代码。

示例过程 2:安全的 Git 操作

既然,咱们成为了可验证的代码,那样下一步,咱们应该思虑的是结合 VCS 来进行代码提交。为了保证不执行不安全的操作,咱们不直接执行 Git 操作,而 是借助于 IDE 的 VCS API 来执行对应的操作。

于是,咱们设计了 /commit 指令来提交代码:

/commit ```commitfeat: add new feature```

针对需要更繁杂的场景,诸如于远程生成的任务来讲咱们经过 /patch 指令来

示例过程 3:自动化问题辅助修复

接下来,咱们的挑战便是怎样在 IDE 获取运行结果,并按照结果来进行对应的操作。于是,咱们在 AutoDev 中设计了一个 DevInsProcessProcessor 来 处理 DevIns 指令的执行结果:

when { event.exitCode == 0 -> { val comment = lookupFlagComment(devInFile!!).firstOrNull() ?: return ///handle flag comments } event.exitCode != 0 -> { project.service<DevInsConversationService>().tryFixWithLlm(scriptPath) } }

即:

成功。当 exitCode 为 0 时,咱们能够经过 flag comments 来决定怎样处理失败。当 exitCode 不为 0 (如 -1)时,咱们能够继续经过 AI 来尝试修复对应的问题

在失败的场景时,咱们需要构建完整的上下文:输入、编译输出、 执行结果/LLM 返回结果,以便于 AI 能更好的理解问题,再给出对应的修复方法

仔细能够参见 DevInsProcessProcessor.kt 代码。

其它

咱们依旧还在设计适用于 IDE 的自动研发框架与 DevIns 语言,倘若大众有兴趣,能够参与到咱们研发中来。

GitHub:https://github.com/unit-mesh/auto-dev

回复

使用道具 举报

3008

主题

2万

回帖

9913万

积分

论坛元老

Rank: 8Rank: 8

积分
99139175
发表于 2024-10-8 13:45:04 | 显示全部楼层
哈哈、笑死我了、太搞笑了吧等。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

站点统计|Archiver|手机版|小黑屋|外链论坛 ( 非经营性网站 )|网站地图

GMT+8, 2024-11-6 08:03 , Processed in 0.067961 second(s), 19 queries .

Powered by Discuz! X3.4

Copyright © 2001-2023, Tencent Cloud.