# 家里老人说，把宝宝照片给我看看 # 智绘鸿蒙·如 7 而至#

## 前言

需求是我家老人提出来的，不是产品经理。她把平板递过来说"帮我找找宝宝在海边的照片"，我打开相册的搜索框，输入"宝宝 海边"，结果是空的。

这件事让我意识到：相册搜索对不会打字、不会组织关键词的人来说，是个负功能。他们脑子里是一句话，搜索框要的是一个词。

鸿蒙 7 的 Core Vision Kit 里有个端侧能力叫文搜图（`textSearchImage`），拿自然语言去检索本地图片。我们把它接到一个九张照片的小相册上，做了 15 条查询的命中率实验。**结论很反直觉：在这个能力上，"教用户输入关键词"是错的产品设计。**

## 实验怎么设的

相册 9 张图：3 张宝宝（海边玩沙、客厅沙发看书、公园草地跑）+ 6 张旅行照（海、雪、沙漠、森林、城市、古镇）当干扰项。全部用 `insertImage(path, 'family')` 建到同一个 scope。

15 条查询分四组，**每条的期望结果在跑之前就先写死**，避免事后找解释：

| 组 | 查询 | 期望命中的图 |
| --- | --- | --- |
| 主体词 | 宝宝 / 孩子 / 小孩 / 娃 | 任一 kid_* |
| 场景词 | 沙发 / 客厅 / 海滩 / 沙子 / 草地 / 公园 | 对应那一张 |
| 口语整句 | 宝宝在沙发上看书 / 孩子在草地上跑 / 把宝宝在海边的照片给我看看 | 对应那一张 |
| 干扰词 | 雪山 / 沙漠 | 对应旅行照 |

判定标准：返回结果的第一位是不是期望的那张图。

## 结果：8/15

| 组 | 查询 | 命中数 | 首位 | 相似度 | 耗时 |
| --- | --- | --- | --- | --- | --- |
| 主体词 | 宝宝 | 0 | — | — | 36ms |
| 主体词 | 孩子 | 3 | kid_park | 0.314 | 21ms |
| 主体词 | 小孩 | 2 | kid_park | 0.304 | 18ms |
| 主体词 | 娃 | 0 | — | — | 31ms |
| 场景词 | 沙发 | 0 | — | — | 31ms |
| 场景词 | 客厅 | 0 | — | — | 25ms |
| 场景词 | 海滩 | 2 | kid_beach | 0.317 | 31ms |
| 场景词 | 沙子 | 1 | kid_beach | 0.335 | 30ms |
| 场景词 | 草地 | 0 | — | — | 33ms |
| 场景词 | 公园 | 0 | — | — | 32ms |
| 整句 | 宝宝在沙发上看书 | 1 | kid_sofa | 0.364 | 38ms |
| 整句 | 孩子在草地上跑 | 1 | kid_park | 0.367 | 35ms |
| 整句 | 把宝宝在海边的照片给我看看 | 1 | kid_beach | 0.341 | 42ms |
| 干扰 | 雪山 | 1 | trip_snow | 0.332 | 29ms |
| 干扰 | 沙漠 | 0 | — | — | 28ms |

九张图建索引 3916ms，平均 435ms/张；单条查询 18~42ms。

## 结论一：单词会失败，整句能救回来

最关键的一组对比：

```
"沙发"            → 0 条
"宝宝在沙发上看书" → 命中 kid_sofa

"草地"            → 0 条
"孩子在草地上跑"   → 命中 kid_park
```

同一个场景、同一张图，把词换成句子就有了。这说明它不是关键词匹配，而是把整句编码成一个语义向量去比对——**信息量不够的时候，一个孤立的词反而落不到任何一张图上**。

对产品的影响非常直接：搜索框的占位文案不能写"输入关键词"，那是在教用户用一种会失败的方式输入。应该写"描述一下这张照片"，并且给一两个整句例子。

## 结论二：别做同义词表

"宝宝" 0 命中，"孩子""小孩" 有结果，"娃" 0 命中。第一反应是加同义词改写：宝宝 → 孩子。

