鸿蒙图片检索最佳实践

更新时间: 2026/09/04 17:59:48

本文主要介绍鸿蒙 AI 能力在 OCR 与视觉语义检索中的应用。

概述

云信 IM HarmonyOS SDK 自 V10.11.0 起,接入鸿蒙 AI 能力用于本地消息搜索。

鸿蒙图片搜索的价值,不在于增加一个图片筛选入口,而在于把系统 AI 能力转化为可组合、可解释、可恢复的消息检索能力。系统 OCR 负责理解图片中的文字,HarmonyOS Core Vision 负责理解图片表达的画面语义,统一的消息搜索入口再把 AI 命中结果映射回原始会话消息。业务不需要自建图片语义服务,也不需要维护独立的图片搜索数据库。

因此,用户可以在同一个会话搜索体验中完成三件事:

  • 按消息文本搜索
  • 按图片内文字搜索
  • 按画面内容搜索

本文围绕这项鸿蒙特性,说明三种来源如何协同、需要哪些 HAR 和 Service 配置,以及接入后页面和搜索结果应呈现的效果。

产品形态

在会话图片页中,用户可以浏览消息、输入关键词并选择 文本图片文字画面内容;结果页回到原始会话消息,并标出每张图片的命中来源。

图片检索

上图中的三个状态分别对应:

状态 说明
浏览态 默认展示会话图片库存,保留原有预览和消息操作
输入态 用户输入关键词,并可组合 图片文字画面内容 两个 AI 来源
结果态 结果直接映射回会话图片消息,同时展示命中来源;同一张图片被多个来源命中时只展示一次

把这个页面效果映射到三个搜索来源,就很直观:

页面操作 用户意图 实际能力 典型结果
选择 文本 找包含某个词的消息 本地文本检索 消息正文或标题命中
选择 图片文字 找图片里出现的字 鸿蒙系统 OCR 白板、截图、文档照片命中
选择 画面内容 找图片表达的场景 鸿蒙 Core Vision 视觉语义 冲浪、会议现场、咖啡等画面命中

例如,搜索 会议白板 时,OCR 命中的是图片中确实出现的文字;搜索 海边冲浪 时,VISUAL 命中的是海浪和冲浪板等画面语义;搜索 项目排期 时,普通文本检索继续查找消息正文。三种结果可以在同一个页面中呈现,但命中原因必须分别标识。

搜索类型

消息文本:搜索已有内容

普通文本搜索面向消息正文、标题等已有文本字段,复用原有的本地全文检索能力。它适合搜索 项目排期周报 这类消息文本,也可以继续使用原有的会话范围、时间范围和分页语义。

图片文字:搜索 OCR 内容

OCR 回答的是 这张图片里有没有这几个字。例如,用户搜索 7319,命中的是一张包含该编号的截图;搜索 会议纪要,命中的是拍摄的白板照片。

在鸿蒙上,这条链路使用系统提供的文字识别能力。图片下载到本地后,SDK 异步识别图片,保存识别出的文本层级和布局元数据,再对归一化后的文字建立本地索引。查询阶段只查索引,不在每次搜索时重新扫描全部图片。

画面内容:搜索视觉语义

视觉语义搜索回答的是 这张图片表达了什么。例如,搜索 海边冲浪 可以召回画面中有海浪和冲浪板的图片;搜索 办公室白板 可以召回会议现场照片。

这条链路使用鸿蒙 Core Vision 的图像语义搜索能力,由系统负责图片特征和模型实现。SDK 只负责把图片纳入系统索引、发起查询并把结果映射回消息,不依赖或暴露系统内部的特征存储结构。

OCR 和视觉都接收文字 Query,但语义不同——OCR 是字面匹配,VISUAL 是跨模态语义召回。不能 用视觉搜索替代 OCR,也 不能 把 OCR 命中伪装成视觉相似度。

三合一统一入口

业务侧不需要分别调用文本搜索 API、OCR API 和视觉搜索 API。统一入口是 searchLocalMessages,来源通过位标志精确表达:

来源 位值 含义 鸿蒙能力依赖
TEXT_RECOGNITION 1 普通消息文本 SDK 本地文本索引
OCR 2 图片内文字 系统文字识别能力
VISUAL 4 图片画面语义 API 26 + 可选视觉 HAR + Core Vision

三个位可以任意组合,共支持七种非空组合。缺省 searchTypes 时保持原行为,只执行普通文本搜索;显式传入 0 或未知位则直接返回参数错误,避免调用方误以为 没有来源 代表 搜索全部

