【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建 原创

GeorgeGcs
发布于 2025-9-3 00:05
浏览
1收藏

【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建

最近在做HarmonyOS AI应用开发,感觉鸿蒙以后和AI会越来越紧密。AI和鸿蒙两个热门方向,居然融合在一起了。感慨颇多。
【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建-鸿蒙开发者社区

智能体功能听着很高大上。目前用户能在App里直接调用小艺生态下的智能体,在小艺开放平台,任何人都可以创建智能体上架。所以我们需要给应用集成智能体功能入口。

而提供的Agent Framework Kit是核心工具,实现了应用内激活小艺智能体的效果。

从入门到跑通流程踩了些小坑,索性整理成一篇实战笔记,希望能帮到同样在做智能体集成的开发者。

一、先搞懂:Agent Framework Kit到底是干啥的?

刚开始接触这个Kit的时候,我还以为是个复杂的框架,实际用下来发现定位很清晰。

它就是帮你在HarmonyOS应用里拉起指定智能体的工具包。

核心价值其实就一点:你先在小艺开放平台把自己的智能体上线,然后通过Agent Framework Kit,就能让用户在你的App里,通过Kit提供的UI控件主动打开这个智能体。简单说,它解决了“应用怎么和智能体对接”的核心问题,不用自己从零搭一套交互入口。

这个Kit里最核心的东西就是Function组件

所有和智能体拉起相关的操作,基本都围绕这个组件展开。后续的开发实战,也都是基于这个组件来做的。

二、Function组件:智能体入口的两种形态

Function组件是Agent Framework Kit的“门面”,用户就是通过它触发智能体拉起的。

这里有个小细节我刚开始没注意:它会根据你是否设置“标题”,自动切换成两种形态,用途不太一样。

第一种是图标组件

当你不设置title的时候,组件会默认显示成图标样式。这种适合做“综合型入口”。比如App首页的智能体入口按钮,不带具体的用户意图,点进去就是智能体的主界面。我在项目里把它放在了个人中心的工具栏,作为智能体的总入口,用户一眼就能找到。

【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建-鸿蒙开发者社区

第二种是按钮组件
只要你设置了title,组件就会变成按钮样式,还能自定义功能描述。这种更适合场景化入口。

比如在创建任务页面,我把按钮标题设为“智能生成任务”,queryText设为“帮我生成本周的工作计划”,用户点这个按钮,拉起智能体就直接带了明确的意图,体验更顺畅。
【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建-鸿蒙开发者社区

三、开发前必看:那些容易踩坑的限制条件

在动手写代码前,一定要先确认环境是否符合要求。

我刚开始用模拟器测了半天没反应,后来才发现是踩了限制的坑,白浪费时间。

设备限制:目前只支持手机(Phone)和平板(Tablet),其他设备比如手表、车机暂时不兼容,开发和测试必须用真实设备,模拟器跑不起来。
地区限制:仅限中国境内使用,香港、澳门、台湾地区暂时用不了,如果你做的是面向这些地区的应用,可能得等后续更新。
账号准备:设备必须登录华为账号,而且要联网,智能体需要和小艺开放平台交互,没登录的话会直接报错,这点要在App里加个引导提示。

另外,别忘了先在小艺开放平台把你的智能体创建并上线,拿到唯一的agentId。这是后续开发的关键,没有它组件根本拉不起智能体。

四、实战:用Function组件拉起智能体的完整流程

接下来就是最核心的开发步骤了,我按自己项目里的实现过程来写,代码里会标上关键注释,直接复制改改就能用。

1. 第一步:引入必要的依赖包

首先找到项目根目录下的/src/main/ets/pages/Index.ets文件(如果你的入口页面不是Index.ets,就找对应的页面文件),把需要的类引进来。这里要注意包名别写错,尤其是AgentFrameworkKit的路径:

// 引入Agent Framework Kit核心组件和控制器
import { FunctionComponent, FunctionController } from '@kit.AgentFrameworkKit';
// 处理业务错误
import { BusinessError } from "@kit.BasicServicesKit";
// 日志打印(方便调试)
import { hilog } from "@kit.PerformanceAnalysisKit";
// 后面判断Agent可用性会用到UIAbilityContext
import { common } from '@kit.ArkUI';

2. 第二步:构建基础页面与Function组件

接下来在页面中创建FunctionComponent,这里有两个必填参数绝对不能漏:agentId(你在小艺开放平台拿到的智能体ID)和onError(错误回调,不然出问题没法定位)。

我先写了个最基础的示例,组件会默认显示成图标样式(因为没设title):

