讨论广场 讨论详情
DevEco Code&DevEco CLI 体验复现体验:用一款鸿蒙 AI 智能菜谱应用,复盘 DevEco Code / DevEco CLI 的正确打开方式
一键难忘 2026-07-16 16:39:32 金牌共创者
26 评论 分享
AI Coding的风吹到了鸿蒙

AI Coding 能“真干活”还是“真整活”?用一款鸿蒙 AI 智能菜谱应用,复盘 DevEco Code / DevEco CLI 的正确打开方式

【共创季稿事节】HarmonyOS 6.1 让大模型帮你想「今天吃什么」:一款鸿蒙 AI 智能菜谱应用的结构化输出实战(AI Coding 复盘篇)

HarmonyOS 7.0 在 HDC 2026 正式发布后,DevEco Code 与 DevEco CLI 把一个问题摆到了每位鸿蒙开发者面前:AI Coding 究竟是能交付代码的生产力,还是会把项目带偏的“整活机”?

我没有用“让 AI 一句话生成一个 App”来回答它,而是选取一个已经完整跑通的 HarmonyOS 6.1 项目——AI 智能菜谱——做了一次开发链路复盘。结论先说:在需求澄清、重复性 UI、类型脚手架、错误定位、文档检索这几类边界清晰的任务上,AI Coding 已经能真干活;在产品取舍、数据契约、架构边界、最终验收上,开发者仍必须是第一责任人。

本文聚焦项目的真实工程结构和 ArkTS 约束,讨论怎样把 DevEco Code 的 Build / Plan / UI 意图验证思路,以及 DevEco CLI 面向 Agent 的“文档—构建—诊断”工作流,落到一个可维护的鸿蒙 AI 应用里。文中不会把 AI 描绘成魔法:没有经过设备或命令验证的能力会明确标为“建议验证项”,命令以实际安装版本的帮助信息为准。 在这里插入图片描述

一、为什么拿“今天吃什么”来检验 AI Coding

“今天吃什么”看似是轻需求,实际上恰好覆盖了 AI 应用开发最典型的一组难题:

  • 用户输入是开放的:冰箱里有什么、几个人吃、是否忌口、想快一点还是想吃得健康;
  • 模型输出天然不稳定:它可能返回散文式菜谱,也可能夹带 Markdown 代码块,甚至漏字段;
  • App 需要确定性:页面不能因为一个字段缺失而白屏,采购清单、收藏和步骤展示都依赖明确的数据模型;
  • 鸿蒙端侧有工程约束:ArkTS 对类型和状态更新更严格,网络、存储、页面状态不能靠“差不多能跑”处理。

这正是检验 AI Coding 是否“真干活”的好场景。它不是只生成一个静态页面,而是要经历完整链路:需求拆解 → 项目分层 → ArkTS 编码 → 模型接入 → JSON 解析 → UI 展示 → 构建诊断 → 模拟器验证

项目最终实现的能力如下: 在这里插入图片描述

页面 用户价值 对 AI Coding 的检验点
做菜 标签式录入食材、人数和口味,生成 2~3 道菜 表单状态、异步加载、请求体建模
菜谱 展示难度、时长、已有/待购食材、步骤 结构化模型到原生组件的映射
收藏 保存喜欢的菜谱并可回看 Preferences 持久化、列表状态
我的 保存口味/忌口与服务配置 设置页表单、配置边界

项目并不把大模型返回的一段话直接塞进 Text。真正的核心是让模型返回一份可被程序消费的契约:

{
  "recipes": [
    {
      "name": "番茄炒蛋",
      "desc": "酸甜开胃的家常快手菜",
      "difficulty": "简单",
      "minutes": 10,
      "tags": ["快手", "下饭"],
      "ingredients": [
        { "name": "鸡蛋", "amount": "3个", "have": true },
        { "name": "番茄", "amount": "2个", "have": true },
        { "name": "葱", "amount": "少许", "have": false }
      ],
      "steps": ["鸡蛋打散炒熟盛出", "番茄炒出汁", "倒回鸡蛋翻炒调味"],
      "shopping": ["葱"]
    }
  ]
}