但看结论一就知道这没用——问题不在词的选择，在于输入只有一个词。把"宝宝"改写成"孩子"，还是单词，大概率还是空。

真正该做的是**把句子补全**。我们试的三条整句全部命中，包括"把宝宝在海边的照片给我看看"这种带一堆废话（"把""给我看看"）的口语。也就是说这个能力对口语噪声是耐受的，用户不需要说"规范的话"。

所以产品上应该推的是输入引导，不是查询改写。

## 结论三：相似度绝对值不能用

所有命中结果的相似度都落在 **0.304 ~ 0.367** 之间。注意两件事：

- 命中的结果，相似度也才 0.3 出头。如果按直觉设一个"低于 0.5 不展示"的置信度门槛，**这个相册会一条结果都不剩**。
- 整句的相似度（0.341~0.367）系统性地高于单词（0.304~0.335），和命中率的方向一致。这个差值可以拿来做排序参考，但不能拿来当绝对阈值。

结论：`similarity` 只能当相对量用（排序、分组、"更多类似照片"），不能当质量分用。要判断"没找到"，唯一可靠的信号是返回数组长度为 0。

## 适老化界面上会怎么改

按这三条结论，界面要动的地方其实不少：

1. **输入方式**：语音优先。老人说一句比打字快得多，而且天然就是整句。
2. **占位与示例**：把"搜索照片"改成"说说那张照片里有什么"，下面挂两个示例整句。
3. **空结果页**：不要只显示"没有找到"。给一句可执行的引导——"试试说完整一点，比如'宝宝在沙发上看书'"。这一条能直接决定用户是再试一次还是关掉应用。
4. **结果呈现**：大缩略图、单列，别搞九宫格。他们要的是"是不是这张"，不是"扫一眼有多少张"。
5. **索引时机**：435ms/张意味着可以在充电待机时批量建，也可以拍一张建一张。查询 30ms 级，用户完全无感，不需要做"搜索中"的加载态。

## 没测的部分

三件事这轮没有数据，不下结论：

- 照片量上去之后的召回变化。9 张是玩具规模，几千张时"0 命中"的比例会不会更高，不知道。
- 方言与语音识别错误。我们输入的是标准普通话整句，真实场景里语音转写本身会带错字。
- 关系词。"我孙子""姥姥家那只狗"这类需要外部知识才能落到图上的查询，一条都没测。

## 真机数据

| 项目 | 实测值 |
| --- | --- |
| 设备 | MatePad Pro（HarmonyOS 7 / API 26，序列号略） |
| 建索引 | 9 张 3916ms，平均 435ms/张 |
| 单次查询 | 18 ~ 42ms |
| 查询命中率 | 8/15（整句 3/3，单词 4/10，干扰 1/2） |
| 命中结果相似度区间 | 0.304 ~ 0.367 |
| 单词 vs 整句 | "沙发"0 条 → "宝宝在沙发上看书"命中 |

![15 条查询的完整结果表](assets/01-table.png)

![三条口语整句全部命中，相似度反而高于单词](assets/02-sentences.png)

## 总结

文搜图适合"用户记得画面、不记得文件名"的场景：家庭相册、旅行照片、截图找旧信息、电商素材库。它的输入是自然语言，所以产品形态应该往"描述"靠，而不是往"关键词"靠。

不适合需要精确筛选的场景——按拍摄日期、按人、按地点的硬条件过滤，还是得靠元数据。这次实验真正的收获是那条反直觉的：越口语、越完整的句子，效果越好，所以搜索框应该鼓励用户多说，而不是少说。

> 💡 **一句话**：在这个能力上，"输入关键词"是会失败的用法——把搜索框改成"说说那张照片里有什么"，命中率从 4/10 变成 3/3。

## 参考文献

1. 通过文本搜索图片（开发指南）：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/core-vision-text-search-image
2. textSearchImage（文搜图）API 参考：https://developer.huawei.com/consumer/cn/doc/harmonyos-references/core-vision-text-search-image-api
3. Core Vision Kit 简介：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/core-vision-introduction
4. Core Vision Kit 目录：https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/core-vision-kit-guide
