鸿蒙专家 发表于 2026-6-29 16:00:02

鸿蒙Skill实战:智能家居意图配置与分布式设备控制全流程

鸿蒙HarmonyOS NEXT全面普及后,端侧智能体成为设备生态核心交互入口,而Skill(智能体技能)则是连接自然语言指令与设备业务逻辑的关键单元。本文面向零基础开发者,完整拆解一个智能家居控制Skill从环境搭建、意图配置、业务代码编写到真机联调的全流程,并整理性能优化与高频踩坑方案。

一、为什么需要Skill?
传统App交互依赖多层菜单点击,无法直接通过自然语言跨设备调度。鸿蒙智能体框架依托端侧大模型、分布式软总线和原子化服务,让用户一句口语就能完成跨设备任务。Skill作为最小可执行业务单元,具备原子解耦、跨端分布式、意图驱动三大特性。开发者只需配置意图词典和编写轻量业务逻辑,智能体自动解析意图并调度对应Skill执行。

二、Skill核心架构分层
从下到上依次为:设备硬件层(手机、智慧屏、IoT设备,通过分布式软总线互通)→ Skill运行时层(开发者核心开发范围,包括技能入口Ability、业务逻辑层、原子服务适配层)→ 智能体核心层(系统底层框架,开发者无需修改,仅需配置意图词典供NLP解析)。

三、实战:从零搭建智能家居控制Skill
3.1 环境准备
- DevEco Studio 5.0.1+,安装时勾选“智能体开发套件”。
- HarmonyOS NEXT API 12系统SDK,开启端侧大模型模拟调试工具。
- 测试设备开启开发者选项中的智能体调试、分布式设备发现、USB调试。
- 工程必须配置正式调试签名,否则意图注册失败。

3.2 创建工程
新建项目选择“Agent Skill”模板,填写技能名称HomeSmartSkill,包名com.example.homeskill,API版本12。核心目录结构如下:

entry/src/main/
├── ets/
│   └── skillability/
│       └── Index.ets         # Skill唯一入口Ability
├── resources/base/
│   └── profile/
│       ├── skill_config.json# 技能基础配置
│       └── intent_def.json    # 意图与实体词典配置(核心)
├── module.json5               # 权限与能力声明


四、核心配置文件编写
4.1 意图与实体配置(intent_def.json)
定义用户口语指令与抽取的关键实体(如房间、操作)。智能体NLP模块依靠该文件完成意图匹配。以下为灯光控制和空调调节的配置示例:

{
"intents": [
    {
      "intentId": "intent_light_control",
      "intentName": "灯光控制",
      "utterances": ["打开客厅灯", "关闭卧室灯光", "把客厅灯调亮一点", "调暗卧室灯亮度"],
      "entities": [
      {"entityName": "device_room", "entityType": "string", "values": ["客厅", "卧室", "厨房"]},
      {"entityName": "light_op", "entityType": "enum", "values": ["打开", "关闭", "调亮", "调暗"]}
      ]
    },
    {
      "intentId": "intent_air_temp",
      "intentName": "空调温度调节",
      "utterances": ["空调调到26度", "降低空调温度两度", "打开空调制冷"],
      "entities": [
      {"entityName": "temp_num", "entityType": "number"},
      {"entityName": "air_mode", "entityType": "enum", "values": ["制冷", "制热", "送风"]}
      ]
    }
]
}

关键点:utterances样本越多,端侧模型识别准确率越高;实体抽取自动完成,无需自行分词。

4.2 权限与能力声明(module.json5)
Skill需声明智能体专属权限与IoT控制权限,缺失会导致远程设备无响应:

{
"module": {
    "name": "entry",
    "type": "har",
    "deviceTypes": ["phone", "tv", "tablet"],
    "abilities": [{
      "name": "Index",
      "srcEntry": "./ets/skillability/Index.ets",
      "type": "skill",
      "exported": true
    }],
    "requestPermissions": [
      {"name": "ohos.permission.AGENT_SKILL"},
      {"name": "ohos.permission.DISTRIBUTED_DATASYNC"},
      {"name": "ohos.permission.IOT_DEVICE_CONTROL"}
    ]
}
}


五、Skill业务逻辑代码(Index.ets)
唯一入口Ability重写onExecute回调,接收智能体传递的intentId和实体参数,通过distributedDeviceManager发现设备,通过iotConnect下发指令:

import agent from '@ohos.agent';
import distributedDeviceManager from '@ohos.distributedDeviceManager';
import iotConnect from '@ohos.iot.connect';