这份 JSON 就是菜谱应用的“中间语言”。它既是模型生成的目标,也是 UI 渲染、收藏持久化、采购清单计算的共同输入。如果这个契约没有定义好,AI 再会写页面,也只能生成看起来像应用的演示品。

二、先回答圆桌问题:AI 在这里到底做对了什么,又做错了什么

在开始代码前,先给出这次复盘中最重要的一张表。它也是我认为使用 DevEco Code 或接入 DevEco CLI 的 Agent 时,最值得建立的工作边界。

工作类型 AI 适合程度 原因 人必须把关的点
根据明确描述生成 ArkUI 卡片 组件层次、字体、间距、颜色是可描述、可对照的 小屏溢出、无障碍、真实交互手感
生成 interface、请求体与基础 Service 重复、规则明确,能减少样板代码 字段语义、空值策略、密钥隔离
根据编译报错给出修改建议 报错信息与代码上下文具备较强确定性 不要接受“为了通过编译而删类型/关规则”
搜索 ArkTS/ArkUI 文档与 API 用法 从“找资料”变成“带上下文定位资料” API 版本、权限与设备能力仍要核对
从一句产品想法生成完整应用 中低 需求缺少边界,模型会自行补全大量假设 信息架构、数据流、异常分支往往失真
设计大模型结构化 Schema AI 能给备选,但业务语义来自产品决策 版本演进、字段所有权、契约兼容性
自动验证 UI 意图 中高 能快速发现明显错位和遗漏 不能替代真实设备、网络失败等场景测试
自动修复构建/运行错误 小范围错误有效,大范围“连锁修复”风险高 每次改动必须可审查、可回滚、可构建

因此,我更愿意把 AI Coding 看作一个能读上下文、能执行局部任务、能调用工具的初级工程搭档,而不是一个“把需求扔进去就能下班”的虚拟团队。

对鸿蒙开发而言,这个判断尤其重要。ArkTS 的严格类型、ArkUI 的声明式状态、HarmonyOS SDK 的版本与系统能力约束,会立刻放大“看似合理、实际不成立”的生成结果。AI 最有价值的地方,不是取代开发者思考,而是把开发者从机械的检索、样板编写和第一轮排错中释放出来。

在这里插入图片描述

三、从需求到 Plan:不要让 AI 从模糊的一句话开始写代码

最容易失败的提示词是:

帮我做一个鸿蒙 AI 菜谱 App,要好看,接大模型。

它包含了太多未定义项:几页?数据长什么样?模型失败怎么办?“好看”是暖色、极简还是拟物?是否需要收藏?密钥在哪里?结果页怎么跳转?AI 若直接开始生成,通常会得到一个 UI 很满、数据流却很虚的单页 Demo。

更可靠的做法,是先用 DevEco Code 的 Plan 思路(先规划再落地)把任务写成可验收的工程计划。对这个项目,我会把输入收敛成下面这样:

目标:开发 HarmonyOS 6.1 ArkTS 菜谱应用。

业务流程:用户输入现有食材、用餐人数和可选忌口;服务返回 2~3 道菜;
每道菜展示菜名、简介、难度、耗时、标签、食材(已有/待购)、步骤、采购清单;
支持收藏和偏好持久化。

工程约束:
1. 页面不得直接发网络请求,模型交互统一收敛到 model/RecipeAI.ets;
2. 所有网络请求体与模型数据必须有显式 ArkTS interface;
3. 大模型输出以 recipes 为根字段的 JSON;解析失败不能崩溃,返回中文错误;
4. 适配 phone、tablet、2in1;
5. 正式发布不在客户端保存真实 API Key。

请先输出:目录结构、数据模型、状态流、异常分支、验收清单;
不要直接给完整页面代码。

一个合格的 Plan,至少应包含五件事。

3.1 明确模块边界

最终工程按职责拆分:

