鸿蒙 insight_intent 到底怎么写,才能被小艺搜索正确理解
适合谁看
-
想写好鸿蒙
insight_intent.json的开发者 -
想让应用被鸿蒙小艺搜索理解的人
-
已经接了 Intents Kit,但配置还很松散的人
问题背景
很多入口配置的问题不是"格式错误",而是"语义太弱":
-
名称不稳定(今天叫
openPage,明天改navigateTo) -
参数太随意(直接传路由字符串)
-
候选值不清晰(不知道支持哪些页面)
-
关键词和展示描述没有产品语义
鸿蒙系统入口如果写成这样,后面基本很难维护。小艺搜索也看不懂你在说什么。
项目中的真实场景
食界探味当前的入口配置在:
-
app/ohos/entry/src/main/resources/base/profile/insight_intent.json
完整配置:
{
"insightIntents": [
{
"intentName": "JumpFunctionPage",
"domain": "ToolsDomain",
"intentVersion": "1.0.1",
"srcEntry": "./ets/entryability/InsightIntentExecutorImpl.ets",
"uiAbility": {
"ability": "EntryAbility",
"executeMode": ["foreground"]
},
"inputParams": [
{
"properties": {
"pageId": {
"type": "string",
"enum": [
{
"value": "search",
"displayName": "搜索美食",
"keywords": ["搜索", "找菜", "查菜"],
"displayDescription": "搜索全球美食与食材",
"icon": "https://abc.xx"
},
{
"value": "wish_box",
"displayName": "心愿单",
"keywords": ["心愿", "想吃"],
"displayDescription": "查看我的美食心愿",
"icon": "https://abc.xx"
},
{
"value": "ingredients",
"displayName": "食材探索",
"keywords": ["食材", "原料"],
"displayDescription": "浏览全球食材",
"icon": "https://abc.xx"
},
{
"value": "explore",
"displayName": "探索美食",
"keywords": ["探索", "推荐", "发现"],
"displayDescription": "浏览今日推荐与全球美食",
"icon": "https://abc.xx"
},
{
"value": "dish_detail",
"displayName": "查看菜品详情",
"keywords": ["菜品", "详情", "做法"],
"displayDescription": "打开指定菜品的详情页",
"icon": "https://abc.xx"
}
]
}
}
}
]
}
]
}
核心实现
一、先定义稳定的 intent 名称
当前使用的是 JumpFunctionPage。
这个名字本身就表达了用途:跳到功能页。它比模糊的 openPage、navigate 更稳定。
命名原则:
|
原则 |
好的例子 |
差的例子 |
|---|---|---|
|
表达意图 |
|
|
|
不包含实现细节 |
|
|
|
稳定不变 |
|
|
|
语义清晰 |
|
|
intent 名称一旦上线就很难改,因为鸿蒙系统会缓存这个名称。所以第一次就要想清楚。
二、参数要用结构化字段,不要直接写路由
当前输入参数的核心是 pageId,而不是 /search、/wish-box 这类路由路径。
为什么用 pageId 而不是路由路径:
|
方式 |
示例 |
问题 |
|---|---|---|
|
路由路径 |
|
和 Flutter 实现耦合,改路由要改配置 |
|
结构化参数 |
|
和实现解耦,改路由不用改配置 |
pageId 是业务语义,不是实现细节。鸿蒙配置层只认识 search,不认识 /search。这样配置层和 Flutter 实现层保持解耦。
三、enum 要限制可选值
当前配置里对 pageId 做了枚举:
"enum": [
{ "value": "search", "displayName": "搜索美食" },
{ "value": "wish_box", "displayName": "心愿单" },
{ "value": "ingredients", "displayName": "食材探索" },
{ "value": "explore", "displayName": "探索美食" },
{ "value": "dish_detail", "displayName": "查看菜品详情" }
]
这一步很重要,因为它告诉鸿蒙系统"我真正支持哪些语义入口"。
enum 的作用:
|
作用 |
说明 |
|---|---|
|
限制参数范围 |
只接受这 5 个值,其他值会被拒绝 |
|
系统理解入口 |
小艺搜索知道你支持哪些功能 |
|
文档化 |
每个值都有 displayName,一目了然 |
|
校验 |
执行器可以用 |
四、展示名、关键词、描述不能随便填
每个 enum 值都有 3 个展示字段:
{
"value": "search",
"displayName": "搜索美食",
"keywords": ["搜索", "找菜", "查菜"],
"displayDescription": "搜索全球美食与食材"
}
这 3 个字段决定了小艺搜索怎么理解你的入口:
|
字段 |
作用 |
影响 |
|---|---|---|
|
|
用户在搜索结果中看到的名称 |
决定用户是否点击 |
|
|
小艺搜索匹配的关键词 |
决定用户搜索时能否找到 |
|
|
搜索结果中的描述文字 |
帮助用户理解入口功能 |
关键词设计原则:
|
原则 |
说明 |
示例 |
|---|---|---|
|
覆盖用户可能搜索的词 |
用户不会搜"pageId=search" |
"搜索"、"找菜"、"查菜" |
|
不要太泛 |
"美食"太泛,匹配所有入口 |
"搜索美食"比"美食"好 |
|
不要太窄 |
"牛肉咖喱搜索"太窄 |
"搜索"比"牛肉咖喱搜索"好 |
|
3-5 个关键词 |
太少匹配不到,太多匹配太杂 |
["搜索", "找菜", "查菜"] |
小艺搜索的工作原理:
用户对小艺说:"帮我搜索美食"
↓
小艺在 insight_intent.json 中匹配关键词
↓
找到 "search" 入口的 keywords: ["搜索", "找菜", "查菜"]
↓
匹配成功 → 展示 "搜索美食" 入口
↓
用户点击 → 调起应用,传入 pageId="search"
如果 keywords 写得不好,小艺搜索就找不到你的入口。
五、配置层和执行层要对齐
配置层(insight_intent.json)定义了 5 个 pageId:
search, wish_box, ingredients, explore, dish_detail
执行层(InsightIntentExecutorImpl.ets)的白名单:
const VALID_PAGE_IDS: string[] = [
'search', 'wish_box', 'ingredients', 'explore', 'dish_detail'
];
两边必须一致! 如果配置层加了一个新 pageId,执行层也要跟着加。否则系统会传入一个执行器不认识的值。
六、dish_detail 的特殊处理
dish_detail 是唯一需要额外参数的入口:
{
"value": "dish_detail",
"displayName": "查看菜品详情",
"keywords": ["菜品", "详情", "做法"],
"displayDescription": "打开指定菜品的详情页"
}
执行器会对它做特殊校验:
if (pageId === 'dish_detail' && (!dishId || dishId.length === 0)) {
resolve(makeResult(-1, 'dishId type error'));
return;
}
这说明:不是所有入口都一样简单。有些入口需要额外参数,配置层要体现这一点。
关键代码位置
|
文件 |
作用 |
|---|---|
|
|
鸿蒙入口配置(本文核心) |
|
|
参数校验 |
配置层设计原则总结
|
原则 |
说明 |
食界探味的做法 |
|---|---|---|
|
稳定命名 |
intent 名称一旦上线就很难改 |
|
|
结构化参数 |
用 pageId 而不是路由路径 |
|
|
枚举限制 |
明确支持哪些入口 |
5 个 enum 值 |
|
语义化展示 |
displayName + keywords + 每个值都有 |
|
|
配置执行对齐 |
配置层和执行层的参数一致 |
两边都是 5 个 pageId |
常见坑
-
直接把 Flutter 路由字符串写进 insight_intent.json — 应该用 pageId,路由留给 Flutter
-
keywords 和 displayDescription 太空泛 — 应该覆盖用户可能搜索的词
-
enum 不限制,参数范围过大 — 应该用 enum 明确可选值
-
配置层和执行层各自定义一套不同参数语义 — 两边必须一致
-
intent 名称太泛 —
openPage不如JumpFunctionPage表达清晰 -
没有给每个 enum 值加 displayName — 小艺搜索无法展示友好的入口名称
-
关键词覆盖不全 — 用户搜索"查菜"时找不到入口
可复用模板
insight_intent.json 模板
{
"insightIntents": [
{
"intentName": "JumpFunctionPage",
"domain": "YourDomain",
"intentVersion": "1.0.0",
"srcEntry": "./ets/entryability/IntentExecutorImpl.ets",
"uiAbility": {
"ability": "EntryAbility",
"executeMode": ["foreground"]
},
"inputParams": [
{
"properties": {
"pageId": {
"type": "string",
"enum": [
{
"value": "home",
"displayName": "首页",
"keywords": ["首页", "主页", "推荐"],
"displayDescription": "浏览推荐内容"
},
{
"value": "profile",
"displayName": "我的",
"keywords": ["个人", "设置", "账户"],
"displayDescription": "查看个人信息"
}
]
}
}
}
]
}
]
}
关键词设计模板
每个 enum 值的 keywords 应该:
✅ 覆盖用户可能搜索的词(3-5 个)
✅ 不要太泛("美食"太泛)
✅ 不要太窄("牛肉咖喱搜索"太窄)
✅ 包含同义词("搜索"、"找菜"、"查菜")
❌ 只有 1 个关键词(匹配率低)
❌ 只有技术术语(用户不会搜 "pageId")
配置执行对齐检查清单
每新增一个 pageId,检查:
□ insight_intent.json 的 enum 里加了?
□ displayName 起好了?
□ keywords 覆盖了用户可能搜索的词?
□ displayDescription 描述清楚了?
□ InsightIntentExecutorImpl.ets 的 VALID_PAGE_IDS 加了?
□ intent_navigation_channel.dart 的 _pageIdToRoute 加了?
本篇总结
鸿蒙 insight_intent.json 写得好不好,决定小艺搜索能不能真正理解你的应用入口。核心要点:
-
稳定命名 —
JumpFunctionPage,不包含实现细节 -
结构化参数 — 用
pageId,不用路由路径 -
枚举限制 — 明确 5 个可选值,不接受任意参数
-
语义化展示 — 每个值都有
displayName+keywords+displayDescription -
配置执行对齐 — 配置层和执行层的参数必须一致
把它当成系统语义配置,而不是普通 JSON 文件,质量会高很多。
更多推荐




所有评论(0)