UniApp 中拉起鸿蒙小艺智能体技术详解

2 阅读13分钟

目录


前言

大家好!我是一名全栈开发者Jack,最近在基于UniAPP开发一款名为 BabyOne 的育儿助手应用。在开发过程中,我成功集成了鸿蒙系统的小艺智能体功能,让用户可以通过 AI 助手获得专业的育儿建议和问答服务。

为了让更多开发者能够快速上手,我将这个功能封装成了 jack-aiagent 插件,并在 UniApp 插件市场发布。本文将详细介绍如何在 UniApp 项目中使用这个插件,实现一键拉起小艺智能体的功能。

开始之前

在开始之前,需要准备好一个小艺智能体,如果还不会创建的,可以参考我的上一篇文章完成创建哦~

传送门:华为小艺智能体完整创建流程保姆级教程(附审核避坑指南)

此外,发布智能体前,需要提前关联应用,具体操作如下:

  1. 在工作空间中找到准备关联的智能体,点击进入

  2. 找到**「关联应用」**,点击右侧的「+」号,添加对应的应用即可

调试时,如果智能体暂未发布,可以配置设备白名单后,发布真机调试,即可正常被白名单的设备拉起测试~

什么是小艺智能体?

小艺智能体是华为鸿蒙系统提供的 AI 能力,开发者可以创建自己的智能体,为用户提供:

  • 智能问答:基于大语言模型的对话能力
  • 个性化服务:根据应用场景定制的专业建议
  • 精准响应:针对特定领域的知识库支持
  • 多轮对话:支持上下文理解的连续对话

在我的 BabyOne 应用中,我创建了“育儿小伴侣BabyOne”智能体,它可以回答关于宝宝喂养、健康、早教等各方面的问题,成为新手父母的贴心助手。

jack-aiagent 插件介绍

官方文档中,需要使用Agent Framework Kit中的Function组件拉起智能体。但是在UniAPP中无法直接使用,需要“搭桥”来实现。

在我的 BabyOne 应用实际开发过程中,为了简化在 UniApp 中集成小艺智能体的流程,我封装了 jack-aiagent 插件。

插件特点

  • 简单易用:只需一个 <embed> 标签即可集成
  • 原生体验:基于鸿蒙原生 API,性能优异
  • 开箱即用:无需复杂配置,快速接入
  • 完全免费:已在 UniApp 插件市场发布,免费使用

插件地址

🔗 UniApp 插件市场ext.dcloud.net.cn/plugin?name…

技术架构

插件目录结构

uni_modules/jack-aiagent/
├── utssdk/
│   └── app-harmony/
│       ├── aiagent.ets             # 鸿蒙平台实现
│       └── index.uts               # UTS插件引入
└── package.json

插件完整源码

为了方便大家使用和理解,这里提供 jack-aiagent 插件的完整源代码,可以直接复制到你的项目中使用。

1. jack-aiagent/utssdk/app-harmony/aiagent.ets(鸿蒙平台实现)


import { NodeRenderType } from '@kit.ArkUI'
import { NativeEmbedBuilderOptions, defineNativeEmbed } from "@dcloudio/uni-app-runtime"

import { FunctionComponent, FunctionController } from '@kit.AgentFrameworkKit';
import { BusinessError } from "@kit.BasicServicesKit";

interface AgentBuilderOptions extends NativeEmbedBuilderOptions {
  agentId: string,
  title: string,
  queryText: string
}

@Component
struct AiAgentComponent {
  @Prop agentId: string
  @Prop title: string
  @Prop queryText: string

  build() {
    FunctionComponent({
      agentId: this.agentId,
      onError: (err: BusinessError) => {
        console.log(err.message)
      },
      options: {
        title: this.title,
        queryText: this.queryText,
        isShowShadow: false,  // 这里可以根据需要选择是否要阴影,在我的BabyOne中,为了适配场景,所以调整成了false,如果有需要可以改为true
        titleColors:['#1AD0F1','#FFA4E5']
      },
      controller:new FunctionController()
    })
    
  }
}

@Builder
function AiAgentBuilder(options: AgentBuilderOptions) {
  AiAgentComponent(options)
    .width(options.width)
    .height(options.height)

  
}

defineNativeEmbed('aiagent', {
  builder: AiAgentBuilder
})

2. jack-aiagent/utssdk/app-harmony/index.uts(接口定义)