entry/src/main/ets/
├── entryability/EntryAbility.ets     应用生命周期与窗口初始化
├── common/
│   ├── Theme.ets                     色彩、圆角、间距等设计令牌
│   ├── AIConfig.ets                  模型端点与系统提示词
│   └── RecipeCard.ets                可复用菜谱卡片
├── model/
│   ├── Recipe.ets                    Recipe / Ingredient 与本地存储
│   ├── RecipeAI.ets                  请求、响应抽取、JSON 容错解析
│   └── RecipeSession.ets             跨 Tab 的当前菜谱状态
└── pages/
    ├── Index.ets                     四 Tab 主壳
    ├── CookTab.ets                   食材输入与生成
    ├── DetailPage.ets                详情与采购清单
    ├── FavTab.ets                    收藏
    └── ProfileTab.ets                偏好和配置

这里的关键不是目录“看起来专业”,而是网络、数据和 UI 不互相越界。让 AI 生成代码时,也应一次只授权它处理一个边界明确的文件或组件。比如先让它只产出 RecipeIngredient 类型,再生成 RecipeCard;不要让它一次改十个文件后再祈祷能编过。

3.2 明确状态流

菜谱生成页的状态可以画成非常朴素的一条线:

用户编辑食材 / 人数 / 偏好
            ↓
点击生成 → loading=true → RecipeAI.generate(...)
            ↓
  成功:results=recipes,更新页面与会话态
  失败:toast(error),保留原输入
            ↓
loading=false

这类状态机特别适合让 AI 辅助检查遗漏。例如可以要求它只做一件事:

审查 onGenerate 的状态转换,列出重复点击、请求失败、空食材、解析为空四种情况下是否有可见反馈;不改代码,只给问题清单。

相比“帮我优化代码”,这个指令有清晰输入和验收标准。AI 的回答也更容易被审查。

3.3 先写验收,而不是只写功能

本项目的最低验收项是:

  • 至少一个食材才能发起生成;
  • 请求期间按钮禁用并给出加载态;
  • HTTP 非 200、超时、JSON 无法解析都能看见中文提示;
  • ingredients 中的 have 决定 UI 的已有/待购标记;
  • 收藏重启应用后仍存在;
  • 手机与 2in1 尺寸下不会因固定宽度挤压;
  • 构建通过,且不以关闭 ArkTS 规则来换取通过。

AI Coding 的提效,应该体现在它能围绕这些验收项生成、检查与修复,而不是“它写了多少行”。

四、Build 模式最值得做的事:生成可审查的 ArkTS 样板,而不是整页盲生成

4.1 先让 AI 帮忙建立类型契约

在 ArkTS 中,类型不是锦上添花,而是让异步服务和 UI 可以稳定协作的基础。菜谱数据模型可以先固定为:

export interface Ingredient {
  name: string;
  amount: string;
  have: boolean;
}

export interface Recipe {
  name: string;
  desc: string;
  difficulty: string;
  minutes: number;
  tags: string[];
  ingredients: Ingredient[];
  steps: string[];
  shopping: string[];
}

export interface RecipeResult {
  ok: boolean;
  recipes: Recipe[];
  error: string;
}

这一段很适合通过自然语言让 AI 生成初稿,但我会额外追问两轮:

  1. minutes 不是数字、ingredients 缺失、shoppingnull 时怎么办?
  2. 这些类型是否足以支持“收藏”“详情”“采购清单”三个页面?

前者是在设计不可信模型输出的容错边界,后者是在验证页面需求是否反向影响 Schema。这两件事都不该由 AI 默默替你做决定。

4.2 让 AI 写“局部组件”,并给出视觉约束

菜谱首页采用暖橙色设计,但“做一个好看的页面”依然太模糊。更可操作的 UI 描述应包含结构和状态:

生成 CookTab 中“已有食材”卡片:
- 卡片内先显示标题;
- 已添加食材是可删除的圆角标签,主色为暖橙;
- 下方是 TextInput 和“添加”按钮;
- 再提供一组可换行的快捷食材;
- 使用 Theme.ets 的颜色和圆角常量,不要新建散落的魔法颜色;
- 所有点击回调只调用已有的 addIng/removeIng,不要写网络逻辑。

这样的任务,AI 生成结果通常具有很高可用性,因为组件层级、样式变量和回调入口都已确定。生成后再由开发者做三项检查:

  • 标签数组增删是否真正触发刷新;
  • 长食材名与小尺寸窗口是否溢出;
  • 是否出现了未定义、过时或不符合项目 SDK 的 ArkUI API。