flowchart LR
    A[业务搜索框] --> B[searchLocalMessages]
    B --> C[普通文本索引]
    B --> D[OCR 本地索引]
    B --> E[Core Vision 视觉索引]
    C --> F[按 messageClientId 去重]
    D --> F
    E --> F
    F --> G[统一消息结果 + 实际命中来源 + 视觉相关性]

统一入口的价值不只是 API 数量更少,更重要的是把 请求来源实际命中来源 分开表达。调用方传入 searchTypes 表示希望执行哪些来源;每条结果通过 matchTypes 表示它实际被哪些来源命中。同一张图片同时被 OCR 和视觉命中时,只返回一条消息,并把两个位合并到 matchTypes 中。

搜索能力配置

只在页面里调用 searchLocalMessages,并不代表图片搜索已经生效。HarmonyOS NIM SDK 的业务能力采用 业务 HAR + 服务注册 + 服务配置 的装配方式,三个环节缺一不可。

引入对应 HAR

普通文本和 OCR 至少需要引入核心搜索 HAR:

json5{
  "dependencies": {
    "@nimsdk/nim": "10.11.0",
    "@nimsdk/base": "10.11.0",
    "@nimsdk/message": "10.11.0",
    "@nimsdk/search": "10.11.0"
  }
}

如需启用画面语义搜索,在 API 26 宿主中增加可选视觉 HAR,并保持所有 NIM HAR 使用同一个版本号:

json5{
  "dependencies": {
    "@nimsdk/search": "10.11.0",
    "@nimsdk/aivision": "10.11.0"
  }
}
  • 本文使用的 10.11.0 是图片搜索能力开始支持的 SDK 版本。接入时应将 NIM 相关 HAR 统一到 10.11.0,避免核心 SDK、搜索服务和视觉 HAR 版本不一致。
  • @nimsdk/aivision 的构建目标是 API 26。

注册搜索服务与 AIVision Service

业务 HAR 引入后,必须在创建 NIM 实例前注册真实实现。AIVisionServiceImpl 按普通业务 Service 注册。

tsimport {
  NIMServiceOptions,
  V2NIMProvidedServiceType
} from '@nimsdk/base'
import { NIMSdk } from '@nimsdk/nim'
import { V2NIMSearchServiceImpl } from '@nimsdk/search'
import { AIVisionServiceImpl } from '@nimsdk/aivision'

NIMSdk.registerCustomServices(
  V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_SEARCH,
  (core, serviceName, serviceConfig) =>
    new V2NIMSearchServiceImpl(core, serviceName, serviceConfig)
)

NIMSdk.registerCustomServices(
  V2NIMProvidedServiceType.V2NIM_PROVIDED_SERVICE_AIVISION,
  (core, serviceName, serviceConfig) =>
    new AIVisionServiceImpl(core, serviceName, serviceConfig)
)

const serviceOptions: NIMServiceOptions = {
  searchServiceConfig: {
    searchAccountIdEnabled: true
  },
  messageServiceConfig: {
    imageTextRecognitionSearchEnabled: true,
    imageVisualSemanticSearchEnabled: true
  }
}

const nim = NIMSdk.newInstance(context, initializeOptions, serviceOptions)

注册顺序很重要:先注册搜索服务和 AIVision Service,再调用 NIMSdk.newInstance

打开 OCR 与视觉开关

两个开关对应两个独立 Runtime:

开关 说明
imageTextRecognitionSearchEnabled: true 允许 SDK 建立和查询 OCR 索引
imageVisualSemanticSearchEnabled: true 允许 SDK 使用视觉语义搜索能力

关闭其中一个开关只关闭对应来源,不会影响普通文本或另一个来源。推荐在产品配置中显式写出两个开关,而不是依赖默认值,这样线上排查时可以直接确认 是未开启、未装配,还是系统能力不可用

完成上述三步后,普通文本和 OCR 搜索即可由核心搜索服务处理。要启用画面语义搜索,还需要在 API 26 宿主中引入并注册 AIVision 业务服务,同时打开视觉语义搜索开关。

建立索引

图片搜索依赖图片先完成本地化,但不需要等待全部图片完成索引。附件落盘后,SDK 会在后台异步建立 OCR 和视觉索引;查询只读取已经完成的对应索引,首次结果可能随索引进度逐步补充。