import './aiagent.ets';

核心实现原理

插件使用 UniApp 的 <embed> 标签来嵌入鸿蒙原生组件,通过传递参数来配置智能体的行为。

快速开始

第一步:安装插件

方式一:通过 HBuilderX 插件市场安装(推荐)

  1. 打开 HBuilderX
  2. 访问插件市场:ext.dcloud.net.cn/plugin?name…
  3. 点击"使用 HBuilderX 导入插件"
  4. 选择你的项目,完成导入

方式二:手动安装

  1. 打卡 HBuilderX
  2. 找到 uni_modules 目录,右击点击新建插件
  3. 填写好插件名称 jack-aiagent,分类选择 「UTS插件-API插件」,完成创建即可
  4. 复制上面的源码
  5. 找到对应的路径,替换对应的内容即可
  6. 重新编译运行

第二步:获取智能体 ID

在使用插件之前,你需要先在华为开发者平台创建自己的智能体:

  1. 访问 华为开发者联盟
  2. 进入"小艺智能体"管理后台
  3. 创建新的智能体,配置知识库和对话能力
  4. 获取智能体的 agentId

具体操作可以参考我的上一篇文章的「五、智能体ID」哦~

传送门:华为小艺智能体完整创建流程保姆级教程(附审核避坑指南)

第三步:在页面中使用

这是最简单的部分!只需要在你的页面中添加一个 <embed> 标签即可。

完整示例代码

下面是我BabyOne应用中的一个完整的示例页面,展示了如何使用 jack-aiagent 插件:

<template>
  <view class="ai-agent-page">
    <!-- 右上角装饰圆 -->
    <view class="decoration-circle"></view>
    
    <!-- #ifdef APP-HARMONY -->
    <!-- AI 智能体按钮 -->
    <view class="ai-agent-container">
      <embed 
        class="ai-agent-native" 
        tag="aiagent" 
        :options="agentOptions"
      ></embed>
    </view>
    <!-- #endif -->
    
    <text class="button-hint">点击上方按钮召唤AI助手</text>
    
    <!-- 介绍说明区域 -->
    <view class="intro-section">
      <view class="intro-card">
        <view class="card-header">
          <text class="card-icon">✨</text>
          <text class="card-title">育儿小伴侣BabyOne</text>
        </view>
        
        <view class="card-content">
          <text class="intro-text">
            点击上方的"育儿小伴侣"按钮,即可召唤BabyOne软件提供的《育儿小伴侣BabyOne》小艺智能体。
          </text>
          
          <view class="feature-list">
            <view class="feature-item">
              <text class="feature-icon">💬</text>
              <view class="feature-info">
                <text class="feature-title">智能问答</text>
                <text class="feature-desc">专业的育儿知识问答服务</text>
              </view>
            </view>
            
            <view class="feature-item">
              <text class="feature-icon">👶</text>
              <view class="feature-info">
                <text class="feature-title">个性化建议</text>
                <text class="feature-desc">根据宝宝情况提供定制建议</text>
              </view>
            </view>
            
            <view class="feature-item">
              <text class="feature-icon">📚</text>
              <view class="feature-info">
                <text class="feature-title">知识库丰富</text>
                <text class="feature-desc">涵盖喂养、健康、早教等领域</text>
              </view>
            </view>
            
            <view class="feature-item">
              <text class="feature-icon">⚡</text>
              <view class="feature-info">
                <text class="feature-title">即时响应</text>
                <text class="feature-desc">快速解答您的育儿疑问</text>
              </view>
            </view>
          </view>
        </view>
      </view>
      
      <!-- 使用提示 -->
      <view class="tips-card">
        <view class="tips-header">
          <text class="tips-icon">💡</text>
          <text class="tips-title">使用提示</text>
        </view>
        <view class="tips-list">
          <text class="tip-item">• 您可以询问任何育儿相关的问题</text>
          <text class="tip-item">• 支持语音和文字两种交互方式</text>
          <text class="tip-item">• AI助手会根据您的问题提供专业建议</text>
          <text class="tip-item">• 建议结合实际情况参考使用</text>
        </view>
      </view>
    </view>
  </view> 
</template>

<script>
// #ifdef APP-HARMONY
import 'uni_modules/jack-aiagent'
// #endif