实际实现里,食材数组增删的重点是不可变更新:

addIng(): void {
  const value = this.input.trim();
  if (value === '') {
    return;
  }
  if (!this.ingredients.includes(value)) {
    this.ingredients.push(value);
    this.ingredients = this.ingredients.slice();
  }
  this.input = '';
}

removeIng(ingredient: string): void {
  this.ingredients = this.ingredients.filter((item: string) => item !== ingredient);
}

这也是一次很典型的“AI 生成后必须人工看懂”的例子。若工具只给出 push,页面是否刷新取决于具体状态机制;如果改成 slice()filter(),意图就更清晰,回归风险也更低。

4.3 异步逻辑不要“聪明化”

生成菜谱按钮背后的代码并不复杂,但它承载了用户对 App 是否可靠的第一印象:

async onGenerate(): Promise<void> {
  if (this.ingredients.length === 0) {
    promptAction.showToast({ message: '请先添加至少一种食材', duration: 1500 });
    return;
  }

  this.loading = true;
  this.results = [];
  const result: RecipeResult = await RecipeAI.generate(
    this.ingredients,
    this.servings,
    this.pref
  );
  this.loading = false;

  if (!result.ok) {
    promptAction.showToast({ message: result.error, duration: 2000 });
    return;
  }

  this.results = result.recipes;
  RecipeSession.setResults(result.recipes);
}

AI 很擅长生成这样的样板,也很适合在这里做 code review:是否有遗漏的 loading=false?是否允许重复点击?失败时是否清空了用户输入?但要警惕一种常见“整活”:为了让代码短一点,AI 把错误吞掉、把 catch 留空,或把异常直接 JSON.stringify 到用户界面。短不等于稳。

五、真正的难点不在“调用模型”,而在“把不确定的输出装进确定的容器”

5.1 用提示词把模型输出变成数据契约

对于菜谱应用,大模型不能只回答“可以做番茄炒蛋”。系统提示词必须告诉它:你输出的不是文章,而是一份待渲染的数据。

static readonly systemPrompt: string =
  '你是一位专业的家常菜大厨兼营养师。用户会告诉你现有的食材和偏好,' +
  '你需要基于这些食材推荐 2 到 3 道菜,尽量充分利用已有食材。' +
  '必须严格只输出 JSON,不要输出任何多余文字、解释或 markdown 代码块标记。' +
  'JSON 格式如下:' +
  '{"recipes":[{' +
  '"name":"菜名",' +
  '"desc":"一句话简介",' +
  '"difficulty":"简单|中等|困难",' +
  '"minutes":预计分钟数(整数),' +
  '"tags":["标签1","标签2"],' +
  '"ingredients":[{"name":"用料名","amount":"用量","have":true或false}],' +
  '"steps":["步骤1","步骤2"],' +
  '"shopping":["需要额外购买的食材1","食材2"]' +
  '}]}' +
  '其中 have 字段:用户已有的食材标 true,需要额外买的标 false;' +
  'shopping 列出所有 have 为 false 的食材。';

这段提示词的价值有三层:

  1. 完整骨架:把字段、嵌套和类型明确写出,降低模型自由发挥的空间;
  2. 业务语义前置haveshopping 不只是展示字段,它们直接服务“我有什么、我还缺什么”的决策;
  3. 限制输出边界:禁止前后解释和 Markdown 包裹,减少解析成本。

如果让 AI Coding 参与这一步,我会让它做“批评者”而不是“作者”:

请评审下面 Schema 是否支持 2~3 道菜、已有/待购食材、采购去重和详情展示。只列出字段缺失、歧义和兼容性风险,不能自行改变业务含义。

这样可以获得第二视角,但 Schema 的最终版本依旧由人拍板。

5.2 提示词强约束不等于可信输入

即使明确要求 JSON,模型仍可能返回:

当然可以,下面是为你设计的菜谱:
```json
{ ... }

因此需要“提示词约束 + 提取 + 解析 + 默认值”四层防线。核心服务 `RecipeAI` 先从 OpenAI 兼容响应中取出 `message.content`,再截取第一个 `{` 与最后一个 `}` 之间的内容:

```typescript
private static parseRecipes(content: string): Recipe[] {
  let text = content.trim();
  const start = text.indexOf('{');
  const end = text.lastIndexOf('}');
  if (start >= 0 && end > start) {
    text = text.substring(start, end + 1);
  }

  try {
    const object = JSON.parse(text) as Record<string, Object>;
    const recipes = object['recipes'] as Object[];
    if (recipes === undefined) {
      return [];
    }
    const result: Recipe[] = [];
    for (const item of recipes) {
      result.push(RecipeAI.toRecipe(item as Record<string, Object>));
    }
    return result;
  } catch (error) {
    return [];
  }
}

而在 toRecipe 中,每个字段都要兜底:

return {
  name: `${raw['name'] ?? '未命名菜品'}`,
  desc: `${raw['desc'] ?? ''}`,
  difficulty: `${raw['difficulty'] ?? '简单'}`,
  minutes: Number(raw['minutes'] ?? 20),
  tags: RecipeAI.toStrArr(raw['tags']),
  ingredients: ingredients,
  steps: RecipeAI.toStrArr(raw['steps']),
  shopping: RecipeAI.toStrArr(raw['shopping'])
};

这里正好说明了“AI 能写什么、人必须决定什么”:工具可以协助生成 extractContentparseRecipes 甚至空值转换样板;但是否允许截取首尾花括号、解析失败给用户什么文案、是否要做 JSON Schema 校验、哪些字段不能缺失,属于应用可靠性设计,不能盲从生成答案。

5.3 不要把密钥和模型选择当成 UI 细节

开发演示阶段,客户端直连兼容接口可以快速验证闭环;正式应用不能把真实密钥硬编码在 AIConfig.ets,更不能提交到公开仓库。正确边界应该是:

HarmonyOS App
  └─ 业务请求(食材、人数、偏好)
       ↓
自有服务端 / 受控网关
  ├─ 鉴权、限流、审计
  ├─ 保存模型密钥
  ├─ 注入系统提示词、版本化 Schema
  └─ 调用大模型并返回受控结果

AI Coding 有时会为了让示例“可直接运行”而把 token 写入常量。这在 demo 阶段很常见,但绝不是可推广的工程实践。使用 DevEco Code 自动生成网络层或使用 DevEco CLI 接入 Agent 时,建议把“不得输出、读取或提交真实密钥”放进工作区规则里。

六、DevEco CLI 的意义:让通用 Agent 真正理解鸿蒙工程,而不是只会猜

DevEco Code 面向开发者的即时协作,而 DevEco CLI 的价值更像是把 HarmonyOS 开发能力暴露给已有 AI Agent:它知道怎样初始化、怎样检索文档、怎样执行构建和怎样把诊断回传给 Agent。对习惯在终端、编辑器或自建工作流中使用 AI 的开发者来说,这解决的是“通用模型不懂鸿蒙上下文”的问题。

但这里有一个重要前提:CLI 的具体命令、参数、可用工具会随版本演进,应该以本机 --help 和官方仓库说明为准。 不要从一篇文章复制未经本机验证的命令后就把失败归因给工具。

6.1 推荐的 Agent 工作闭环

对智能菜谱项目,更可靠的闭环不是“Agent 自己写完自己说成功”,而是:

读取工程结构
  ↓
用本地/官方文档确认 ArkTS、ArkUI、NetworkKit 的 API 与 SDK 版本
  ↓
仅修改一个目标模块
  ↓
运行 ArkTS 静态诊断或 IDE 检查
  ↓
执行 Hvigor 构建
  ↓
把真实报错、相关代码和最小修改一起交给 Agent 分析
  ↓
人工审查 diff,再进入下一轮

这就是 DevEco CLI 最值得融入 Agent 的位置:提供可验证的工具结果,而不是让模型凭训练记忆编造 API。

在本项目里,可以把任务拆成如下粒度:

任务 A:只为 RecipeAI.ets 定义 ChatRequest、ChatMessage、RecipeResult 类型。
任务 B:只实现 OpenAI 兼容响应的 content 提取,不能修改页面。
任务 C:根据当前项目 SDK 查证 NetworkKit HTTP 请求超时的正确配置。
任务 D:运行构建并解释第一个 ArkTS 编译错误,给出最小改动补丁。
任务 E:在模拟器验证“空食材、生成中、成功、网络失败”四种 UI 状态。

每个任务都有明确的输入、输出和停止条件。这是让 Agent “真干活”的方法论:不是赋予它无限权限,而是提供有限上下文、明确边界和硬验证

6.2 文档检索比“模型记得”可靠

HarmonyOS API、SDK、ArkTS 检查规则都在持续更新。比如 Preferences 的方法参数、某些上下文获取方式、资源或页面配置的写法,都可能因 API 版本变化出现差异。通用大模型即使给出一段看上去合理的代码,也可能是旧版本用法。

因此,我会优先把问题问成可检索的形式:

当前工程 targetSdkVersion 为 X。
请从 HarmonyOS 本地/官方文档中查找 NetworkKit http.createHttp 的 request 参数定义,
确认 connectTimeout 与 readTimeout 的类型、单位和适用范围;输出文档来源与最小示例。

这比“帮我写一个 HTTP 请求”多了三道保险:限定版本、要求来源、要求最小示例。DevEco CLI 若能把这类文档检索能力提供给 Agent,就能显著减少鸿蒙项目中“语法像对、版本不对”的无效来回。

6.3 构建错误是 Agent 最有价值的输入,不是噪声

当构建失败时,最差的做法是把整段错误丢给 AI 并说“修一下”。更好的做法是提供:

  • 完整的首个错误信息;
  • 对应文件的几十行上下文;
  • 当前 SDK / targetSdkVersion;
  • 该文件最近一次变更;
  • 期望保持不变的业务行为。

例如:

编译器提示 arkts-no-untyped-obj-literals。
文件:RecipeAI.ets。
约束:保持请求 JSON 字段不变,不能使用 any,补齐最小 interface。
请只输出需要新增的类型和替换片段,并说明为什么。

这类问题的修复质量通常很高。因为 AI 不需要猜产品,而是在一个清晰的语法和类型问题上工作。反过来,如果 Agent 为了消除错误建议使用 any、关闭检查或删除字段,应该直接拒绝。

七、UI 意图验证:它能替你发现什么,不能替你证明什么

DevEco Code 提到 UI 意图验证,这是我最期待的能力之一。对声明式 UI 来说,代码结构正确不等于页面正确:一行 layoutWeight、一个错误的 width('100%')、一个被遗忘的安全区,都可能让手机和 PC 的视觉结果差很多。

以菜谱 App 为例,适合定义成“可观察的 UI 意图”:

场景 应观察到的结果
初始进入做菜页 至少展示默认食材、人数控件、生成按钮
添加“豆腐” 新标签出现一次,输入框清空,重复添加不产生重复标签
空食材点击生成 显示提示,不发请求,不进入 loading
生成中 按钮文本变化且不可重复点击
生成成功 出现 2~3 张菜谱卡片,每张有名称、耗时、缺少食材提示
小窗口/手机尺寸 食材标签和快捷标签自动换行,底部 Tab 不遮挡内容
失败响应 保留食材输入,展示可理解的失败提示

若工具可以调起模拟器并检查截图/组件树,这些场景能够成为非常高效的回归测试入口。它尤其适合发现:页面没有加载、组件被遮挡、按钮文案未变、条件渲染未触发、卡片结构缺失等“第一眼就能发现”的问题。

但也必须明确它的边界:

  1. UI 意图验证不是可用性研究。 它看不出用户是否理解“已有/待购”的图标语义;
  2. 不是性能结论。 首屏看起来正常,不代表滚动、网络慢、连续点击时没有卡顿;
  3. 不是设备能力证明。 模拟器能跑,不代表所有真机型号、系统版本、网络环境都一致;
  4. 不是安全审计。 截图正常,不代表密钥、日志和网络链路安全。

所以最合理的定位是:把 UI 意图验证放在“开发中的快速反馈层”,而不是取代模拟器、云调试、真机和人工体验验收。

八、一次真实项目复盘:哪些环节让我觉得 AI Coding 值回票价