@Entry
@Component
export struct AgentDemoPage {
  // 初始化Function控制器,用来后续监听事件、判断可用性
  private agentController: FunctionController = new FunctionController();
  // 替换成你自己的agentId!替换成你自己的agentId!替换成你自己的agentId!
  private myAgentId: string = 'agentproxy65481da1fa2293a8482d45';

  build() {
    // 用Column布局把组件放在页面中间
    Column({ space: 20, alignItems: ItemAlign.Center }) {
      Text('我的智能体入口')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      // 核心的Function组件
      FunctionComponent({
        agentId: this.myAgentId, // 必填:智能体唯一标识
        onError: (err: BusinessError) => { // 必填:错误回调
          // 打印错误信息,方便调试
          hilog.error(0x0001, 'AgentDemo', `智能体拉起失败:${err.code} - ${err.message}`);
          // 这里可以加用户提示,比如Toast.showToast
        },
        controller: this.agentController, // 绑定控制器
        options: {
          // 这里没设title,组件会显示成图标样式
          queryText: '' // 可选:默认的用户意图,空的话就是智能体主入口
        }
      })
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

3. 优化:先判断Agent是否可用,再加载组件

上面的基础版有个问题:如果agentId无效,或者设备不支持智能体功能,组件会加载失败但用户看不到提示。我后来加了个判断逻辑。

页面加载前先检查当前agentId是否可用,可用再渲染组件,体验更友好。

在刚才的代码里加这段逻辑:

@Entry
@Component
export struct AgentDemoPage {
  private agentController: FunctionController = new FunctionController();
  private myAgentId: string = 'agentproxy65481da1fa2293a8482d45';
  // 新增:标记当前agent是否可用
  @State isAgentAvailable: boolean = false;

  // 页面即将显示时,检查Agent可用性
  aboutToAppear() {
    this.checkAgentSupport();
  }

  // 异步检查Agent是否可用
  async checkAgentSupport() {
    try {
      // 获取UIAbility上下文,用于检查
      const context = this.getUIContext()?.getHostContext() as common.UIAbilityContext;
      // 调用控制器的isAgentSupport方法,传入上下文和agentId
      this.isAgentAvailable = await this.agentController.isAgentSupport(context, this.myAgentId);
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(0x0001, 'AgentDemo', `检查Agent可用性失败:${error.code} - ${error.message}`);
      this.isAgentAvailable = false;
    }
  }

  build() {
    Column({ space: 20, alignItems: ItemAlign.Center }) {
      Text('我的智能体入口')
        .fontSize(20)
        .fontWeight(FontWeight.Bold)

      // 只有Agent可用时,才渲染组件
      if (this.isAgentAvailable) {
        FunctionComponent({
          agentId: this.myAgentId,
          onError: (err: BusinessError) => {
            hilog.error(0x0001, 'AgentDemo', `智能体拉起失败:${err.code} - ${err.message}`);
          },
          controller: this.agentController,
          options: {
            title: '智能生成任务', // 这里设了title,组件会显示成按钮样式
            queryText: '帮我生成本周的工作计划', // 带明确意图
            isShowShadow: true // 可选:给按钮加阴影,视觉效果更好
          }
        })
      } else {
        // Agent不可用时,显示提示
        Text('当前设备不支持智能体功能,请检查设备或账号状态')
          .fontSize(14)
          .fontColor('#ff4444')
      }
    }
    .width('100%')
    .height('100%')
    .padding(20)
  }
}

4. 进阶:监听智能体对话框的状态

有时候需要知道用户什么时候打开/关闭了智能体对话框,比如统计使用次数,或者在对话框关闭后刷新页面数据。这时候可以给控制器加监听事件,注意在页面销毁时移除监听,避免内存泄漏。

继续完善代码,加入监听逻辑:

@Entry
@Component
export struct AgentDemoPage {
  private agentController: FunctionController = new FunctionController();
  private myAgentId: string = 'agentproxy65481da1fa2293a8482d45';
  @State isAgentAvailable: boolean = false;

  aboutToAppear() {
    this.checkAgentSupport();
    // 页面显示时,初始化监听
    this.initAgentListeners();
  }

  aboutToDisappear() {
    // 页面销毁时,移除监听,避免内存泄漏
    this.removeAgentListeners();
  }

  async checkAgentSupport() {
    // (同上,省略重复代码)
  }

  // 初始化监听:对话框打开和关闭事件
  initAgentListeners() {
    // 监听对话框打开
    this.agentController?.on('agentDialogOpened', () => {
      hilog.info(0x0001, 'AgentDemo', '用户打开了智能体对话框');
      // 这里可以加业务逻辑,比如记录用户行为
    });

    // 监听对话框关闭
    this.agentController?.on('agentDialogClosed', () => {
      hilog.info(0x0001, 'AgentDemo', '用户关闭了智能体对话框');
      // 比如对话框关闭后,刷新页面数据
      // this.refreshPageData();
    });
  }

  // 移除监听
  removeAgentListeners() {
    this.agentController?.off('agentDialogOpened');
    this.agentController?.off('agentDialogClosed');
  }

  build() {
    // (同上,省略重复代码)
  }
}

5. DEMO源码

最后,我把上面的逻辑整合了一份完整代码,大家复制过去,替换掉myAgentId,用真实手机(登录华为账号、联网)就能跑通:

import { FunctionComponent, FunctionController } from '@kit.AgentFrameworkKit';
import { BusinessError } from "@kit.BasicServicesKit";
import { hilog } from "@kit.PerformanceAnalysisKit";
import { common } from '@kit.ArkUI';
import { Column, Text, ItemAlign } from '@kit.ArkUI';

@Entry
@Component
export struct AgentFunctionDemo {
  // 1. 初始化控制器和agentId(替换成你的真实agentId)
  private agentController: FunctionController = new FunctionController();
  private myAgentId: string = 'agentproxy65481da1fa2293a8482d45'; // 替换这里!
  // 2. 标记Agent是否可用
  @State isAgentAvailable: boolean = false;

  // 3. 页面加载前:检查Agent可用性 + 初始化监听
  aboutToAppear() {
    this.checkAgentSupport();
    this.initAgentListeners();
  }

  // 4. 页面销毁:移除监听
  aboutToDisappear() {
    this.removeAgentListeners();
  }

  // 5. 检查Agent是否可用
  async checkAgentSupport() {
    try {
      const context = this.getUIContext()?.getHostContext() as common.UIAbilityContext;
      this.isAgentAvailable = await this.agentController.isAgentSupport(context, this.myAgentId);
    } catch (err) {
      const error = err as BusinessError;
      hilog.error(0x0001, 'AgentDemo', `检查失败:${error.code} - ${error.message}`);
      this.isAgentAvailable = false;
    }
  }

  // 6. 监听对话框状态
  initAgentListeners() {
    this.agentController?.on('agentDialogOpened', () => {
      hilog.info(0x0001, 'AgentDemo', '智能体对话框已打开');
      // 可添加:记录用户行为、切换页面状态等逻辑
    });

    this.agentController?.on('agentDialogClosed', () => {
      hilog.info(0x0001, 'AgentDemo', '智能体对话框已关闭');
      // 可添加:刷新数据、弹窗提示等逻辑
    });
  }

  // 7. 移除监听
  removeAgentListeners() {
    this.agentController?.off('agentDialogOpened');
    this.agentController?.off('agentDialogClosed');
  }

  // 8. 页面渲染
  build() {
    Column({ space: 24, alignItems: ItemAlign.Center }) {
      Text('HarmonyOS智能体入口示例')
        .fontSize(22)
        .fontWeight(FontWeight.Bold)
        .textColor('#1a1a1a')

      // Agent可用时显示按钮,不可用时显示提示
      if (this.isAgentAvailable) {
        FunctionComponent({
          agentId: this.myAgentId,
          onError: (err: BusinessError) => {
            hilog.error(0x0001, 'AgentDemo', `拉起失败:${err.code} - ${err.message}`);
            // 这里可以加Toast提示用户,比如:
            // Toast.showToast({ message: '智能体拉起失败,请稍后再试' });
          },
          controller: this.agentController,
          options: {
            title: '智能生成工作计划', // 按钮标题(显示为按钮组件)
            queryText: '帮我生成一份本周的开发工作计划,包含需求评审、编码、测试', // 初始意图
            isShowShadow: true, // 显示按钮阴影
            // 更多配置可参考官方文档的FunctionComponent参数说明
          }
        })
      } else {
        Text('当前设备不支持智能体功能\n请检查:1. 登录华为账号 2. 联网 3. 使用手机/平板')
          .fontSize(14)
          .textColor('#ff4444')
          .textAlign(TextAlign.Center)
          .width('80%')
      }
    }
    .width('100%')
    .height('100%')
    .padding(30)
    .backgroundColor('#f5f5f5')
  }
}

五、如何创建小艺生态智能体

傻瓜操作,在小艺开放平台上,点击创建后,使用自然语言描述你的智能体的功能和作用。目前上架还没完全开放。但是可以体验效果。
【 HarmonyOS 6 】HarmonyOS智能体开发实战:Function组件和智能体创建-鸿蒙开发者社区

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
1
收藏 1
回复
举报
回复
    相关推荐