export default {
  data() {
    return {
      agentOptions: {
        agentId: 'agent9**************************',  // 你的智能体 ID
        title: '育儿智能助手',                          // 按钮显示的标题
        queryText: '你好,我想咨询育儿问题'               // 默认问题(可以留空)
      }
    }
  },
  
  onLoad(options) {
    console.log('AI Agent 页面加载:', this.agentOptions)
  }
}
</script>

<style lang="scss" scoped>
.ai-agent-page {
  width: 100%;
  min-height: 100vh;
  background: #fff4f9;
  padding: 10rpx 40rpx;
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  align-items: center;
  position: relative;
  overflow: hidden;
}

/* 右上角装饰圆 */
.decoration-circle {
  position: absolute;
  top: -100rpx;
  right: -100rpx;
  width: 300rpx;
  height: 300rpx;
  border-radius: 50%;
  background: linear-gradient(135deg, #FF9A9E, #FECFEF);
  opacity: 0.15;
  z-index: 0;
}

.ai-agent-container {
  width: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 40rpx 0;
  position: relative;
  z-index: 1;
  box-sizing: border-box;
  padding: 0;
}

.ai-agent-native {
  width: 130px;
  height: 40px;
  text-align: center;
}

.button-hint {
  font-size: 26rpx;
  color: #FF9A9E;
  text-align: center;
  position: relative;
  z-index: 1;
}

/* 介绍说明区域 */
.intro-section {
  display: flex;
  flex-direction: column;
  gap: 24rpx;
  text-align: left;
  position: relative;
  z-index: 1;
  width: 100%;
}

.intro-card {
  background: #fff;
  border-radius: 24rpx;
  padding: 32rpx;
  box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
}

.card-header {
  display: flex;
  align-items: center;
  gap: 12rpx;
  margin-bottom: 24rpx;
}

.card-icon {
  font-size: 32rpx;
}

.card-title {
  font-size: 32rpx;
  font-weight: 600;
  color: #333;
  text-align: left;
}

.card-content {
  display: flex;
  flex-direction: column;
  gap: 24rpx;
}


.feature-list {
  display: flex;
  flex-direction: column;
  gap: 20rpx;
  margin-top: 8rpx;
}

.feature-item {
  display: flex;
  align-items: flex-start;
  gap: 16rpx;
  padding: 20rpx;
  background: linear-gradient(135deg, #FFF5F5, #FFF0F5);
  border-radius: 16rpx;
}

.feature-icon {
  font-size: 36rpx;
  line-height: 1;
}

.feature-info {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 4rpx;
}

.feature-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
}

.feature-desc {
  font-size: 24rpx;
  color: #999;
  line-height: 1.5;
}

/* 使用提示 */
.tips-card {
  background: #fff;
  border-radius: 24rpx;
  padding: 32rpx;
  box-shadow: 0 4rpx 24rpx rgba(0, 0, 0, 0.06);
}

.tips-header {
  display: flex;
  align-items: center;
  gap: 12rpx;
  margin-bottom: 20rpx;
}

.tips-icon {
  font-size: 28rpx;
}

.tips-title {
  font-size: 28rpx;
  font-weight: 600;
  color: #333;
}

.tips-list {
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}

.tip-item {
  font-size: 26rpx;
  color: #666;
  line-height: 1.8;
}
</style>

示例效果图

当然了,还可以稍加修改,放到首页中,更加美观哦~效果如下图(页面右上角):

核心代码解析

1. embed 标签的使用

这是整个插件最核心的部分,只需要一个 <embed> 标签:

<embed 
  class="ai-agent-native" 
  tag="aiagent" 
  :options="agentOptions"
></embed>

参数说明:

  • tag="aiagent":指定要嵌入的原生组件类型
  • :options="agentOptions":传递配置参数给智能体

2. agentOptions 配置对象

agentOptions: {
  agentId: 'agent9**************************',    // 必填:智能体 ID
  title: '育儿智能助手',                            // 可选:按钮显示文字
  queryText: '你好,我想咨询育儿问题'                 // 可选:默认问题
}

配置项详解:

参数类型必填说明
agentIdString智能体的唯一标识符,从华为开发者平台获取
titleString按钮上显示的标题文字,无标题时默认显示图标组件
queryTextString点击按钮后发送给智能体的初始问候语

3. 条件编译处理

由于智能体功能仅在鸿蒙平台支持,需要使用条件编译:

<!-- #ifdef APP-HARMONY -->
<view class="ai-agent-container">
  <embed 
    class="ai-agent-native" 
    tag="aiagent" 
    :options="agentOptions"
  ></embed>
</view>
<!-- #endif -->

<!-- #ifndef APP-HARMONY -->
<view class="not-support">
  <text class="not-support-text">当前平台暂不支持智能体功能</text>
  <text class="not-support-hint">请在鸿蒙设备上体验</text>
</view>
<!-- #endif -->

4. 动态参数传递

如果需要从其他页面跳转并传递参数:

// 页面 A:跳转并传递参数
uni.navigateTo({
  url: '/pages/ai-agent-function/index?agentId=your_agent_id&message=' + encodeURIComponent('帮我查询宝宝疫苗接种时间')
})

// 页面 B:接收参数
onLoad(options) {
  if (options.agentId) {
    this.agentOptions.agentId = options.agentId
  }
  if (options.message) {
    this.agentOptions.queryText = decodeURIComponent(options.message)
  }
}

实际应用场景

场景一:育儿咨询助手

在 BabyOne 应用中,我将智能体集成到了多个场景:

// 疫苗接种页面
navigateToAIAgent() {
  uni.navigateTo({
    url: '/pages/ai-agent-function/index?message=' + 
         encodeURIComponent('我的宝宝3个月了,应该接种什么疫苗?')
  })
}

// 喂养指导页面
askFeedingQuestion() {
  uni.navigateTo({
    url: '/pages/ai-agent-function/index?message=' + 
         encodeURIComponent('6个月宝宝辅食添加顺序是什么?')
  })
}

// 健康咨询页面
consultHealth() {
  uni.navigateTo({
    url: '/pages/ai-agent-function/index?message=' + 
         encodeURIComponent('宝宝发烧38度,应该怎么处理?')
  })
}

场景二:智能客服

// 在客服页面集成智能体
data() {
  return {
    agentOptions: {
      agentId: 'your_customer_service_agent_id',
      title: '智能客服',
      queryText: '您好,有什么可以帮您的?'
    }
  }
}

场景三:知识问答

// 在知识库页面集成智能体
data() {
  return {
    agentOptions: {
      agentId: 'your_knowledge_agent_id',
      title: '知识助手',
      queryText: '请问有什么想了解的?'
    }
  }
}

进阶技巧

1. 多智能体切换

如果你的应用有多个智能体,可以动态切换:

<template>
  <view>
    <picker @change="onAgentChange" :value="currentAgentIndex" :range="agents" range-key="name">
      <view class="picker">
        当前智能体:{{ agents[currentAgentIndex].name }}
      </view>
    </picker>
    
    <!-- #ifdef APP-HARMONY -->
    <embed 
      class="ai-agent-native" 
      tag="aiagent" 
      :options="currentAgent"
    ></embed>
    <!-- #endif -->
  </view>
</template>

<script>
export default {
  data() {
    return {
      currentAgentIndex: 0,
      agents: [
        {
          name: '育儿助手',
          agentId: 'agent_parenting_id',
          title: '育儿助手',
          queryText: '您好,我是育儿助手'
        },
        {
          name: '健康顾问',
          agentId: 'agent_health_id',
          title: '健康顾问',
          queryText: '您好,我是健康顾问'
        },
        {
          name: '营养师',
          agentId: 'agent_nutrition_id',
          title: '营养师',
          queryText: '您好,我是营养师'
        }
      ]
    }
  },
  
  computed: {
    currentAgent() {
      return this.agents[this.currentAgentIndex]
    }
  },
  
  methods: {
    onAgentChange(e) {
      this.currentAgentIndex = e.detail.value
    }
  }
}
</script>

2. 与用户数据结合

根据用户信息定制智能体的问候语:

onLoad() {
  const userInfo = uni.getStorageSync('userInfo')
  const babyInfo = uni.getStorageSync('babyInfo')
  
  if (userInfo && babyInfo) {
    this.agentOptions.queryText = 
      `您好${userInfo.name},您的宝宝${babyInfo.name}现在${babyInfo.age}个月了,有什么可以帮您的吗?`
  }
}

常见问题 FAQ

Q1: 如何获取智能体 ID?

A: 按照以下步骤获取:

  1. 登录 华为开发者联盟
  2. 进入"小艺智能体"管理后台
  3. 创建或选择已有的智能体
  4. 在智能体详情页面找到 agentId,格式类似:agent9b5fb0d253194fde9b8e218c5ce36592

Q2: 插件在非鸿蒙平台会报错吗?

A: 不会。使用条件编译 #ifdef APP-HARMONY 后,在其他平台上这段代码不会被编译,因此不会报错。建议添加提示信息:

<!-- #ifndef APP-HARMONY -->
<view class="not-support">
  <text>当前平台暂不支持智能体功能</text>
</view>
<!-- #endif -->

Q3: 可以自定义按钮样式吗?

A: 按钮是鸿蒙原生Function组件,样式由系统控制。但你可以通过 CSS 调整容器的布局和位置:

.ai-agent-container {
  display: flex;
  justify-content: center;
  align-items: center;
  margin: 40rpx 0;
}

.ai-agent-native {
  width: 130px;   /* 可调整宽度 */
  height: 40px;   /* 可调整高度 */
}

Q4: 智能体按钮点击后没有反应?

A: 可能的原因:

  1. agentId 错误:检查是否正确填写了智能体 ID
  2. 网络问题:智能体需要网络连接,检查设备网络状态
  3. 权限问题:确保应用有网络访问权限
  4. 系统版本:确保鸿蒙系统版本支持智能体功能
  5. 智能体没有关联应用:确保智能体发布前,关联上了这个应用

Q5: 一个应用可以集成多个智能体吗?

A: 可以!只需要在不同页面或场景使用不同的 agentId 即可:

// 育儿助手
agentOptions: {
  agentId: 'agent_parenting_id'
}

// 健康顾问
agentOptions: {
  agentId: 'agent_health_id'
}

性能优化建议

1. 缓存配置

将智能体配置缓存到本地,减少重复配置:

// utils/ai-agent-config.js
export const AI_AGENT_CONFIG = {
  parenting: {
    agentId: 'agent_parenting_id',
    title: '育儿助手',
    queryText: '您好,我是育儿助手'
  },
  health: {
    agentId: 'agent_health_id',
    title: '健康顾问',
    queryText: '您好,我是健康顾问'
  }
}

// 在页面中使用
import { AI_AGENT_CONFIG } from '@/utils/ai-agent-config.js'

export default {
  data() {
    return {
      agentOptions: AI_AGENT_CONFIG.parenting
    }
  }
}

2. 错误边界

添加错误处理,提升用户体验:

<template>
  <view>
    <!-- #ifdef APP-HARMONY -->
    <view v-if="isSupported" class="ai-agent-container">
      <embed 
        class="ai-agent-native" 
        tag="aiagent" 
        :options="agentOptions"
        @error="onAIAgentError"
      ></embed>
    </view>
    <view v-else class="error-tip">
      <text>智能体功能暂时不可用</text>
    </view>
    <!-- #endif -->
  </view>
</template>

<script>
export default {
  data() {
    return {
      isSupported: true,
      agentOptions: {
        agentId: 'your_agent_id',
        title: '智能助手',
        queryText: '你好'
      }
    }
  },
  
  methods: {
    onAIAgentError(e) {
      console.error('智能体加载失败:', e)
      this.isSupported = false
      uni.showToast({
        title: '智能体暂时不可用',
        icon: 'none'
      })
    }
  }
}
</script>

总结

通过本文,我分享了如何在 UniApp 项目中使用 jack-aiagent 插件,快速集成鸿蒙小艺智能体功能。这个插件具有以下优势:

简单易用:只需一个 <embed> 标签即可集成
开箱即用:无需复杂配置,快速接入
原生体验:基于鸿蒙原生 API,性能优异
完全免费:已在 UniApp 插件市场发布,免费使用
场景丰富:适用于客服、问答、咨询等多种场景

在 BabyOne 应用的开发过程中,智能体功能极大地提升了用户体验,让新手父母能够随时获得专业的育儿建议。希望这个插件也能帮助到更多开发者!

插件下载

🔗 UniApp 插件市场ext.dcloud.net.cn/plugin?name…


如有问题或建议,欢迎在评论区交流讨论!


💡 提示:本文示例代码已在 HarmonyOS NEXT 上测试通过。如果你在使用过程中遇到问题,欢迎在评论区留言!

如果本文对你有帮助,欢迎点赞、收藏、关注!也欢迎分享给更多需要的开发者!