8.1 从“查资料”到“带上下文提问”

以前遇到 ArkTS 或 ArkUI 问题,常见路径是搜索关键词、打开多篇文档、在不同 API 版本之间比对,再回到代码试错。DevEco Code / CLI 这类工具的价值,是把问题和工程上下文同时带进去。

比如不是问“ArkTS 数组为什么不刷新”,而是问:

CookTab@State ingredients: string[],点击添加后使用 push。请解释在当前状态管理模式下 UI 刷新是否可靠,并给出不改变业务的最小更新写法。

这个问题会自然引导工具回答“数组引用变化”和 slice() 的必要性,而不是泛泛讲 TypeScript 数组。

8.2 从“写一大坨页面”到“生成可复用单元”

RecipeCard 同时服务推荐结果和收藏列表,是非常适合 AI 辅助生成的组件。输入应包含清晰的 props:

RecipeCard 输入 Recipe;展示菜名、简介、难度、分钟数、两个标签;
如果 shopping 非空,显示“缺 N 样食材”;点击执行 onTap(recipe)。
不得直接读 AppStorage、不得导航、不得发请求。

这样得到的是一个低耦合组件。即使第一次样式不够好看,后续也只是在组件内迭代,不会牵动网络逻辑。AI 在 UI 编写上最值得发挥的地方,正是这种明确输入、明确输出、可局部预览的场景。

8.3 从“猜错误原因”到“围绕证据修复”

大模型最不可靠的时刻,是没有证据还很自信地回答。相反,拿到编译器错误、目标文件和 SDK 信息后,它做诊断的质量会明显上升。

我的原则是:每轮修复只接受一个最小 diff,并在下一轮构建前回答三个问题:

  • 这处修改解决了哪一条错误?
  • 会不会改变原有业务行为?
  • 如果没有解决,怎么回滚?

这种做法看上去慢,但因为避免了“AI 修一个错又引入三个错”,总耗时反而更短。

九、AI Coding 最容易“真整活”的五个地方

既然是体验复盘,也必须把风险写清楚。以下问题不是某一个工具独有,而是当前 Agent 式开发普遍会遇到的。

9.1 把旧 API 当成新 API

鸿蒙 SDK 迭代很快。模型可能记住过往示例,却不知道当前项目的 API Level。症状是:代码语义正确、编译却过不了。解决办法不是让它“再试一个”,而是要求基于当前 SDK 文档重新确认,并把版本号放进提示词。

9.2 为了编译通过而牺牲类型

遇到对象字面量、未知响应、动态字段时,AI 可能给出 any 或粗暴断言。这会把问题从编译期推迟到运行期。菜谱项目中应坚持 ChatRequestRecipeIngredient 等显式接口,并在不可信 JSON 进入 UI 前完成转换。

9.3 忽略“失败也是一种界面状态”

AI 生成 Happy Path 很快,却经常漏掉网络不可用、服务返回 500、模型给出半截 JSON、用户连续点击等场景。对接大模型时,异常路径不是补丁,而是产品体验的一部分。

9.4 把真实密钥写进示例

为了让演示方便,很多代码会把 API Key 放进配置常量。它能跑,但不安全。任何 AI Coding 工作流都应该默认屏蔽密钥、使用环境或服务端网关,并在提交前做敏感信息检查。

9.5 超范围改动

“顺便重构一下”是 Agent 最危险的能力之一。一个本来只需修复类型问题的任务,可能被改成目录重排、组件替换、依赖变化,最后很难确认回归来源。对 AI 的最佳授权方式是:一次一个目标文件、一次一个可验证目的、一次一个最小 diff。

十、给鸿蒙开发者的实操清单:怎样把 AI 变成生产力而不是事故源

开始前

  • 先写清用户流程、页面数量、数据模型和失败分支;
  • 记录 compatibleSdkVersiontargetSdkVersion、设备类型和已有依赖;
  • 把密钥、隐私数据、生产配置从 Agent 可见上下文中隔离;
  • 为每项功能补一条“用户看得见的验收结果”。

