我要提问
ARTICLE DETAIL

资讯详情

前沿编程新知与开发实战干货的深度解读。

AI原生鸿蒙应用开发实战:从会议助手看系统AI与意图框架

AI原生鸿蒙应用开发实战:从会议助手看系统AI与意图框架 “AI原生鸿蒙应用开发实战”这个词最近我被好几个朋友追着问。说起来也不怪鸿蒙生态发展到这个阶段已经陆续出现一批带着明显“AI原生感”的应用你打开一个会议工具它能在你说话的过程中实时提炼关键结论把待办事项自动整理成结构化卡片而不是等你录完音再手动丢给某个大模型对话框。这类体验靠的不是在App里简单塞一个聊天机器人而是系统级AI能力的全面开放。这篇文章我拿自己做的一个“会议录音整理助手”Demo说事讲讲我理解的AI原生鸿蒙开发到底是什么、怎么接入系统AI能力、意图框架怎么用以及真机调测时踩过哪些坑。适合三类人看准备转鸿蒙原生的移动端老手、想落地端侧AI应用的产品或开发同学、还有纯粹对“系统级智能”怎么工作感兴趣的技术爱好者。不同基础都能找到自己能上手的那一段。1. 先搞清“AI原生”到底指什么1.1 AI原生不是“应用里接了个大模型API”以前大家做AI功能基本套路是应用内置某个SDK把用户数据传到云端等大模型返回结果再渲染到界面上。这种模式有两个绕不开的痛一是时延和网络不可控二是数据隐私边界模糊。我把这种叫“外挂式AI集成”因为AI能力和操作系统、设备能力是完全割裂的应用像个“管道工”自己拉水管到水库还得自己维护管道。AI原生的思路完全相反。系统层面就内置了智能调度与推理能力应用通过标准化的系统接口去调用而不是自己打包模型或对接第三方SDK。可以类比成市政管网入户你不需要挖井不需要修水塔拧开水龙头就有水。区别只是这个水龙头背后是系统级算力调度、端侧模型推理、意图感知、隐私合规这些一整套基础设施。以鸿蒙为例AI原生应用可以调用的资源包括设备上的NPU算力、系统预置的语音识别与文本处理能力、系统级智能助手预留的交互入口、以及基于用户场景的意图框架。这些能力不是某个App私有而是所有应用在同一套系统服务框架下按标准接口使用。用户的感知是AI功能变得更加“无感”不用打开某个App去点“生成摘要”而是在合适的时间、合适的位置系统主动把结果送过来。1.2 鸿蒙AI能力体系的四层结构我习惯把鸿蒙的AI能力体系分成四层从底到上分别是算力资源层、能力服务层、意图感知层、交互呈现层。这样分的好处是遇到问题时能快速定位是哪一层出了bug而不是头痛医头。算力资源层是硬件底座包括CPU、GPU、NPU以及统一调度这些算力的运行时。开发者通常不直接碰这一层但需要理解端侧推理为什么能在手机上实时跑。能力服务层把算力封装成具体能力比如语音转写、图像OCR、文本翻译、文本摘要、内容审核等开发者按能力维度去调用不用关心模型文件和管理或手工做算子适配。意图感知层负责理解“用户现在想干什么”比如用户正在开会、正在开车、正在看英文文章系统通过上下文判断是否需要某个App的某项能力。交互呈现层则是用户实际看到的形态包括系统级建议卡片、语音驱动、胶囊/气泡等。开发者接触最多的是能力服务层和意图感知层。前者解决“AI能力怎么用”后者解决“AI能力怎么被系统在合适的场景下唤醒”。大多数传统开发者对能力服务层都不陌生但意图感知层是鸿蒙这一类系统级AI最特殊的地方也是从“AI应用”走向“AI原生应用”的分水岭。层级核心作用开发者接触点典型场景交互呈现层AI结果的系统级展示智能卡片、语音播报、胶囊会议结束后的摘要卡片意图感知层理解场景并发起能力调度意图注册、场景订阅开会时系统建议“开始记录”能力服务层封装并开放AI算法能力统一AI能力调用接口语音转写、文本摘要算力资源层NPU/CPU/GPU统一调度间接感知通过API端侧推理加速1.3 什么样的应用适合走AI原生路线不是所有应用都需要接入系统AI能力。我最开始也想做一个“大而全”的智能助手但做到后面发现AI原生开发适合的场景有明显的边界。适合的典型特征有三个第一功能本身强依赖设备端实时处理比如录音转写、实时翻译、取词翻译这类场景对时延敏感走云端会明显卡顿。第二用户数据带有明确的隐私属性比如会议内容、健康记录、相册照片端侧处理能让用户更放心。第三存在明确场景连续性比如一个“整理会议纪要”的动作可以在多个入口触发需要系统级建议和语音指令配合。不太适合的场景也有几种需要完全自定义与私有模型的行业应用、对模型精度要求极高且端侧模型满足不了的场景、必须在服务端统一审计和留痕的业务。这种时候硬接系统AI能力反而不划算。判断原则很简单看你的核心价值在算法本身还是在算法带来的体验整合。如果前者的权重更高自己部署模型如果后者权重高优先拥抱系统能力。2. 环境准备把AI开发链路先打通2.1 DevEco Studio与SDK版本选择AI原生开发对开发工具有一些特定的要求。默认下载的DevEco Studio不一定会带上完整的AI能力SDK至少我拿到手的版本就属于“基础开发工具”需要在SDK管理器里额外勾选与AI能力相关的组件。建议你在创建工程之前先把SDK配置好别等到写代码时才发现缺包。API版本的选择很关键。我个人的体验是AI相关接口在旧版本上不太稳定尤其是意图框架和端侧模型会话管理这类能力很多细节都是在高版本里补全的。如果你手头没有特殊限制API版本尽量往高选能在一定程度上避开早期实现的坑。有同行反馈用旧版本编译时能过但真机上运行时经常报“能力不支持”升级API后问题消失这类情况我遇到的不是一次两次。配置时还要留意开发者调试证书。基础开发证书和应用市场发布证书的权限范围不同AI能力往往涉及敏感权限调试证书必须勾选对应能力项否则真机上调用系统AI接口会被直接拒绝。有一个比较隐蔽的点即使你的代码写了动态权限申请如果证书没有勾选对应系统能力错误也会表现为“权限不足”而不是“能力不存在”排查时容易误判方向。2.2 真机调测系统AI能力只在真机上完整可用模拟器和真机的差异在AI原生开发里比普通应用开发大得多。普通应用在模拟器上跑界面布局、逻辑流转基本一致但系统AI能力高度依赖设备端硬件与系统服务模拟器上很多能力实际上是不可用的。我遇到过的情况是模拟器上调用语音转写接口正常返回但结果是空的调用文本摘要进程直接报超时。一开始以为是代码问题换到真机上一模一样的代码功能正常。后面才弄明白模拟器本身没有对应的端侧模型和NPU调度服务接口存在但底座缺失所以给了“看起来能用实际用不了”的错觉。建议开发阶段把AI相关功能单独做成一个模块所有系统能力调用都通过这个模块转发这样可以在非AI功能调试时使用模拟器AI相关功能切到真机验证。模块化还有一个额外好处当你需要mock数据或做自动化测试时可以直接替换掉底层实现不需要动业务代码。真机调测时还要注意设备本身的“AI能力服务”是否开启。部分设备在设置里提供了AI能力总开关比如“智能服务增强”这类选项。如果关闭了应用侧调用任何AI能力都会失败。测试前养成习惯先确认系统AI开关状态再排查应用代码能省去大量无效定位时间。2.3 新建项目时要注意的3个关键配置第一个关键配置是Module里的依赖声明。AI能力的相关Kit需要以显式依赖方式加到工程中不是只在代码里引入头文件/类型定义就能用。官方文档中一般会写明依赖包名建议直接复制避免手拼时出现版本不匹配。这里有一个易错点IDE提示的自动补全不一定可靠有时它会自动引入一个很旧的依赖版本编译能过但运行时接口行为不一致。第二个关键配置是module.json5里的权限与能力声明。普通应用申请麦克风权限只需要在requestPermissions里加麦克风条目但AI原生应用往往还需要额外的“系统能力声明”。不同能力对应的声明项不一样比如语音识别和文本生成所需的声明就不相同。我习惯在新建项目时先把用到的能力列成清单逐项比对文档防止漏声明。第三个关键配置是应用元数据里的AI服务开关。有些系统AI能力需要应用在配置文件中声明“本应用需要使用系统AI服务”并指定服务类型。这个开关不在权限列表里而是通过metadata字段配置。如果不做这一步代码里的会话创建请求会被系统静默丢弃日志里没有任何异常提示排查难度非常高。这三个配置有个共同特点错一个不报编译错误只在运行时表现为各种“灵异现象”。所以我把它们单独拎出来讲值得在项目初期就一次配好。3. 实战从零做一个会议录音整理助手3.1 功能拆解与架构方案我做的“会议录音整理助手”Demo目标场景是用户进入会议室后点一下“开始记录”App在后台采集音频实时转写文本会议结束后系统自动生成摘要、结论、待办事项并且生成一页可分享的纪要。整个功能拆解为五个环节音频采集、语音转写、文本分段、摘要生成、结构化输出。其中音频采集走系统麦克风能力语音转写和摘要生成走系统AI能力文本分段和结构化输出可以自己写逻辑用规则匹配来完成。架构上采用横向分层UI层负责录音界面和结果展示服务层管理录音会话、转写会话、摘要会话的生命周期能力层封装系统AI调用与系统建议卡片数据层处理纪要本地存储。这个方案有几个刻意的设计选择。第一语音转写采用分段式流式处理每30秒截断一次文本并送入转写会话避免一次性处理长音频导致的内存压力。第二摘要生成放到会议结束后统一执行不在实时转写过程中占用推理资源。第三把“生成待办”单独做成一个意图动作注册到系统意图框架中让用户除了在App内点按钮也能通过语音指令和系统建议卡片触发。3.2 端侧AI能力的接入流程在鸿蒙的AI原生开发体系里系统能力调用的大致流程是创建会话、配置能力参数、执行推理、解析结果、释放会话。整个过程以异步为主和自然语言模型服务商的API风格比较接近但不需要自己管理API Keys和网络状态。我摘一段实际开发中最核心的调用逻辑以“文本摘要”能力为例用尽量接近SDK风格的写法示意// 伪代码示例实际包名与类型名以你的SDK版本为准 import { AI } from harmony-ai-kit; const session await AI.createSession({ capability: AI.Capabilities.TextSummarization, modelConfig: { paramSize: 1.5, // 尽量选择轻量模型 quantization: true, // 开启量化以降低内存占用 }, }); const result await session.execute({ text: meetingText, maxSummarizedLength: 300, }); if (result.errorCode 0) { const summary result.data.summarizedText; console.log(摘要结果:, summary); } else { console.error(摘要失败:, result.errorMsg); } await session.release();几个容易踩的点createSession是一个异步操作必须在UI任务里和耗时操作区分开不要在onPageShow这类生命周期回调里同步等待。session尽量复用不要每条文本都创建新会话。createSession本身可能触发模型加载耗时可能几百毫秒到数秒不等如果每次都新建再释放用户能明显感到界面卡顿。如果你的应用在一段录音里连续多次调用文本理解能力建议把session池化就是创建2到3个会话实例循环复用而不是用完即弃。有几个比较费时的等待是模型加载和热启动复用能有效降低等待时间。会话释放也很重要系统对并发会话数有限制不及时释放后面会报“超出最大会话数”的错误。3.3 意图框架的注册与触发意图框架是AI原生开发和传统AI应用差异最集中的地方。它要解决的核心问题是系统怎么知道“你的应用能做什么”以及“在什么场景下应该唤起你”。没有这个框架应用只能被动等待用户打开有了它应用可以主动出现在用户的智能流程中。以我的会议助手为例我注册了一个“开始会议记录”的意图。用户在语音助手中说“帮我记录会议”系统会匹配到这个意图并唤起我的应用进入记录模式。用户也可以在下拉通知栏或桌面智能助手的建议卡片中看到“开始会议记录”的快捷入口。这种体验的核心价值在于用户不需要进入到App内部去找录音按钮而是由系统根据场景主动提供入口。注册意图通常要有一个配置文件声明意图名称、触发域、目标Ability、参数约束等。这里的难点不是写配置而是梳理清楚“你的应用能承接哪种用户意图”。切入视角要站在系统侧系统看到一个场景需要判断“这件事谁来做最合适”——你的应用必须让这一步识别成为可能。{ intents: [ { domain: productivity.meeting, name: startMeetingRecord, targetAbility: MeetingRecordAbility, triggerSource: [assistant, suggestionCard], parameters: { meetingTitle: { type: string, required: false } } } ] }注册完意图之后还要在目标Ability中处理意图参数根据参数决定启动后的行为。如果参数里带了会议标题直接预填到界面上如果没带进入默认的录音等待状态。意图框架的联调有点考验耐心因为它依赖系统级组件响应真机上有时延迟比较明显。一个可尝试的调试技巧先在系统助手的测试指令里输入你注册的示例意图确认能稳定唤起后再在真实会议场景里去测试场景触发。3.4 界面与交互的实现要点AI原生应用的界面比普通应用更注重“状态反馈”。录音转写过程中用户需要看到音频采集仍在进行转写文本在实时滚动摘要结果在生成中这几个状态都要有明确UI反馈否则用户会怀疑App是否卡死。用状态机驱动UI是比较清晰的做法idle、recording、transcribing、summarizing、completed每个状态对应用户可见的控件形态。实时转写文本流使用滚动列表呈现时需要关注列表性能。如果每30秒一段转写内容会不断增加直接往List容器里追加节点会导致滚动抖动。我的做法是限制显示区内的最大文本块数量超过后自动折叠早期内容只保留首屏可见的最新几段。用户查看历史内容时再点击展开这个交互既保证了实时性又不会拖垮UI线程。摘要结果展示也不建议单纯用一段文字堆到底。我做了三类卡片主题摘要、结论列表、待办事项。结论和待办从摘要结果中做二次结构化提取这一步可以用规则匹配比如识别以“决定”“确认”“下一步”开头的句子进入对应分组。虽然不如大模型理解得那么智能但胜在稳定可控且不依赖额外AI调用。麦克风权限请求要提前到用户第一次进入录音界面时就开始。应用试图在用户点“开始记录”之后再弹权限请求会打断操作流程。我在业务代码里做了预请求逻辑用户初始化界面时就触发系统权限确认同时通过界面文案解释权限用途尽量降低用户拒绝概率。实测下来提前请求的授权率远高于使用时请求。4. 性能优化与端侧模型调优4.1 为什么优先端侧算力端侧推理在AI原生应用里的权重非常高核心原因有三点隐私、时延、可用性。隐私层面会议摘要这类场景用户不希望原始录音内容被传上云端处理端侧推理让原始音频只停留在设备本地隐私边界清晰。时延层面即便网络条件很好云端往返也要消耗几百毫秒而端侧推理一旦模型加载完成处理器是纳秒级的在实时语音转写场景下体验差距非常明显。可用性层面端侧模型不依赖网络信号在地下室、电梯里也能正常完成推理这类场景虽然不高频但属于“关键时刻不掉链子”。鸿蒙的端侧推理框架会尝试把模型调度到NPU上运行但并不是所有算子在NPU上都有对应的实现。如果模型里含有不支持的算子系统会自动回退到CPU执行速度就会明显下降。一个实用的检测手段是看日志里session创建和执行阶段是否有“算子回退”提示如果某个算子频繁回退可以考虑换模型版本或调整预处理逻辑。4.2 模型加载与内存优化端侧模型相比传统模块更吃内存。我用的文本摘要模型量化后大约几百MB虽然比云端动辄几十GB的模型轻很多但在内存有限的设备上仍然是需要精细管理的资源。如果不做控制多开几个会话内存直接报警。第一条优化是延迟加载。不要在应用启动时就把模型加载到内存而是等到用户真正需要执行摘要时再创建会话。冷启动模型会有一段明显的等待期要配合Loading动效或进度条而不是让界面静止不动。第二条优化是及时释放。会话一旦执行完成如果之后一段时间内不会再使用就主动调用release接口释放模型占用的内存而不是等到系统来回收。第三条优化是控制并发。同一时间尽量只保留一个端侧模型会话避免多个大模型同时驻留内存。文本长度的控制也很重要。输入给摘要模型的文本长度会直接影响推理耗时和内存峰值。我在调用前会做文本裁剪把会议转写内容按重要程度分段优先保留含有关键词的段落。比如包含“决定”“问题”“风险”“日期”的句子加权保留其余长段落按比例截断。这个方法在低成本前提下有效控制了模型输入长度摘要质量基本不受影响。4.3 时延、功耗、并发三种场景的平衡端侧AI优化没有一个万能参数更多是在不同场景下做权衡。实时转写要求低时延所以推理请求要频繁模型常驻内存功耗会升高。会议结束后的摘要生成不要求实时性可以采用低功耗模式让推理请求排入系统空闲队列避免和用户操作抢资源。我的做法是设置一个“优先级档位”录音转写过程中AI能力上下文优先级设为高保证转写流畅录音结束后自动切为低优先级摘要生成采用延迟触发等用户离开当前页面或App退到后台后再静默执行。这样用户感知不到摘要生成的等待功耗曲线也更平滑。并发方面同时跑转写和摘要会话是不推荐的一方面算力资源争抢严重另一方面内存压力可能触发系统清理。合理的方式是串行化先完成录音转写再启动摘要会话。这个过程在业务代码里用任务队列实现按序处理避免并发冲突。5. 常见问题与排坑实录5.1 权限、签名与配置问题速查故障现象可能原因处理思路调用AI接口返回“权限不足”证书未勾选系统能力项检查开发证书权限配置重新签名接口无异常但结果为空系统AI能力总开关关闭检查设备设置中的AI能力开关创建会话超时设备首次使用需下载模型预留网络时间增加等待提示日志提示“超出最大会话数”会话未释放或并发超限检查完整生命周期增加复用机制模拟器上报不支持错误模拟器缺少端侧模型底座切换到真机联调遇到这一类问题我有个固定的排查顺序先看设备系统设置再看应用权限再看签名证书最后才怀疑代码。因为配置类问题的报错信息经常是延迟出现或误导性的直接看代码容易绕远路。5.2 模型加载失败的真实原因端侧模型的加载失败大部分不是应用代码的问题而是设备侧环境的问题。最常见的是首次使用需要联网下载模型如果下载被系统中断后续再调用时会出现“模型文件不完整”的错误。这种情况需要在系统AI能力管理界面手动触发重新下载或者在应用内提示用户“模型未准备好请检查网络后重试”。存储空间不足也会导致加载失败但报错文案往往写作“模型加载失败”从表面看根本想不到是磁盘问题。排查时留意一下设备剩余空间至少要预留1GB左右给系统AI能力使用。部分老设备上NPU支持有限也会加载失败。我的建议是在应用首次启动检测设备能力等级对能力较差的设备自动采用更低功能版本而不是把所有流量都打到一个标准能力上。5.3 模拟器与真机的行为差异模拟器和真机的行为差异前面已经提到过一部分这里补充几个实际联调中很麻烦的差异点。模拟器上时间基准和真机不同导致部分AI能力返回结果的时间戳格式不一致如果应用里做了时间计算可能会出现负数间隔。模拟器的系统AI服务版本不一定真实反映真机状况即使是最新模拟器也存在缺失部分能力的情况。遇到这类问题我的建议是把模拟器定位为“UI与业务逻辑调试工具”AI能力联调一律走真机。同时为了能早期发现问题在开发环境里给AI调用模块增加一个Mock模式返回预设数据。这样即使没有真机在身边也不影响界面开发和流程验证等拿到真机后再单独联调AI能力。Mock模式的额外好处是便于自动化测试避免测试环境不稳定影响CI流程。5.4 版本兼容性API版本与设备能力差异同一套代码在不同设备上运行表现可能完全不同。有些设备系统版本较低AI能力接口存在但行为不一致比如返回字段的命名差异、错误码定义差异。建议在所有AI能力调用前先使用系统能力判断接口检查当前设备是否支持该能力并在不支持时提供降级路径。我在项目里抽象了一个“能力管理”模块集中判断支持项。核心逻辑是列出应用依赖的所有系统AI能力逐一检测把不支持的设备自动切换到降级方案。比如文本摘要能力不支持时降级为本地规则抽取意图框架不支持时隐藏系统建议卡片入口只保留应用内按钮。这套机制实现起来不复杂但对体验提升非常明显。还有一点容易被忽略系统AI能力的版本可能随系统升级变化同一型号设备在不同系统版本下能力表现不同。上线前的兼容测试至少要覆盖目标用户群体中主流的几个系统版本不要只用自己开发机验证就发版。6. 一些更深度的个人体会6.1 别急着上大模型先吃透系统已有能力我刚做这个Demo时第一反应是找大模型服务方部署一个私有会议摘要模型。但动手做选型评估后发现系统已有的文本摘要能力在会议纪要场景下完全够用还省掉了模型训练、部署、鉴权、计费这一整套后勤包袱。我的体会是AI原生开发的第一步不是“变得更强”而是“减少重复造轮子的冲动”。系统能力覆盖不了的场景再考虑私有部署覆盖得了的场景优先用系统能力这个顺序能帮你快速交付第一版。6.2 把AI能力封装成可替换模块AI能力最大的特点是迭代快。今天系统提供的摘要能力可能过两个版本就有了新的替代方案。如果业务代码里到处直接调用系统接口后面替换工作量会非常大。我的做法是所有AI调用统一封装在AbilityService层暴露给业务侧的方法名完全不带系统API特征。后续即使把系统摘要换成自研模型业务层代码可以原封不动只需要替换封装层内部实现。6.3 下一步的扩展思考做完第一版Demo后我尝试把会议纪要流转到平板上看发现分屏状态下摘要卡片和转写文本可以天然形成“左侧原始材料、右侧结构化结论”的布局。再往后可以基于意图框架把“记录会议”扩展到更多触达场景比如耳机语音按键、手表快捷指令。从这套基础能力往上发展我觉得方向在于“AI能力与系统场景的编排”而不是追逐更大的模型。这也是AI原生开发区别于传统开发的真正魅力所在它考验的不只是算法和模型而是对整个系统上下文的理解与组合能力。
返回列表