查看: 232|回复: 3

鸿蒙拍小票记账:端侧OCR与多模态意图框架整合实践

[复制链接]
发表于 9 小时前 | 显示全部楼层 |阅读模式
在鸿蒙生态中,应用智能化远不止在界面塞一个聊天框接大模型。真正有价值的智能化,是让系统级AI能力、云端大模型和意图框架协同工作,让用户无需手动打开应用就能完成操作。本文以完整实现的「智慧收据管家」为例,拆解如何利用Core Vision Kit端侧OCR、阿里百联多模态大模型(qwen-vl-plus)以及意图框架(Intent Framework)来实现拍小票记账功能。

一、为什么选“拍小票记账”作为智能化载体
这个场景恰好触及系统AI与云端大模型的边界:文字提取是系统端侧OCR的强项(离线、隐私好),但语义理解(如判断“金龙鱼”属于餐饮还是购物)则是多模态大模型的长处。同时,记账有高频、低认知负担诉求,适合用意图框架让语音助手直接调度。

二、第一层:系统AI能力——Core Vision Kit端侧OCR
鸿蒙的Core Vision Kit内置通用OCR,运行在设备本地,不联网、图片不出设备。调用链路简化为:图片→PixelMap→文字识别→释放资源。注意必须将图片转为RGBA_8888格式的PixelMap,且显式调用source.release()避免内存堆积。示例代码封装在VisionService中:
  1. import { textRecognition } from '@kit.CoreVisionKit';
  2. import { image } from '@kit.ImageKit';
  3. export interface OcrResult {
  4.   ok: boolean;
  5.   text: string;
  6.   error: string;
  7. }
  8. export class VisionService {
  9.   static async uriToPixelMap(uri: string): Promise<image.PixelMap | null> {
  10.     try {
  11.       const source = image.createImageSource(uri);
  12.       const pm = await source.createPixelMap({
  13.         desiredPixelFormat: image.PixelMapFormat.RGBA_8888
  14.       });
  15.       source.release();
  16.       return pm;
  17.     } catch (e) {
  18.       return null;
  19.     }
  20.   }
  21.   static async recognize(pm: image.PixelMap): Promise<OcrResult> {
  22.     try {
  23.       const visionInfo: textRecognition.VisionInfo = { pixelMap: pm };
  24.       const config: textRecognition.TextRecognitionConfiguration = {
  25.         isDirectionDetectionSupported: false
  26.       };
  27.       const result = await textRecognition.recognizeText(visionInfo, config);
  28.       const fullText: string = result.value;
  29.       if (fullText.trim().length === 0) {
  30.         return { ok: false, text: '', error: '未识别到文字,请重拍或手动输入' };
  31.       }
  32.       return { ok: true, text: fullText, error: '' };
  33.     } catch (e) {
  34.       return { ok: false, text: '', error: '文字识别失败,模拟器可能不支持OCR,建议真机运行' };
  35.     }
  36.   }
  37. }
复制代码
推荐使用系统Picker获取图片(`photoAccessHelper.PhotoViewPicker`)而非申请完整权限,实现最小权限。Core Vision Kit返回的是原始文本,需要自己解析。例如提取金额时使用关键词定位加多级兜底策略:先找“合计/应付/实付”等关键词所在行,再从中提取数字;若失败则取全文最后一个带¥/¥的数字。

三、第二层:云端大模型协同——多模态模型补足语义短板
端侧OCR无法处理语义分类,因此接入阿里百联的qwen-vl-plus多模态模型。图片通过Base64编码内嵌到请求中,利用鸿蒙的`util.Base64Helper`同步编码小体积图片。构造OpenAI兼容格式的content数组,包含image_url和text。提示词要求模型只输出结构化JSON,并限定分类枚举集合(餐饮、交通、购物等)。解析层使用“截取首尾大括号”技巧过滤模型偶尔输出的markdown包裹,每个字段用??默认值兜底。

真实案例:同一张小票(应付166.77元),AI识别为16677,因为热敏打印的小数点极小,模型将其忽略。这印证了“置信度”字段只是模型自我评估,最终必须交给人审——应用中的结果可编辑修正正是为此设计。