使用 DevEco Code / Agent 时

  • 先 Plan,确认目录、数据流与任务拆分,再 Build;
  • 用“文件 + 函数 + 约束 + 验收”描述任务,避免“优化一下”;
  • 让它生成接口、局部组件、测试场景和错误解释,而非一次性接管工程;
  • 对涉及 SDK API 的答案要求文档依据,并核对版本;
  • 每次修改后看 diff,拒绝无关重构。

使用 DevEco CLI 工作流时

  • 先通过本机帮助与官方资料确认当前可用命令;
  • 让 Agent 先检索本地/官方文档,再生成调用代码;
  • 把构建输出、首个错误、文件上下文一起交给 Agent;
  • 修改后必须执行静态诊断与 Hvigor 构建;
  • UI 相关修改要在模拟器或可用设备上做意图验证。

发布前

  • 将真实模型密钥迁移到服务端;
  • 对模型 JSON 做格式、字段、长度和业务合理性校验;
  • 覆盖弱网、超时、非 200、空结果、畸形 JSON;
  • 检查不同窗口尺寸、深浅色/系统字体(如适用)和安全区;
  • 对 AI 生成内容添加食品安全、免责声明与必要的用户提示。

十一、下一步期待:我希望 DevEco Code / DevEco CLI 帮鸿蒙开发者解决什么

如果说今天的 AI Coding 已经能在“写、查、改、验”的局部闭环中真干活,那么我对下一阶段有四个期待。

第一,版本感知的知识检索。 不只回答“这个 API 怎么用”,还应结合工程的 SDK 与目标设备,告诉开发者“这个写法在你当前版本是否可用、需要什么权限、是否有替代方案”。

第二,可审计的自动修复。 自动修复不是一键改完,而是给出错误定位、修改理由、影响范围和可选择的补丁。开发者应能一眼看懂它为什么这么改。

第三,面向多端的 UI 验证。 HarmonyOS 的优势在全场景。工具若能把同一页面在手机、平板、2in1 等不同尺寸下的布局差异自动呈现,并指出溢出、遮挡和点击区域问题,会比单纯生成 UI 更有价值。

第四,AI 应用的契约工具链。 对“模型输出 JSON”这类场景,未来最需要的不是再多一个聊天框,而是从 Schema 定义、提示词版本、服务端校验、模拟响应到端侧模型映射的完整工具链。大模型的创造性必须被工程契约驯服,才能稳定进入生产。

十二、结语:AI 给的是速度,工程给的是确定性

回到开头的问题:AI Coding 在鸿蒙生态里,到底是“真干活”还是“真整活”?

我的答案是:它会放大你的工作流。 如果输入是一句模糊需求、没有数据契约、没有构建验证、没有人工审查,它会更快地产出一堆看似完整的代码,也更快地制造难以定位的 Bug;如果输入是清晰的 Plan、受控的任务边界、真实的工具反馈和严格的验收标准,它就能把开发者从重复劳动中解放出来,真正加速从想法到可运行应用的过程。

在这款 AI 智能菜谱应用中,大模型负责把“冰箱里有鸡蛋、番茄和豆腐”扩展成有创意的菜单;ArkTS 类型、JSON 容错、原生 UI、存储和构建验证,则负责把这份创意变成稳定可用的产品。DevEco Code 和 DevEco CLI 的价值,也正在这条分工线上:让 AI 更懂鸿蒙,让开发者把时间花在真正需要判断力的地方。

大模型带来可能性,AI Coding 带来速度,而工程化验证才带来交付。

参考资料

  1. DevEco Code 开源仓库:https://gitcode.com/openharmony-sig/deveco-code
  2. HarmonyOS 社区:《开发者实践:牛人带你玩转 HarmonyOS AI Coding 提效工具 DevEco Code 和 DevEco CLI》
  3. HarmonyOS Developer 文档与 DevEco Studio / DevEco CLI 本机帮助(具体能力、命令与版本以官方最新说明为准)

本文项目为 HarmonyOS 6.1 ArkTS AI 智能菜谱实践复盘。模型生成内容仅供烹饪灵感参考,实际烹饪请结合食材状态、个人过敏史和食品安全规范判断。

26 评论 分享
写讨论
全部评论(0)