AI Agent + DevEco CLI:鸿蒙应用自动化开发实测记录
前阵子我把一台开了开发者模式的手机插上电脑盯着终端里一个 AI Agent 自己建目录、自己写代码、自己编译、自己修错最后还把应用装到了手机桌面上。说实话第一次跑通整个流程的时候我还是挺意外的。鸿蒙开发这种过去几乎被 IDE 绑定得死死的事情现在靠一套稳定的命令行工具链配合一个稍微有点耐心的 Agent居然能全程无人值守地走完。这篇文章就是那段时间的实测记录。我不会堆一堆“AI 改变开发”的漂亮话只讲实际跑通的东西DevEco CLI 到底能接管哪些环节Agent 在哪些地方真的靠谱哪些地方一碰就翻车以及我最后总结出来的一套“能把活干完”的协作方式。如果你也想试试让 Agent 给你写鸿蒙应用这篇应该能帮你少踩不少坑。1. 为什么 AI 写鸿蒙应用这件事必须从命令行说起1.1 不是 Agent 不够聪明是 IDE 不向 Agent 开放很多人第一次尝试让 AI 写鸿蒙应用方式基本是让 AI 生成一段 ArkTS 代码然后自己打开 DevEco Studio手动新建工程、把代码贴进去再点运行。这其实不是“AI 写应用”而是“AI 写代码片段”中间所有需要和工程环境打交道的事情还是人在做。真正的“Agent 自己写应用”指的是 AI 能独立完成从创建工程到构建、签名、安装的整条链路。这里有个绕不开的现实问题DevEco Studio 的图形界面是给人用的Agent 没法点按钮。它唯一的抓手就是命令行工具。所以我做的第一件事就是把 Agent 和 DevEco 的命令行工具链对接起来。对接完之后Agent 可以自己执行命令、读取输出、根据报错改代码、再重新构建形成一个完整的自动化闭环。图形界面这边完全没有打开过。1.2 DevEco CLI 到底包含哪几件趁手的工具鸿蒙开发的命令行工具链没有很多人想象得那么神秘。我实测下来主力就是这几件工具作用对应图形界面功能hvigorw工程构建核心负责编译、打包 HAPDevEco Studio 里的 Sync 和 Build 按钮ohpm包管理器负责安装依赖图形界面里的 OhPM 面板hdc设备连接工具负责安装应用、运行调试一键运行到模拟器/真机SDK 自带工具链包含签名、资源编译等底层工具隐藏在 IDE 内部逻辑里其中最重要、实测里用得最多的就是 hvigorw。它就是鸿蒙版的 Gradle 思路工程根目录下会有hvigorw脚本执行hvigorw assembleHap就能把整个工程打包成可安装的 HAP 文件。Agent 写代码的能力固然重要但没有这套 CLI它写出来的代码就只是一堆没法运行的文本。CLI 是让 Agent 的代码“活”起来的关键通道。1.3 全自动流水线长什么样我实测中跑通的完整链路是用户需求描述 → Agent 规划工程结构 → 生成配置文件和 ArkTS 源码 → hvigorw 执行构建 → 解析编译错误 → 修改代码 → 重新构建 → 生成 HAP → 签名 → hdc 安装到设备 → 启动应用 → 验证结果这条链路里除了第一行的需求描述是我输入的后面所有步骤都是 Agent 自己循环执行的。它会读我给的工程要求把项目结构建好写完代码跑构建如果报错就自己看日志、找原因、改代码、再跑一次直到构建通过为止。后面几节我会把每个环节的细节和踩过的坑拆开说。先提醒一句链路跑通不代表万事大吉恰恰是跑通之后才是真正考验你工程能力的时候。2. 先把环境收拾利索CLI 接管的必要条件2.1 核心环境变量与最小依赖清单我第一次把 Agent 放上去跑结果它在第一步就卡了半小时执行hvigorw的时候直接提示找不到命令。原因很简单我在图形界面里装好了 DevEco Studio但命令行工具并不会自动注册到系统 PATH 里。你需要先确认这几个东西都在装好 DevEco Studio 之后SDK 里面自带了命令行工具但路径比较深一般在sdk/目录下的command-line-tools里。环境变量DEVECO_SDK_HOME要指向 SDK 目录这个变量比 PATH 更关键hvigorw 在构建时要用它定位 SDK 里的编译工具。如果hvigorw不在 PATH 里建议把command-line-tools/bin或者工程内.hvigor相关路径加进去或者干脆在 Agent 的 prompt 里写明“所有命令必须用绝对路径或先从某个路径 export”。我是怎么处理的我在给 Agent 初始化环境的脚本里最前面加了一段export DEVECO_SDK_HOME$HOME/你的路径/sdk export PATH$DEVECO_SDK_HOME/command-line-tools/bin:$PATH这样每次 Agent 启动子 shell 执行命令时环境都是对的。这个细节极其重要因为 Agent 执行命令时经常不是交互式登录 shell~/.bashrc里的配置它未必会加载。另外构建还需要 JDK。DevEco Studio 自带 JBRJetBrains Runtime但在纯命令行环境里你得手动把 JAVA_HOME 也指过去或者安装一个 JDK 17。我实测中直接引用了 DevEco 自带的 JBR 路径省事不少。2.2 签名问题CI 环境里最容易卡住的地方鸿蒙应用安装到真机或模拟器之前必须完成签名。图形界面里看起来很轻松因为你登录了华为账号IDE 会自动帮你生成签名文件、配置好 build-profile。但命令行环境下Agent 是没有“登录账号”这个概念的。我在实测里的做法是先在 DevEco Studio 里手动完成一次自动签名配置然后看工程里的build-profile.json5把签名相关配置读懂。之后命令行构建就会复用这套签名配置Agent 不需要操作签名过程hvigorw 构建时会自动读取配置完成签名。如果你真的想完全脱离 IDE 生成签名也可以走手动签名路线创建 .p12 密钥库、生成 .cer 证书请求、申请 profile 文件然后用 SDK 里的签名工具一次性签好。这条路非常折腾实测中我不建议普通场景去走。自动化流水线的最佳实践是保留一份签名配置文件在工程里让 Agent 始终复用。2.3 让 Agent 学会“看清编译输出”环境配好了但 Agent 的初始行为会让你崩溃它看到一大段编译日志经常抓不住重点反复修改无关代码。这不是 Agent 笨而是它的 prompt 里没告诉它“如何读日志”。我在 Agent 的系统提示里加了一段明确的指令当 hvigorw 构建失败时从日志中寻找“ERROR”和“FAILED”相关行优先处理第一个错误。不要根据猜测同时修改多个文件。修复一个错误后立即重新构建直到没有新错误出现。这个指令加上之后Agent 的行为立刻聪明了许多。它在迭代时的模式变成了读第一个错误 → 定位到具体文件 → 做最小修改 → 构建 → 读下一个错误。这其实就是我们人眼排查问题时的做法只不过现在 Agent 能自己执行这套循环了。3. 实战记录让 Agent 从零构建一个待办应用3.1 任务书给 Agent 一个可验收的需求描述我给 Agent 出的题目是一个最简单的待办事项应用。需求描述写得很明确越明确 Agent 的产出越可控请创建一个鸿蒙应用工程目录名 todo_app。要求 1. 使用 Stage 模型开发语言 ArkTSUI 基于 ArkUI 声明式语法。 2. 实现待办列表可以添加事项、删除事项、标记完成。 3. 数据用数组保存在内存即可不做持久化。 4. 界面布局顶部输入框 添加按钮下方 List 列表展示。 5. 页面入口为 EntryAbility首页路径 pages/Index。 6. 构建必须通过 hvigorw assembleHap 命令。 7. 不要引入任何第三方依赖。这里有一个关键设计我把“验收标准”直接写进了需求里。第 6 条让 Agent 明确知道自己最终要过的是hvigorw assembleHap这一关而不是“写看起来差不多的代码”。实测下来这个写法极大地减少了 Agent 耗时因为它会主动去适配构建工具的要求。3.2 Agent 自动搭建工程骨架收到任务后Agent 的第一步动作是对照鸿蒙工程的标准结构手动创建文件。没有用模板脚手架因为它发现工程目录还不存在hc 相关的初始化命令在 DevEco CLI 里并不像后端框架那样成熟所以它选择直接手写工程结构。它创建的文件包括todo_app/ ├── AppScope/ │ ├── app.json5 │ └── resources/ ├── entry/ │ ├── build-profile.json5 │ ├── hvigorfile.ts │ ├── oh-package.json5 │ └── src/main/ │ ├── module.json5 │ ├── ets/ │ │ ├── entryability/EntryAbility.ets │ │ └── pages/Index.ets │ └── resources/ │ ├── base/element/string.json │ ├── base/media/ │ └── base/profile/main_pages.json ├── build-profile.json5 ├── hvigorfile.ts ├── oh-package.json5 └── hvigor/ └── hvigor-config.json5这个结构它不是猜出来的而是根据 DevEco 官方文档的工程规范还原的。这里我不得不提一句Agent 之所以能还原出这个结构是因为训练数据里包含了大量的鸿蒙工程范例。如果是一个特征很冷门的框架它大概率做不到这一步。骨架搭好之后Agent 会先执行一次ohpm install初始化依赖。这里我加了点小经验把 ohpm 的仓库配置指向可以正常访问的镜像源这一步在部分网络环境下会节省大量时间而且 Agent 遇到包下载失败时会反复重试挺浪费的。3.3 自动编译与迭代修复工程骨架完成后Agent 开始写核心代码。它先写了module.json5和app.json5把 bundleName、abilities、pages 等配置补全然后写了EntryAbility.ets和首页Index.ets。第一次执行hvigorw assembleHap毫无悬念地失败了。我截取了当时报错日志中最关键的一段[ERROR] Failed to run task ArkTSCompile. [ERROR] entry/src/main/ets/pages/Index.ets:8:17 - ArkTS:API List is not available in this component.报错信息说List组件不可用。这个问题的真实原因是 Agent 在 ArkTS 里用了不标准的写法——它把List当成了泛型容器类型在组件渲染区域里直接声明了一个Liststring这跟 ArkUI 的List组件产生了命名冲突。Agent 的修复策略很有意思它没有把变量改名而是直接把那个变量名从List改成了taskList并且同步修改了所有引用位置。这个修复很小但方向完全正确。改完之后重新构建这次走到了更远的阶段报错变成了资源文件缺失[ERROR] resource string/entry_desc is not foundAgent 打开string.json看了一眼发现里面只有一个应用名字符串缺少entry_desc它主动把这个字符串补上了顺带把main_pages.json里登记的页面路径做了校验。第二轮构建通过。我在旁边算了一下从第一次构建失败到构建通过Agent 一共完成了三次代码修改耗时大概 4 分钟。这个速度已经相当能打了。3.4 签名、安装、验证一整套流程亲测可用构建出 HAP 之后真正的考验来了签名和安装。我在工程里预先配置好的自动签名文件此时发挥了作用。Agent 执行构建命令时hvigorw 会根据build-profile.json5里的配置自动完成签名所以 Agent 不需要额外处理签名逻辑。输出目录里出现了一个带签名的 HAP 文件体积大约几百 KB。接下来 Agent 调用 hdc 工具把手机通过 USB 连到电脑上。先执行hdc list targets确认设备在线然后执行hdc install -r entry/build/default/outputs/default/entry-default-signed.hap安装成功后Agent 并没有停手它接着执行了启动命令hdc shell aa start -a EntryAbility -b com.example.todoapp这是我最意外的地方。它知道用aa start命令来拉起应用而不是让我去手机屏幕上手动点图标。这说明 Agent 对鸿蒙系统的调试机制是有基本认知的不是只会照着文档抄命令。启动后我看了手机屏幕应用正常打开界面显示输入框、添加按钮和一个空列表。我手动添加了一条待办App 没有闪退列表正常渲染。到这一步整条自动化链路算是完整跑通了。4. 真实踩坑Agent 不是神这些环节必须有护栏4.1 编译报错无限循环给 Agent 加上“三振出局”机制我遇到过最让人抓狂的情况是 Agent 在同一个报错上反复打转。它改了一版代码报错 A再改一版还是报错 A再改报错 A 的变体……原因是它在用户 prompt 里没有被限制迭代次数加上它对自己修改后的代码过于自信每次都只改表面不查根因。后来我加了一条硬性护栏prompt 里明确规定“同一个错误信息若连续出现 3 次停止修改输出当前所有相关代码和日志等待人工指示”。这个“三振出局”机制非常管用。加了之后Agent 不会再在一个点上死磕而是在卡住时主动把现场信息整理出来我一看就知道问题在哪。实际工作中让人工介入的时机越早浪费的 token 和精力就越少。别让 Agent 一个人演独角戏该设止损线就设止损线。4.2 上下文遗忘长文件改到最后忘了开头Agent 的上下文窗口虽然是有限的但这不代表它会主动记住所有内容。在处理较复杂的工程文件时Agent 容易出现一个典型症状改到文件末尾时忘了开头声明的变量类型和数据流。我遇到的一次事故是这样的Agent 在一个Index.ets里把列表数据结构从Arraystring改成了Array{ id: number, text: string, done: boolean }但页面顶部State声明的初始值还是旧的字符串数组。编译直接报类型不匹配。Agent 看了报错之后没有回头改State反而把下面适配新结构的代码又改回旧结构结果两边来回折腾越改越乱。这个坑的解法有两个在任务书里明确要求“修改数据结构时同步检查所有引用点”。把文件拆小。让 Agent 每个页面的代码量控制在合理范围内不要一个.ets文件写上千行。它维护的粒度和人一样文件越小越不容易出错。4.3 签名盲区Agent 为什么总在证书上翻车有一次我清理了电脑的缓存重新拉了一个新环境给 Agent 用。结果它在签名阶段反复报错来回试了很多次日志显示sign hap failed。我进去看发现它完全不理解证书、profile、密钥库之间的关系。它尝试自己生成了一组新的证书去签名但因为配置文件里的 bundleName 和 profile 里的包名不一致签名后安装到设备直接被拒。这个问题它自己折腾了很久没解决最后我把之前备份的build-profile.json5和签名文件恢复回去才顺利通过。如果你打算让 Agent 处理签名一定要在 prompt 里明确告诉它签名配置已经存在不要动它。Agent 对签名机制的理解还停留在“有一组神秘文件就能过”的程度让它自由发挥大概率会出事。4.4 命令环境的坑非交互式 shell 下 PATH 不完整Agent 执行命令时通常是通过一个子进程来调用的这个子进程默认不是交互式 shell所以很多你在本地终端里能用的命令Agent 的环境里可能根本没有。我遇到的问题是ohpm命令找不到。本地终端里ohpm能用因为它在.bashrc里被 export 了。但 Agent 的子进程没有加载.bashrc所以执行ohpm install时报 command not found。解决方案是在 Agent 的系统 prompt 里写死一条规则每次执行命令前必须先执行环境初始化脚本例如source $HOME/ohpm/env.sh export DEVECO_SDK_HOME... export PATH...。把环境初始化变成 Agent 的固定习惯之后这类问题就再也没出现过了。5. Agent 写的代码到底能不能用质量评估与分工建议5.1 能用跟好用之间的差距在哪把“跑起来”作为唯一标准的话Agent 写的应用完全达标。但如果你抱着“直接交付生产环境”的期待那还得泼一盆冷水。我实测生成的待办应用有几个明显问题第一代码组织比较“平铺”。Agent 把所有逻辑都堆在Index.ets里没有拆分组件。如果后续要给列表项加交互逻辑这个文件会变成无底洞。第二状态管理方式比较简单没有用Observed等更 robust 的方案数据是“能用级别”而非“好维护级别”。第三代码存在重复片段。比如添加待办和删除待办的对话框逻辑它写了两遍近似的代码没有抽公共函数。这些问题是 Agent 的生成习惯导致的。它在训练数据里见过无数种写法但生成的时候倾向于复制最普遍的“最短路径”而不是为你做架构设计。想让它产出更干净的代码你需要把“拆组件”“抽公共逻辑”“注释规范”等要求直接写进任务书里它才会照做。5.2 建议的分工方式模板化 Agent 人工 Review经过几次实测我现在比较倾向于一种“模板化 Agent 人工 Review”的协作方式我先整理出一套标准工程模板包括目录结构、基础配置、公共组件、工具函数。每次让 Agent 开发新页面时要求它基于模板来写而不是从零开始。Agent 完成构建后我会亲自 Review 关键代码文件特别是module.json5、app.json5和状态管理相关的部分。涉及系统能力相机、定位、通知的部分我会单独写 Demo 给 Agent 参考不让它自由发挥。这套协作方式下Agent 在自动化重复劳动上发挥很大价值而人要盯住的是架构边界和系统级能力的调用。至少在我目前实测的项目里这样的分工是效率最高的。5.3 下一步可以怎么玩跑通这个流程之后我还在尝试让 Agent 做更复杂的事情。比如把设计稿截图丢给它让它照着界面还原页面比如让它读崩溃日志自己定位到具体代码行并修复。这些方向目前还处在实验阶段但跑通整条 CLI 链路之后这些扩展都具备了基础条件。我个人的建议是如果你想试探 Agent 写鸿蒙应用的能力边界先从“单个页面 简单交互”开始。这个范围内Agent 的可靠度很高。等你有信心之后再逐步扩大任务范围让它处理多模块、多页面跳转、系统 API 调用等复杂场景。每往深走一步你对它的信任边界就会更清晰一分。最后再分享一个我自己的实操心得别急着追求“全自动无人值守”那只是一个理想状态。真正可持续的高效模式是“Agent 跑流程人盯关键点”。AI 帮你省下的是那些重复、机械、耗时间的部分判断和决策的活至少在鸿蒙开发这个领域还得靠你自己。