四、第三层:意图框架——让语音助手直接调度记账
default export class ReceiptIntentExecutor extends InsightIntentExecutor {
  async onExecuteInUIAbilityForegroundMode(
    name: string,
    param: Record<string, Object>,
    pageLoader: object
  ): Promise<insightIntent.ExecuteResult> {
    let message = '';
    if (name === 'QueryMonthSpending') {
      message = await this.doQueryMonth();
    } else {
      message = await this.doAdd(param);
    }
    AppStorage.setOrCreate('lastIntentMsg', message);
    AppStorage.setOrCreate('intentTick', Date.now());
    return { code: 0, result: { message: message } } as insightIntent.ExecuteResult;
  }
}
[/code]
意图执行器与UI不在同一生命周期,通过AppStorage跨上下文传递信息。为离线验证意图解析逻辑,应用内提供“模拟语音触发”入口,输入自然语言(如“记一下打车35元”)后本地关键词匹配解析参数并完成记账。本地规则匹配几乎零延迟,适合语音场景。

五、总结
鸿蒙应用智能化应遵循“确定性强、成本低的系统能力优先;大模型补足模糊地带;意图框架让能力被系统发现”的工程原则。端侧OCR+云端多模态+意图框架三层组合,既保证了隐私和离线可用性,又提供了语义理解的灵活性,最终实现“拍小票记账”的流畅体验。任何AI接入都应设计为“建议+确认”的协同模式,而不是自动化黑盒。
回复

使用道具 举报

发表于 8 小时前 | 显示全部楼层

Re: 鸿蒙拍小票记账:端侧OCR与多模态意图框架整合实践

非常好的技术分享!鸿蒙这套「端侧OCR+云端多模态+意图框架」的分层设计思路很清晰,把不同AI能力的边界和协作点都讲透了。尤其是金额提取时那个多级兜底策略,以及用截取大括号处理模型输出脏数据的小技巧,都是实战中容易踩坑但文档不会细说的细节。我比较好奇的是,在意图框架那层,语音助手触发记账后,如果用户想临时修改识别结果(比如AI误读金额),你们目前是在页面里直接提供编辑入口,还是打算通过对话式交互让用户口头修正?这个交互流程感觉对体验挺关键的。
回复 支持 反对

使用道具 举报

发表于 8 小时前 | 显示全部楼层

Re: 鸿蒙拍小票记账:端侧OCR与多模态意图框架整合实践

楼主的文章干货满满,尤其把端侧 OCR 和多模态大模型分工讲得很透彻。我比较好奇的是,在第三层意图框架里,语音助手调度记账时,用户如果拍了一张模糊的小票,系统是直接跳转应用让用户修正,还是能在语音交互界面里先给出初步结果让用户确认?这个流程体验如果处理不好,反而会增加用户的操作步骤。另外,阿里百联那个模型对小数点识别的问题挺典型,不知道你们在实际测试中有没有尝试过加一个后处理步骤,比如根据数字长度和常见金额范围做规则矫正?期待后续分享更多踩坑细节。
回复 支持 反对

使用道具 举报

发表于 8 小时前 | 显示全部楼层

Re: 鸿蒙拍小票记账:端侧OCR与多模态意图框架整合实践

这个方案分层设计得很清晰,尤其是把“端侧OCR提取文本”和“云端大模型理解语义”分开,既保隐私又补能力,思路很务实。 有个细节想请教:Core Vision Kit 的 `recognizeText` 返回的 `result.value` 是直接拼合全文,还是保持了行级结构?如果后续提取金额需要按行分析,是不是得自己再做一次行分割?另外,你提到阿里百联 qwen-vl-plus 在遇到热敏打印小数点时丢精度,这个倒是很真实的坑——目前你们是通过用户手动编辑兜底,还是考虑过在提示词里强制要求保留小数点位数,或者加一个后处理正则判断?(比如数字长度异常时自动补小数点) 意图框架那段看着挺简洁,`AppStorage` 传参确实比绑定复杂 UI 状态省心。不过 `onExecuteInUIAbilityForegroundMode` 返回 `code: 0` 后,如果用户不想跳转 UI 而是直接静默记账,是不是可以配置成不拉起前台?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

指导单位

江苏省公安厅

江苏省通信管理局

浙江省台州刑侦支队

DEFCON GROUP 86025

Hacking Group 021A

旗下站点

态势感知中心

应急响应中心

红盟安全

联系我们

官方QQ群:112851260

官方邮箱:security#ihonker.org(#改成@)

官方核心成员

关注微信公众号

Archiver|手机版|小黑屋| ( 沪ICP备2021026908号 )

GMT+8, 2026-7-13 20:03 , Processed in 0.029642 second(s), 18 queries , Gzip On, Redis On.

Powered by ihonker.com

Copyright © 2015-现在.

  • 返回顶部