推荐的生命周期是:

  1. 图片附件完成下载并落盘,得到可访问的本地绝对路径。
  2. 消息生命周期通知 SDK 图片路径已就绪。
  3. OCR 和视觉分别提交自己的索引任务。
  4. 任务状态持久化,支持重试、对账和恢复。
  5. 用户发起搜索时,读取已经完成的对应索引,后台任务继续处理剩余图片。

如果业务使用自定义下载器,不能只修改内存中的 attachment.path。文件真正落盘后,应调用 SDK 提供的 本地附件路径已就绪 更新入口,让消息生命周期继续触发索引。这样可以避免应用重启后索引丢失,也能保证重复通知不会生成重复任务。

OCR 与视觉共享图片到消息的绑定关系,但索引状态、任务代次和失败恢复彼此独立。视觉模型需要重建时,不应清理 OCR 数据;OCR 初始化失败时,也不应阻塞普通文本和视觉搜索。

构造搜索参数

当请求包含 OCRVISUAL 时,查询必须限定在一个会话内,并传入 1 至 5 个非空关键词:

tsconst result = await messageService.searchLocalMessages({
  conversationId,
  keywordList: ['会议', '白板'],
  keywordMatchType: V2NIMSearchKeywordMathType.V2NIM_SEARCH_KEYWORD_MATH_TYPE_OR,
  messageTypes: [V2NIMMessageType.V2NIM_MESSAGE_TYPE_IMAGE],
  searchTypes: V2NIMMessageSearchType.OCR |
    V2NIMMessageSearchType.VISUAL,
  limit: 50
})

重要约束

约束 说明
keywordList 必须包含 1 至 5 个 trim 后的非空关键词
keywordMatchType 支持 ORAND,用于控制多关键词关系
limit 范围 1...100
messageTypes 显式传入时必须包含图片消息类型
不支持过滤 OCR/视觉请求不支持仅适用于普通 FTS 的发送者、方向、子类型和非零时间范围过滤

分页约束

  • 分页时必须原样传递上一次结果返回的 nextPageToken
  • 修改关键词、来源或会话后必须从首页重新搜索
  • 不要先截取视觉搜索结果,再在业务层做二次过滤,这会造成漏召回。

普通文本请求则继续保留原有多关键词、时间范围、分页和搜索策略语义。两类请求的参数规则不同,业务层最好根据 searchTypes 做一次明确的请求构造,而不是复用一个 万能参数对象

搜索结果

图片搜索的结果不应该只有缩略图和标题。至少要展示两类信息:

  • 命中来源:文本、图片文字、画面内容,可同时展示多个标签。
  • 视觉相关性:只有真实视觉命中时才展示 visualSimilarity不能0 代表 没有视觉命中

当所有请求来源都不可用时,搜索调用会以错误结束,错误详情用于说明具体原因;单个来源不可用时,其他可用来源仍可返回真实结果。

搜索效果

完成 HAR、注册和配置后,业务页面仍然只需要调用统一的 searchLocalMessages。变化发生在 SDK 内部和结果模型中,而不是业务层增加一套新的图片数据库或额外搜索调用。

以会话 项目讨论 为例:

用户输入 选择来源 典型命中 页面应展示
会议白板 图片文字(OCR) 白板照片中识别出的文字 图片缩略图 + 图片文字 标签
海边冲浪 画面内容(VISUAL) 海浪、冲浪板等画面语义 图片缩略图 + 画面内容 标签 + 视觉相关性
会议白板 图片文字 + 画面内容 同一张图片被两个来源共同命中 只展示一张图片 + 两个命中标签
项目排期 普通文本 消息正文或标题 原有文本搜索结果

实际使用时,图片不会在用户点击搜索按钮的瞬间才开始处理。附件落盘后,SDK 会在后台建立派生索引;组合查询中某一个来源不可用时,其他可用来源仍可返回结果。

这也是 接入成功用户体验生效 的区别:

  • 接入成功:HAR 已引入、服务已注册、开关已打开,NIM 实例能够识别并调度对应来源。
  • 体验生效:图片已经有本地路径、索引任务已经完成,查询结果包含真实的 matchTypes,页面能解释命中来源。
此文档是否对你有帮助?
有帮助
去反馈
  • 概述
  • 产品形态
  • 搜索类型
  • 消息文本:搜索已有内容
  • 图片文字:搜索 OCR 内容
  • 画面内容:搜索视觉语义
  • 三合一统一入口
  • 搜索能力配置
  • 引入对应 HAR
  • 注册搜索服务与 AIVision Service
  • 打开 OCR 与视觉开关
  • 建立索引
  • 构造搜索参数
  • 搜索结果
  • 搜索效果