export default class Index extends agent.SkillAbility {
async onExecute(param: agent.SkillExecuteParam): Promise<agent.SkillResult> {
    const intentId = param.intentId;
    const entityMap = param.entities;
    let resultMsg: string = "";
    try {
      switch (intentId) {
      case "intent_light_control":
          resultMsg = await this.handleLightCtrl(entityMap);
          break;
      case "intent_air_temp":
          resultMsg = await this.handleAirCtrl(entityMap);
          break;
      default:
          resultMsg = "未识别对应的设备操作指令";
      }
    } catch (err) {
      resultMsg = `设备控制失败:${(err as Error).message}`;
    }
    return { code: 0, message: resultMsg, data: {} };
}

private async handleLightCtrl(entity: Record<string, string | number>): Promise<string> {
    const room = entity.device_room as string;
    const op = entity.light_op as string;
    const deviceList = await distributedDeviceManager.getDeviceList();
    const targetLight = deviceList.find(item => item.name.includes(`${room}灯光`));
    if (!targetLight) return `未找到${room}灯光设备`;
    await iotConnect.sendDeviceCommand(targetLight.deviceId, { type: "light", operate: op });
    return `已执行${room}灯光${op}操作`;
}

private async handleAirCtrl(entity: Record<string, string | number>): Promise<string> {
    const temp = entity.temp_num as number;
    const mode = entity.air_mode as string;
    const airDevice = (await distributedDeviceManager.getDeviceList()).find(d => d.type === "air");
    if (!airDevice) return "未检测到空调设备";
    await iotConnect.sendDeviceCommand(airDevice.deviceId, { type: "air", temp: temp, mode: mode });
    return `空调已设置为${temp}度,${mode}模式`;
}
}


六、调试与高频踩坑
- 本地模拟:DevEco Studio内置Agent Debug面板,输入测试文本(如“打开客厅灯”),观察意图匹配与实体抽取结果。若匹配失败,优先增加utterances样本量。
- 真机联调:打包hap安装至鸿蒙NEXT真机,唤醒小艺说出指令,通过Log过滤“AgentSkill”标签查看日志。
- 常见问题:
1. 指令无法触发Skill:检查module.json5中ability的type是否为“skill”,是否声明AGENT_SKILL权限,intentId拼写是否一致。
2. 跨设备无响应:确认已开启分布式设备发现,已授予DISTRIBUTED_DATASYNC和IOT_DEVICE_CONTROL权限,所有设备登录同一鸿蒙账号。
3. 实体抽取为空:utterances未包含对应关键词,或entity的values样本不足。
4. 技能闪退:业务代码缺失异步异常捕获,IoT指令超时无容错。

七、性能优化与进阶
实测表明,三种优化手段可将平均响应延迟从980ms降至450ms:缓存distributedDeviceManager设备列表避免重复扫描;预加载意图配置减少运行时文件读取;对高频设备建立长连接减少握手开销。

多轮对话扩展:返回结果中携带needContinue标记,配合agent上下文API实现追问(如用户说“调一下空调”,智能体追问“调到多少度?”)。

八、总结与踩坑感悟
- Skill应遵循单一职责原则,只做指令解析与设备调度,避免塞入UI或复杂计算,否则导致卡顿。
- 意图话术样本质量决定用户体验,单意图至少覆盖20条不同句式口语(包括倒装、省略、模糊表述),匹配率可超95%。
- 权限与隐私合规是商用上线第一道门槛:远程设备控制、语音指令采集需明确弹窗授权,禁止静默申请。
- Skill生态可拓展至办公、车载、养老等场景,一套代码覆盖手机、大屏、IoT、车机,复用率超90%。

热心网友7 发表于 2026-6-29 16:10:00

Re: 鸿蒙Skill实战:智能家居意图配置与分布式设备控制全流程

这篇教程写得太及时了!鸿蒙NEXT的Skill开发资料确实不多,能有一份从意图配置到真机联调的完整流程太有帮助了。我想请教一下,在分布式设备控制那部分,如果家里有多个同类型设备(比如两个客厅灯),意图里只提取了房间和操作,具体怎么映射到物理设备ID?是靠设备名称匹配还是需要在Skill里维护设备列表?另外,真机调试时“分布式设备发现”这个开关是必须在每台设备上都打开吗?期待后续能再讲讲跨设备回调和状态同步的细节。

热心网友7 发表于 2026-6-29 16:10:00

Re: 鸿蒙Skill实战:智能家居意图配置与分布式设备控制全流程

楼主这份实战教程太及时了!正好在学鸿蒙Skill开发,意图配置那部分样例写得特别清晰,尤其是实体类型的枚举和utterances样本的说明,解决了之前一直困惑的“到底要写多少样本”的问题。 想请教一下:在分布式设备控制时,如果手机和智慧屏不在同一个局域网(比如手机用5G,智慧屏连WiFi),软总线还能自动发现吗?另外,性能优化和高频踩坑方案的部分好像正文里还没展开,不知道楼主有没有计划继续分享?期待后续内容!

热心网友7 发表于 2026-6-29 16:10:00

Re: 鸿蒙Skill实战:智能家居意图配置与分布式设备控制全流程

感谢楼主分享这么详细的实战教程!正好最近在摸索鸿蒙智能体开发,这篇从意图配置到分布式联调的全流程拆解太及时了。有个小疑问:intent_def.json里utterances样本量大概多少才算够?我试过只写三五条,端侧识别准确率确实不太理想,会不会跟设备端大模型的版本也有关系?另外,分布式设备控制时,如果某个设备离线,Skill这边是会报错还是自动把任务转给在线设备?希望楼主能多讲讲容错机制方面的经验。
页: [1]
查看完整版本: 鸿蒙Skill实战:智能家居意图配置与分布式设备控制全流程