尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

从 App 到 Agent:鸿蒙意图框架 Intents Kit 实战开发「小艺出行」

从 App 到 Agent:鸿蒙意图框架 Intents Kit 实战开发「小艺出行」 从 App 到 Agent鸿蒙意图框架 Intents Kit 实战开发「小艺出行」引言Agent 时代应用的角色正在被重新定义在正式展开之前先描述一个本项目开发过程中验证成功的真实场景。用户表达一句帮我加个明天九点去机场的行程系统随即理解这一意图从中抽取出目的地、时间等结构化参数并将其分发给本项目开发的出行应用由应用完成行程的创建——整个过程中用户无需主动打开应用任务即被准确完成这一场景揭示了 Agent 时代一个根本性的变化用户不再关心是哪一个应用完成了任务只关心任务本身是否被正确完成。应用能够被系统精准调用的前提是它已向系统声明了自身具备处理相应意图的能力。而这种向系统声明能力、并由系统完成意图分发的机制正是本文要探讨的核心鸿蒙的意图框架Intents Kit。笔者从事 App 开发多年鸿蒙从早期版本一路使用到 HarmonyOS NEXT。过去开发关注的核心始终是页面布局、交互设计与动效实现。而本文希望系统性地记录一次开发范式的转变——从开发一个供用户主动打开的 App到构建一个供系统随时调用的 Agent 能力并在此过程中探讨意图即服务这一理念的工程价值。为使论述具备可验证性本文将以一个真实、可编译的 Demo——「小艺出行」——为主线完整呈现其从零构建到在手机与鸿蒙 PC 双端运行的全过程。鸿蒙手机端运行截图鸿蒙电脑PC端运行截图一、开发范式的转变从应用中心到意图中心在进入代码实现之前有必要先厘清本次开发中最重要的认知升级因为它决定了后续全部技术选型的方向。1.1 传统模式以应用为中心传统 App 的设计遵循以应用为中心的逻辑。以添加行程为例用户的操作路径通常是解锁设备 → 定位应用图标 → 打开应用 → 等待首页加载 → 找到新增入口 → 填写表单 → 保存提交。这一链路涉及多个步骤开发者需要为每一步设计界面、优化性能并通过埋点分析用户流失环节。在这一模式下应用开发的核心目标是获取并留住用户的注意力。应用本身是一个用户必须主动抵达的目的地。1.2 Agent 模式以意图为中心Agent 时代的设计遵循以意图为中心的逻辑。同样是添加行程用户只需表达一句帮我加个明天九点去机场的行程即可完成。在这一过程中用户全程无需打开任何应用。用户表达意图系统中的智能体小艺负责理解该意图并将其路由给最合适的能力提供方执行。其中的关键在于路由机制。应用不再是孤立的目的地而是成为系统能力网络中的一个节点。开发者的核心工作也从设计吸引用户的界面转变为向系统清晰声明可处理哪些意图、需要哪些参数、执行后返回何种结果。1.3 对开发者的实际影响这一范式转变可归纳为三个层面从流量获取到意图接入核心不再是将用户引导进入应用而是让系统在恰当的时机调用应用能力。从界面开发到契约定义核心产出物从一系列 UI 页面转变为一份清晰的意图契约能力范围与参数定义。从单点体验到全场景触达一次能力声明即可在手机、平板、PC、车机等所有小艺可达的设备上生效。理解这三个层面再审视意图框架的相关 API其设计逻辑便清晰可循。二、场景选择为何采用出行助手在候选场景记账、点餐、快递查询等中最终选定出行助手作为演示场景主要基于以下几点考量它们都高度契合意图分发的特性意图表达天然口语化。“加个明天去机场的行程”“我明天有什么安排”导航去公司等表达均为用户的自然语言输入是意图框架的理想应用对象。参数可清晰结构化。目的地、出行方式、时间、备注等要素能够准确映射到意图框架的参数 schema便于演示系统从自然语言中抽取结构化参数的过程。可演示多意图协同。出行并非单一动作至少涵盖添加、查询、导航三类操作可完整展示多个意图如何共存与分派而非孤立的单一功能。天然具备跨设备特性。出行场景涉及手机查询、PC 规划、车机导航等多终端协作契合鸿蒙一次开发、多端部署的设计理念。基于以上考量本文构建了「小艺出行」一个纯端侧、无后端依赖、向小艺开放三种出行能力的应用。三、Demo 整体架构三个页面与三个意图首先给出整体结构概览后续章节将逐层展开。三个页面底部 Tab 切换深色科技风概览品牌头、下一程渐变大卡、今日行程列表以及一块小艺能帮你做什么的引导区。行程全部行程的时间线支持手动新增底部弹层、左滑删除、点标签切换完成状态。我的把三个意图能力做成了可开关的清单配上统计卡片和关于信息。三个意图开放给小艺的能力用户对小艺说命中意图App 行为「加个明天9点去首都机场的行程」AddTrip创建行程并跳到行程页「我明天有什么安排」QueryTrips汇总行程、语音式播报「导航去公司」NavigateTo真实拉起地图规划路线工程目录长这样只列关键部分entry/src/main/ ├── ets/ │ ├── entryability/EntryAbility.ets 入口解析意图 Want、沉浸式全屏 │ ├── common/ │ │ ├── Theme.ets 设计主题色板/尺寸 │ │ └── TripCard.ets 行程卡组件多页复用 │ ├── intents/ │ │ └── TripIntentExecutor.ets 意图执行器三意图共用按名分派 │ ├── model/ │ │ ├── Trip.ets 行程模型 Preferences 持久化 │ │ ├── IntentHandler.ets Want 参数解析 │ │ └── NavHelper.ets 拉起地图导航 │ └── pages/ │ ├── Index.ets 三 Tab 主壳 意图结果回流 │ ├── OverviewTab.ets / TripsTab.ets / ProfileTab.ets ├── resources/base/profile/insight_intents.json 意图声明 └── module.json5 注册 intent metadata四、核心实现向系统声明应用能力这是从 App 到 Agent 转变中最关键的一步。与传统开发首先编写页面不同本项目首先编写的是一份 JSON 配置文件——意图声明。4.1 意图声明insight_intents.json意图声明需要向系统明确三项信息应用具备哪些意图、每个意图的定义、执行该意图所需的参数。以添加行程为例{intentName:AddTrip,domain:TravelManagement,displayName:添加行程,llmDescription:当用户想安排出行、添加行程、记录一次出发时使用。可从表达中提取目的地 destination、出行方式 type、时间 when、备注 note。例如「帮我加个明天9点去首都机场的行程」。,keywords:[加行程,安排出行,添加行程,去,出发],parameters:{type:object,properties:{destination:{type:string,description:目的地必填},type:{type:string,enum:[飞机,高铁,驾车,打车,地铁,步行]},when:{type:string,description:出发时间的自然语言描述},note:{type:string,description:备注可选}},required:[destination]},executor:ets/intents/TripIntentExecutor.ets}这段配置中最值得关注的是llmDescription字段。它并非面向机器的枚举定义而是以自然语言撰写、供大模型理解的能力说明。开发者需要清晰地向小艺表达“在何种场景下应调用本应用以及需要从用户表达中抽取哪些关键信息”。这代表了一种新的编程范式开发者编写的是面向 AI 的提示prompt而非面向编译器的逻辑。keywords用于辅助召回parameters则定义了结构化契约——小艺依据该 schema将用户的口语表达解析为destination首都机场、type飞机、when明天9点等结构化字段。这一抽取过程由系统的大模型完成开发者无需自行实现任何自然语言处理逻辑。4.2 在模块中注册声明仅有声明文件尚不足够还需在module.json5中通过metadata向系统注册该意图声明metadata: [ { name: ohos.ability.intent.metadata, resource: $profile:insight_intents } ]这条配置即完成了应用向系统声明能力的注册动作。4.3 意图执行器能力的具体实现意图声明解决了应用能做什么的问题执行器则负责如何执行。本项目的三个意图共用一个执行器按意图名称进行分派exportdefaultclassTripIntentExecutorextendsInsightIntentExecutor{asynconExecuteInUIAbilityForegroundMode(name:string,param:Recordstring,Object,pageLoader:object):PromiseinsightIntent.ExecuteResult{letmessage;if(nameQueryTrips){messageawaitthis.doQuery(str(param[when]));}elseif(nameNavigateTo){constdeststr(param[destination]);awaitopenNavigation(this.contextascommon.UIAbilityContext,dest);message正在为你拉起地图规划前往「${dest}」的路线…;}else{messageawaitthis.doAdd(param);// AddTrip}// 结果写入全局状态供 UI 回流展示AppStorage.setOrCreate(lastIntentMsg,message);AppStorage.setOrCreate(intentTick,Date.now());return{code:0,result:{message}}asinsightIntent.ExecuteResult;}}需要注意的是最后返回的result.message——它不仅用于 UI 展示还可被小艺进行语音播报。因此文案的撰写需要兼顾语音朗读的流畅度。这是与传统 App 开发的又一处差异返回值需要同时考虑可视与可听两种呈现方式。五、意图结果的 UI 回流机制意图执行完毕后数据发生变更而用户当前可能正处于应用的某个页面。如何实现界面的实时、无感更新是本项目遇到的第一个技术难点。最初的实现是在页面的onPageShow中执行刷新。但实践发现当小艺或深链触发操作时应用已处于前台显示状态不会再次触发onPageShow导致列表无法更新必须手动切换页面或重启应用用户体验较差。改进方案采用全局状态 Watch监听的响应式机制。执行器将结果写入AppStorage页面订阅并监听其变化StorageLink(intentTick)Watch(onIntentResult)intentTick:number0;StorageLink(lastIntentMsg)lastIntentMsg:string;StorageLink(intentJumpTab)intentJumpTab:number-1;onIntentResult():void{// 弹出语音式反馈promptAction.showToast({message: 小艺this.lastIntentMsg,duration:2800});// 自动跳到相关 Tab添加→行程页导航→概览页if(this.intentJumpTab0this.intentJumpTab2){this.currentthis.intentJumpTab;}}该方案的核心在于使用一个递增的intentTick时间戳作为触发信号。每次意图处理完成后更新该值Watch随即响应——无论应用是否处于前台UI 均可即时刷新、弹出反馈并自动跳转至相关页面。这种以时间戳作为信号驱动响应式刷新的方法是本项目在调试过程中总结出的一项实用技巧。六、导航能力的实现真实拉起地图应用在初始版本中导航意图仅弹出正在规划路线的示例提示。为使其具备实际产品价值需要实现真实拉起地图应用的能力。鸿蒙中的应用间跳转通过startAbility Want 实现。由于不同设备预装的地图应用存在差异本项目设计了一条降级调用链依次尝试 Petal 地图、高德、百度任一成功即调用全部失败时则使用系统隐式 Want 作为兜底方案。exportasyncfunctionopenNavigation(context:common.UIAbilityContext,dest:string):Promiseboolean{constschemes[{name:PetalMaps,uri:maps://routes?daddr${encodeURIComponent(dest)}typedrive},{name:Amap,uri:amapuri://route/plan/?dname${encodeURIComponent(dest)}t0},{name:BaiduMap,uri:baidumap://map/direction?destination${encodeURIComponent(dest)}modedriving}];for(constsofschemes){try{awaitcontext.startAbility({uri:s.uri});returntrue;// 谁先成功就用谁}catch(e){/* 该地图未安装继续尝试下一个 */}}// 兜底系统隐式 Want可能弹出可选地图列表try{awaitcontext.startAbility({action:ohos.want.action.viewData,uri:geo:0,0?q${encodeURIComponent(dest)}});returntrue;}catch(e){returnfalse;}}这一设计同样体现了 Agent 化的思路应用无需自行实现地图功能而是将导航这一子任务委托给系统中最擅长处理它的能力提供方。应用之间由此从独立运行转变为能力协作。七、双端适配手机与鸿蒙 PC 的一致运行鸿蒙一次开发、多端部署的能力在本项目中得到了充分验证。该 Demo 未为 PC 单独编写任何布局代码即可在手机与鸿蒙 PC 上直接运行。实现这一效果依赖于开发之初即遵循的几项原则采用弹性布局而非固定尺寸宽度使用layoutWeight、百分比及Flex自动换行避免硬编码 px从而在 PC 大屏下自然展开。安全区适配通过getWindowAvoidArea获取状态栏与导航条高度并存入全局状态页面统一避让可正确处理手机刘海与 PC 窗口边框。组件化复用将行程卡TripCard抽象为独立组件供概览页与列表页复用在不同屏幕尺寸下表现一致。尤为重要的是意图能力天然具备跨端特性。同一份insight_intents.json在手机与鸿蒙 PC 上均可通过小艺触发——因为意图是注册于系统层面而非某一具体屏幕。这正是第一章所述一次声明、全场景触达的实际体现。本项目从模拟器到真机手机再到鸿蒙 PC全程无需修改代码即可运行充分验证了鸿蒙跨端能力的工程价值。八、开发过程中的典型问题与解决方案在 Demo 的开发过程中遇到了若干典型问题现选取几个具有代表性的进行记录供开发者参考。8.1 语音指令被分发至系统日历这是最具代表性的一个现象唤醒小艺添加行程时行程被添加进系统日历本应用无任何响应。经排查其原因在于真实小艺是基于华为云端已上架的意图库进行匹配的。系统日历早已上架了日程类意图而本应用的AddTrip仅为本地声明尚未通过 AppGallery Connect 完成意图框架能力申请与上架因此小艺云端无法感知本应用具备处理该类意图的能力。由此可明确区分两个层面本地声明insight_intents.json仅解决应用内部知晓自身能力的问题平台上架在 AGC 申请意图框架能力并提审才能使小艺云端知晓应用能力从而在真实语音场景中完成意图分发。明确这一机制后即可采用下述方式在本地验证代码的正确性。8.2 未上架情况下的意图链路验证在无法通过语音触发的情况下可使用aa start将意图直接投递至应用——该方式与真实小艺分发所使用的want.parameters通道完全一致# 添加行程结构化参数与真实小艺同通道hdc shellaa start -a EntryAbility -b com.example.smarttrip \ --ps op add --ps destination 首都机场 --ps type flight --ps when tomorrow 9初期为简便起见采用 URI 深链?axby方式传参但发现在多层 shell 环境中被解析为命令分隔符导致仅首个参数能够传入。改用--psstring 参数直接写入want.parameters后问题得以解决。8.3 命令行中文参数乱码命令行传递中文参数如type餐饮经hdc shell处理后会出现编码错乱导致解析失败。需要说明的是这是命令行终端的编码限制真实小艺采用结构化参数传递不受此影响。本项目的应对方案是在参数解析中增加英文 key 到中文的映射如flight→飞机、drive→驾车本地测试使用英文参数既规避了乱码又不影响真实场景。8.4 环境变量污染导致构建失败开发过程中曾遇到构建报错ERR_WORKER_INVALID_EXEC_ARGV: --report-on-fatalerror is not allowed in NODE_OPTIONS且 DevEco Studio 内部 Sync 亦无法执行。经定位原因是NODE_OPTIONS环境变量被外部工具污染而 DevEco Studio 作为 GUI 进程继承了启动时的异常环境。解决方案为彻底退出应用、清除该变量后重新启动。此类环境问题虽与代码无关但排查耗时较长故一并记录。九、意图框架的工程价值分析完成本 Demo 后笔者对意图即服务这一理念有了更为具体的工程层面的认识。其一降低了应用的流量获取压力。开发者无需再刻意引导用户进入应用只要应用能力可靠、意图声明清晰系统即可在恰当时机调用应用能力。竞争维度从应用入口的显著程度转向应用能力的可靠程度。其二重新赋予了垂直应用价值。专注于单一功能并将其做到极致的应用在传统模式下获客较为困难而在意图分发机制下可作为特定垂直意图的最优提供方被系统精准调用这对独立开发者具有积极意义。其三促使开发者重新审视应用的边界。导航功能的实现表明应用无需追求功能大而全完全可以将子任务委托给更专业的能力方。应用之间由此从相互独立转变为协作网络而小艺则承担了调度中枢的角色。与此同时该模式也提出了新的能力要求开发者需要掌握以自然语言撰写面向 AI 的能力说明llmDescription、将返回值优化为适合语音播报的文案、并为跨端场景进行弹性设计。这些均是传统 App 开发中较少涉及的新课题。十、结语回到本文开头所述的场景——用户一句自然语言表达系统即完成意图理解、参数抽取与应用调用行程被准确创建。这一过程印证了一个核心观点在 Agent 时代一个应用真正的起点不是它的首个页面而是它向系统声明的能力契约。从开发一个供用户主动打开的 App到构建一个供系统随时调用的 Agent 能力二者之间的差异并非几个 API而是一整套开发思维的迁移。「小艺出行」Demo 虽仅包含三个页面与三个意图、代码量有限却完整呈现了这一迁移的全过程包括其中的技术难点与解决方案。HarmonyOS 正在将意图即服务构建为每一位开发者均可使用的基础设施。对于长期从事鸿蒙开发的工程师而言能够在这一范式转变的起点参与实践具有重要的意义。对于正在开发鸿蒙应用的开发者笔者建议选取一个熟悉的场景为其编写意图声明并接入小艺。通过这一实践可以真切地理解到——Agent 时代已经到来并已具备完整的工程落地条件。
返回列表