AutoDev: AIGC 助力鸿蒙原生应用开发
英国19世纪中期著名作家、评论家狄更斯曾说:“It was the best of times, it was the worst of times”,而今我们处在高速发展的 21 世纪,同样也是最好的时代和最坏的时代。AI 已经成为这个时代的一个突出特征,给我们生活、工作的各个方面带来了革命性的变化;战争、失业、环境问题等也成为这个时代的严重挑战;作为开发者,我们更关注如何精进自我。在东方,掀起了一波学习鸿蒙开发的浪潮,“全新的鸿蒙操作系统Harmony OS NEXT蓄势待发,鸿蒙原生应用全面启动”,这意味着我们有一个广阔的领域可以去开拓和创造。对于鸿蒙原生应用开发来说,借助 AI 工具能让我们事半功倍,比如 AutoDev.
关于鸿蒙原生应用开发
不知道您身边有没有朋友跟您提起过“鸿蒙原生”,虽然鸿蒙发布至今已经有4年多了,但市面上的鸿蒙手机大多都兼容安卓,以至于大家会有些其他想法。2023年9月,鸿蒙原生应用全面启动;2024年1月,HarmonyOS Next 鸿蒙星河版正式发布。移动互联网应用方面,以支付宝、美团等为代表的Top 20移动互联网应用中已有约半数启动了鸿蒙原生应用的开发;游戏开发方面,已有60+游戏伙伴加入鸿蒙生态合作,超过70款游戏已经完成鸿蒙原生应用开发;生态赋能方面,众多企业、学校等机构积极拥抱鸿蒙原生开发,共筑鸿蒙生态。
图片来源:微博作为开发者来说,“鸿蒙生态千帆启,学习鸿蒙正当时”,未来的发展是怎样的,也许我们很难预判;把握当下,我们可以的!
HarmonyOS NEXT应用开发案例集:https://gitee.com/harmonyos-cases/cases
关于 AutoDev
AutoDev: https://github.com/unit-mesh/auto-dev
❝🧙 AutoDev:人工智能驱动的编码向导,具有多语言支持🌐、自动代码生成🏗️和有用的错误清除助手🐞!包括可自定义的🎨提示和神奇的自动开发/测试/文档功能🧪!🚀
AutoDev提供了多种功能,包括多语言支持、自动代码生成、错误修复助手、可定制的提示和自动测试功能。AutoDev 旨在通过 AI 技术简化编程过程,使开发者能够更专注于创造性工作。
AutoDev 的特点包括:
-
多语言支持:支持 Java, Kotlin, JavaScript/TypeScript, Rust, Python, Golang, C/C++/OC 等。
-
自动开发模式:包括 AutoCRUD (Spring framework), AutoSQL(上下文感知型 SQL 生成), AutoPage(情境感知页面生成)、AutoTesting(创建单元测试意图)、AutoDocument(自动生成文档)、AutoArkUI(自动生成 HarmonyOS ArkUI 代码) 等。
-
Copilot 模式:根据代码上下文、最近的文件更改提供最佳代码建议;帮助我们查找错误、解释代码、跟踪异常、生成提交等。
-
聊天模式:与 AI 聊天,讨论代码相关问题。
-
自定义模式:根据我们自定义的 Prompt 添加意图操作;使用自定义大语言模型服务等等。
-
支持 CI/CD、Dockerfile 等 DevOps 基础架构。
-
内置 LLM 微调,由生成式 AI 赋能软件研发开源解决方案 UnitMesh 驱动。
前提准备
❝Tips: 本文使用 DevEco Studio 4.0 Release、AutoDev 1.6.4-222 以及 星火 API
前提准备:
- DevEcho Studio
- 星火 API (或者其他 LLM 服务,如 OpenAI API key)
下载安装 DevEcho Studio
HUAWEI DevEco Studio 是面向HarmonyOS应用及元服务开发者提供的集成开发环境(IDE), 助力高效开发。
官方网站:https://developer.huawei.com/consumer/cn/deveco-studio/
截止目前(2024年02月28日),我们在官网能下载的最新版本是DevEco Studio 3.1.1 Release (PS:DevEco Studio 3.1配套支持HarmonyOS 3.1及以下版本的应用及服务开发,如需使用DevEco Studio NEXT Developer Preview1版本,请参加Beta招募活动),如需安装 DevEco Studio 4.0 Release 版本可从 OpenHarmony下载.
DevEco Studio 4.0 Release软件 | 版本 | 备注 |
---|---|---|
OpenHarmony | 4.0 Release | NA |
Public SDK | Ohos_sdk_public 4.0.10.13 (API Version 10 Release) | 面向应用开发者提供,不包含需要使用系统权限的系统接口。通过DevEco Studio默认获取的SDK为Public SDK。 |
HUAWEI DevEco Studio(可选) | 4.0 Release | OpenHarmony应用开发推荐使用。获取方式:Windows(64-bit) SHA256校验码:2c88cf43e1ef6ba722aac31eccc8ef92f07a9b72e43a9c1df127017828a22137 Mac(X86) SHA256校验码:25e491458eec50b4abddf5bed6aa85893801d70afbce02958f17bd904619405a Mac(ARM) SHA256校验码:284cb01f7b819e0da1d4fcacbbbbe8017ba220b5e3b9b1d5e4cc59ea30456acc |
HUAWEI DevEco Device Tool(可选) | 4.0 Release | OpenHarmony智能设备集成开发环境推荐使用。 请点击这里获取。 |
IDE 的下载安装和使用技巧请参考鸿蒙官方教程:
<HarmonyOS第一课>运行Hello World: https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101667303102887820
使用DevEco Studio高效开发: https://developer.huawei.com/consumer/cn/training/course/slightMooc/C101680766639443507
注册星火 API
请访问https://xinghuo.xfyun.cn/sparkapi注册。目前星火 API 给到个人的免费额度是 200 万 tokens,暂时可以用一阵子。此处以星火认知大模型3.5为例,本文实际使用的是3.0
星火 API我们点击【免费试用】即可跳转到应用创建页面。
应用创建完毕之后,我们可以去到应用控制台查看,此时我们需要复制保存:APPID、APISecret、APIKey,后续需要填写到 AutoDev 的配置中
AutoDev安装 AutoDev
请访问https://plugins.jetbrains.com/plugin/21520-autodev下载 AutoDev,如果您使用的是 DevEcho Studio 4.0 ,请下载1.6.4-222
AutoDev接着我们打开 DevEcho Studio 的插件管理,从本地安装下载的 AutoDev 并重新启动 IDE。
Install AutoDevAutoDev 安装之后,我们会发现 IDE 中多了好几个相关的入口,比如右下角、右侧边栏、编辑区域右键菜单等等都能看到 AutoDev 的身影。
AutoDev Use我们可以点击右下角 AutoDev 图标快速打开配置窗口并填写配置,请注意 APIKey、APISecret 要和星火 API 配置一一对应。
AutoDev Config简单测试一下:
AutoDev Chat快速上手
❝Tips: 本文使用 DevEco Studio 4.0 Release、AutoDev 1.6.4-222 以及 星火 API
万事俱备,只欠东风;此时此刻需要我们亲自去创造、去感受 AI 辅助编程的魅力。
自动生成 ArkUI
我们通过空白模版创建了一个 API 9 的 HarmonyOS 应用(PS:博主暂时没有权限创建 API 10 的 HarmonyOS),我们在首页中添加// 生成一个经典的前端 counter
并选中然后点击右键选择Auto Generate ArkUI
, AutoDev 会帮我们生成代码,复制粘贴、简单review及修改之后就能使用。不过笔者使用的星火3没能正常返回代码,大概需要星火3.5,我们通过改用 OpeaAI API key 之后能够正常返回。
正常运行:
Auto Generate ArkUI自动补全
官方提供了对应的 AI 代码补全功能,可以帮助开发者快速生成代码。
Code Complate自动生成文档
我们可以选中代码通过 AutoDev 自动生成文档。
自定义模式:添加 Gen HarmonyOS Test
❝Tips: 参考 https://harmonyos-dev.github.io/aigc-harmonyos-sample/autodev-test-gen.html
-
在项目根目录创建
prompts/Gen-HarmonyOS-Test.vm
文件,写入prompt
-
右键选中内容,执行
AutoDev AI Action
,点击Gen HarmonyOS Test
即可生成测试代码。 -
Prompt 示例:
interaction: ChatPanel
---
Write Test for follow ${language} language code.
1. You should use `describe` `it` `expect` to write test.
2. Here is '@ohos/hypium' test framework support method, you can use it:
```ArkTS
assertClose(expectValue: number, precision: number): void, assertContain(expectValue: any): void, assertEqual(expectValue: any): void,
assertFail(): void, assertFalse(): void, assertTrue(): void, assertInstanceOf(expectValue: string): void, not(): Assert;,
assertDeepEquals(expectValue: any):void, assertPromiseIsPending(): void, assertPromiseIsRejected(): void,
assertPromiseIsRejectedWith(expectValue?: any): void, assertPromiseIsRejectedWithError(...expectValue): void,
assertPromiseIsResolved(): void, assertPromiseIsResolvedWith(expectValue?: any): void
```
For example:
```ArkTS
import { describe, it, expect } from '@ohos/hypium'
export default function abilityTest() {
describe('ActsAbilityTest', function () {
it('assertContain',0, function () {
let a = 'abc'
let b = 'b'
expect(a).assertContain(b)
expect(a).assertEqual(a)
})
})
}
```
Here is user code:
```ArkTS
${selection}
```
Please write test for it, use markdown syntax.
Gen HarmonyOS Test
除了上述功能,AutoDev 未来还会支持生成鸿蒙原生应用持续集成、更多 LLM 支持如 Yi 大模型……
补充
如果 AutoDev 插件遇到以下异常请先忽略,我们体验了多款 AI 辅助编程工具,都有不同程度的异常抛出,但不影响使用。
java.lang.ClassNotFoundException
com.intellij.diagnostic.PluginException: cc.unitmesh.devti.actions.chat.ChatBotExplainAction PluginClassLoader(plugin=PluginDescriptor(name=AutoDev, id=cc.unitmesh.devti, descriptorPath=plugin.xml, path=~/Library/Application Support/Huawei/DevEcoStudio4.0/plugins/intellij-autodev, version=1.6.2-222, package=cc.unitmesh, isBundled=false), packagePrefix=cc.unitmesh., instanceId=24, state=active)
at com.intellij.serviceContainer.ComponentManagerImpl.instantiateClass(ComponentManagerImpl.kt:1014)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.instantiate(ActionManagerImpl.java:202)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.convertStub(ActionManagerImpl.java:187)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.getActionImpl(ActionManagerImpl.java:534)
at com.intellij.openapi.actionSystem.impl.ActionManagerImpl.getAction(ActionManagerImpl.java:523)
at com.intellij.openapi.actionSystem.DefaultActionGroup.unStub(DefaultActionGroup.java:401)
at com.intellij.openapi.actionSystem.DefaultActionGroup.getChildren(DefaultActionGroup.java:357)
at com.intellij.openapi.actionSystem.DefaultActionGroup.getChildren(DefaultActionGroup.java:336)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.doGetChildren(ActionUpdater.java:730)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$new$1(ActionUpdater.java:125)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$callAction$5(ActionUpdater.java:186)
at com.intellij.diagnostic.telemetry.TraceKt.computeWithSpan(trace.kt:123)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.callAction(ActionUpdater.java:182)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.callAction(ActionUpdater.java:161)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$new$2(ActionUpdater.java:125)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$getGroupChildren$23(ActionUpdater.java:535)
at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.getGroupChildren(ActionUpdater.java:543)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.iterateGroupChildren(ActionUpdater.java:677)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.expandGroupChild(ActionUpdater.java:578)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$doExpandActionGroup$22(ActionUpdater.java:528)
at com.intellij.util.containers.ContainerUtil.concat(ContainerUtil.java:1406)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.doExpandActionGroup(ActionUpdater.java:528)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.expandActionGroup(ActionUpdater.java:309)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$doExpandActionGroupAsync$14(ActionUpdater.java:372)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$doExpandActionGroupAsync$15(ActionUpdater.java:392)
at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1111)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$tryRunReadActionAndCancelBeforeWrite$19(ActionUpdater.java:424)
at com.intellij.openapi.progress.util.ProgressIndicatorUtilService.runActionAndCancelBeforeWrite(ProgressIndicatorUtilService.java:63)
at com.intellij.openapi.progress.util.ProgressIndicatorUtils.runActionAndCancelBeforeWrite(ProgressIndicatorUtils.java:128)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.tryRunReadActionAndCancelBeforeWrite(ActionUpdater.java:420)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$doExpandActionGroupAsync$16(ActionUpdater.java:392)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:186)
at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$executeProcessUnderProgress$13(CoreProgressManager.java:604)
at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:679)
at com.intellij.openapi.progress.impl.CoreProgressManager.computeUnderProgress(CoreProgressManager.java:635)
at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:603)
at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:60)
at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:173)
at com.intellij.openapi.progress.util.BackgroundTaskUtil.runUnderDisposeAwareIndicator(BackgroundTaskUtil.java:366)
at com.intellij.openapi.actionSystem.impl.ActionUpdater.lambda$doExpandActionGroupAsync$17(ActionUpdater.java:391)
at io.opentelemetry.context.Context.lambda$wrap$1(Context.java:212)
at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:243)
at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:29)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.executeFirstTaskAndHelpQueue(BoundedTaskExecutor.java:216)
at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:212)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:205)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:702)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:699)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:699)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.ClassNotFoundException: cc.unitmesh.devti.actions.chat.ChatBotExplainAction PluginClassLoader(plugin=PluginDescriptor(name=AutoDev, id=cc.unitmesh.devti, descriptorPath=plugin.xml, path=~/Library/Application Support/Huawei/DevEcoStudio4.0/plugins/intellij-autodev, version=1.6.2-222, package=cc.unitmesh, isBundled=false), packagePrefix=cc.unitmesh., instanceId=24, state=active)
at com.intellij.serviceContainer.ComponentManagerImplKt.doLoadClass(ComponentManagerImpl.kt:1519)
at com.intellij.serviceContainer.ComponentManagerImplKt.access$doLoadClass(ComponentManagerImpl.kt:1)
at com.intellij.serviceContainer.ComponentManagerImpl.instantiateClass(ComponentManagerImpl.kt:1006)
... 53 more