鸿蒙 + Flutter 下美食探索场景为什么 AI 推荐比传统搜索更自然

适合谁看

  • 在做内容探索型产品的人

  • 想知道 AI 推荐到底解决了什么产品问题的人

  • 不想把 AI 功能做成"只是换个搜索框"的开发者

  • 想理解搜索和 AI 推荐如何在鸿蒙端协同的人

问题背景

传统搜索并不是没用。它非常适合:

  • 我知道关键词

  • 我知道要找哪个对象

  • 我只想快速定位结果

但美食探索场景有一个天然难点:用户很多时候并不知道具体想找什么

他更可能说的是:

  • 想吃点鸡蛋做的,但别太单调

  • 最近下雨,想来点热乎的

  • 有没有适合第一次尝试的异国吃法

这类输入如果完全按传统搜索框理解,往往会很别扭。

项目中的真实场景

食界探味当前已经同时具备两种路径:

路径 入口 适合场景
普通搜索页 app/lib/features/search/ 已知目标,精确关键词
AI 助手页 app/lib/features/ai_assistant/ 模糊意图,探索发现

AI 助手背后通过 4 个工具把模糊问题转成真实菜品结果:

  • search_dishes --- 多维度条件搜索

  • get_random_dish --- 随机推荐惊喜

  • get_dishes_by_ingredient --- 同食材全球吃法

  • get_dish_detail --- 菜品详情

探索页上两种入口并存:

复制代码
// explore_screen.dart

// 搜索入口 --- 精确查找
SearchEntryBar(horizontalPadding: horizontalPadding),

// AI 入口 --- 模糊探索
if (AppConfig.enableAi)
  AiEntryCard(
    onTap: () => context.push('/ai-assistant'),
  ),

这说明当前 AI 推荐并不是脱离搜索存在,而是在补搜索不擅长的那部分语义理解。

核心实现

先说结论:

在美食探索场景下,AI 推荐之所以更自然,不是因为它更"智能"这个抽象词,而是因为它更适合承接模糊、带情绪、带场景的用户意图。

一、传统搜索更像"定位已知目标"

搜索的优势非常明确:输入关键词 → 快速匹配 → 返回结果列表。

食界探味的传统搜索页实现:

复制代码
// search_screen.dart

void _onQueryChanged(String text) {
  _debounce?.cancel();
  _debounce = Timer(const Duration(milliseconds: 300), () {
    ref.read(searchProvider.notifier).search(text);
  });
}

300ms 防抖后触发搜索,结果直接渲染为菜品列表。这在下面这些场景里很好用:

  • 我就想搜"寿喜锅"

  • 我就想找"牛肉"

  • 我知道自己要什么

但一旦用户输入开始带上情绪、场景、模糊偏好,传统搜索就会开始显得很硬。

二、AI 推荐更适合承接"模糊意图"

食界探味当前 AI 助手的系统提示词里,已经把意图理解写得很明确:

复制代码
// ai_explore_coordinator.dart → _systemPrompt

const _systemPrompt = '''
你是「食界探味 AI 探味助手」,帮助用户从食材出发探索全球吃法。

## 工作流程
1. 理解用户意图:提取食材、口味偏好、排除项、场景等信息
2. 调用 search_dishes 工具检索匹配菜品
3. 如果用户想随机探索,调用 get_random_dish
4. 如果用户想看某道菜的详情,调用 get_dish_detail
5. 如果用户想看同食材的其他吃法,调用 get_dishes_by_ingredient

## 风格
- 温暖、有趣,像朋友推荐美食
- 极简,话越少越好,点到即止
''';

AI 助手不是在机械匹配词,而是在先把用户那句自然语言还原成更结构化的意图。比如用户说"想吃鸡蛋做的,但别太家常",AI 会理解为:

  • 食材: 鸡蛋

  • 避免: 家常口味

  • 需要: 有特色的做法

然后调用 search_dishes 工具:

复制代码
// search_dishes_tool.dart → parametersSchema

'ingredients': { 'description': '食材名称列表,如 ["鸡蛋", "番茄"]' },
'flavorTags': { 'description': '偏好的口味标签,如 ["鲜", "甜"]' },
'avoidTags': { 'description': '排除的口味标签,如 ["辣"]' },
'region': { 'description': '地域偏好,如 "亚洲"、"欧洲"、"美洲"' },

AI 把"别太家常"翻译成 avoidTags: ["家常"],把"鸡蛋做的"翻译成 ingredients: ["鸡蛋"],然后用结构化参数去查数据库。这一步就是 AI 推荐比传统搜索更自然的关键------它能理解自然语言背后的结构化意图

三、四个工具分别解决什么类型的模糊意图

食界探味的 4 个工具不是随机设计的,它们分别对应 4 类不同的用户意图:

工具 解决的意图类型 示例输入
search_dishes 多条件组合探索 "想吃牛肉,清淡一点,不要辣"
get_random_dish 完全随机惊喜 "给我一个惊喜""随便推荐"
get_dishes_by_ingredient 同食材全球吃法 "牛肉在其他国家怎么做"
get_dish_detail 深入了解某道菜 "这道菜的详细介绍"

search_dishes 是最核心的工具,支持 5 个维度的条件组合:

复制代码
// search_dishes_tool.dart

Map<String, dynamic> get parametersSchema => {
  'properties': {
    'ingredients': { 'description': '食材名称列表' },
    'flavorTags': { 'description': '偏好的口味标签' },
    'avoidTags': { 'description': '排除的口味标签' },
    'region': { 'description': '地域偏好' },
    'limit': { 'description': '返回数量,默认 5' },
  },
};

这意味着 AI 可以同时处理"要什么"和"不要什么"------传统搜索很难同时表达"要牛肉"和"不要辣"。

get_random_dish 则解决了一类传统搜索完全无法处理的意图:

复制代码
// get_random_dish_tool.dart

String get description =>
    '随机获取一道菜品,适合用户说"随便推荐一个"或"给我一个惊喜"的场景。';

"给我一个惊喜"------这种输入用传统搜索根本无法处理,但 AI 可以理解它是"随机推荐"的意图。

四、AI 推荐在这里解决的是"表达门槛"

传统搜索要求用户先把问题收得很准:

复制代码
用户想表达:"我想吃鸡蛋做的,清淡一点,适合一个人吃的"
传统搜索输入框:鸡蛋 清淡          ← 用户被迫精简
搜索结果:番茄炒蛋、蒸蛋羹         ← 匹配到的可能不是用户想要的

AI 推荐允许用户保持自然说话方式:

复制代码
用户想表达:"我想吃鸡蛋做的,清淡一点,适合一个人吃的"
AI 助手输入框:今晚想吃点鸡蛋做的,清淡一点,一个人吃
AI 理解:食材=鸡蛋,口味=清淡,场景=一人食
AI 回复:为你找到了 3 道适合一个人的鸡蛋吃法:日式茶碗蒸、
         西班牙蛋饼、泰式蒸蛋。茶碗蒸最清淡,西班牙蛋饼更饱腹。

这种输入方式对用户来说更轻。而对产品来说,它降低的是用户表达意图的门槛

AI 助手页面的欢迎页示例也体现了这一点:

复制代码
// ai_assistant_screen.dart → _WelcomeView

static const _examples = [
  '今晚想吃点热乎的',           // 场景 + 情绪
  '家里有鸡蛋,做什么好',        // 食材 + 开放式
  '来个异国风味的牛肉',          // 食材 + 地域偏好
  '不想吃辣,清淡一点',          // 排除 + 偏好
  '给我一个惊喜',               // 完全随机
];

这 5 个示例没有一个是"精确关键词",全部是自然语言表达。它们在告诉用户:你不需要想好要搜什么,随便说就行。

五、搜索页如何智能引导到 AI 助手

食界探味还有一个很聪明的设计:当用户在搜索页输入了自然语言时,会自动提示"试试 AI 探味助手":

复制代码
// search_screen.dart

static bool _looksLikeNaturalLanguage(String query) {
  if (query.length < 6) return false;
  const intentWords = [
    '想', '不要', '适合', '推荐', '来个',
    '有', '做', '吃', '喜欢', '清淡', '热乎',
  ];
  return intentWords.any((w) => query.contains(w));
}

当检测到搜索词像自然语言时:

复制代码
if (AppConfig.enableAi && _looksLikeNaturalLanguage(state.query))
  _AiSearchHint(
    query: state.query,
    onTap: () => context.push(
      '/ai-assistant?q=${Uri.encodeComponent(state.query)}',
    ),
  ),

这个设计的巧妙之处在于:

  1. 不替代搜索 --- 搜索页仍然正常展示搜索结果

  2. 智能识别 --- 通过关键词检测判断输入是否像自然语言

  3. 无缝引导 --- 点击后带着原始 query 跳转到 AI 助手

  4. 产品逻辑 --- 搜索无结果时也显示这个提示,给用户一条退路

比如用户在搜索页输入"今晚想吃点热乎的":

复制代码
搜索结果:无(因为没有菜名叫"热乎的")
提示:试试用 AI 探味助手理解你的需求 →

点击后跳转到 AI 助手,带着 query"今晚想吃点热乎的",AI 会理解为"热的、汤类、暖胃",然后推荐合适的菜品。

六、AI 输出不是替代搜索结果,而是"组织推荐方向"

食界探味的 AI 助手输出有一个关键设计:AI 不直接展示菜品详情,而是简短文字 + 菜品卡片

系统提示词明确规定:

复制代码
你的文字回复下方会自动展示菜品卡片,用户可以点击卡片查看详情。
所以你的文字部分要非常简短,不要重复卡片上已有的信息。
推荐多道菜时,格式如下(整段控制在3-5句话以内):
为你找到了N道XX相关的吃法:菜名A、菜名B、菜名C。
然后用1-2句话做一个整体点评或亮点提示。

这意味着 AI 在这里的角色是:

复制代码
用户 → AI 理解意图 → AI 调用工具 → AI 组织推荐语义 → 卡片展示真实菜品
              ↓
         不是:
         AI 编造内容 → 直接展示文本

AI 负责"把探索方向讲清楚",真实内容仍然由菜品卡片和详情页承接。这比"让 AI 直接编一整页内容"更稳,也更适合真实产品。

七、为什么说它"更自然",不是"更万能"

AI 推荐并不是要替代所有搜索。更准确的理解应该是:

场景 适合路径 原因
"我要找寿喜锅" 传统搜索 精确目标,直接匹配
"牛肉怎么做" 传统搜索 食材关键词,搜索能处理
"想吃点清淡的鸡蛋" AI 推荐 模糊偏好,需要意图理解
"来个惊喜" AI 推荐 随机推荐,搜索无法处理
"适合下雨天吃的热乎东西" AI 推荐 场景 + 情绪,搜索无法理解
"有没有异国风味的牛肉" AI 推荐 地域 + 食材组合,需要语义理解

食界探味当前同时保留搜索页和 AI 助手页,本身就说明了这一点。它们不是谁替代谁,而是在解决两类不同问题。

八、在鸿蒙端,语音输入让 AI 推荐更自然

这是鸿蒙端特有的优势。鸿蒙设备支持语音输入,用户可以直接用嘴说出模糊意图:

复制代码
用户对着鸿蒙手机说:"想吃点鸡蛋做的,别太家常"
  ↓
鸿蒙 SpeechRecognitionPlugin 识别为文本
  ↓
Flutter SpeechRecognitionChannel 接收文本
  ↓
AI 助手理解意图:食材=鸡蛋,避免=家常
  ↓
调用 search_dishes(ingredients: ["鸡蛋"], avoidTags: ["家常"])
  ↓
推荐:日式茶碗蒸、西班牙蛋饼、泰式蒸蛋
  ↓
用户点击卡片查看详情

语音输入让"自然语言表达"变得更加自然------用户不需要打字,直接说就行。在鸿蒙设备上,这个体验链路是:

复制代码
嘴 → 鸿蒙语音识别 → Flutter AI 助手 → 工具调用 → 菜品卡片

比传统搜索的体验链路更短、更自然:

复制代码
想 → 打字 → 搜索框 → 关键词匹配 → 结果列表

而且语音输入天然支持更长、更复杂的表达。打字时用户可能会精简为"鸡蛋 清淡",但语音时用户会说完整句子"想吃鸡蛋做的,清淡一点,不要太家常"------这让 AI 能获取更丰富的意图信息。

九、TTS 播报让推荐结果可以"被听"

鸿蒙端的 TTS 能力让 AI 推荐的结果可以被语音播报:

复制代码
// ai_explore_coordinator.dart

Future<void> speakText(String text) async {
  final cleaned = _stripForTts(text);
  await TextToSpeechChannel.speak(cleaned);
}

用户看完 AI 推荐后,可以点击"语音播报"按钮,让鸿蒙 TTS 引擎把推荐文案读出来。这在以下场景特别有用:

  • 用户在做饭时,不方便看手机

  • 用户在开车时,想听 AI 推荐

  • 用户视力不便时,语音推荐更友好

语音输入 + AI 推荐 + TTS 播报,形成了一个完整的"说话 → 听推荐"闭环:

复制代码
说话(鸿蒙 ASR)→ AI 理解 → 工具调用 → AI 组织推荐 → 听推荐(鸿蒙 TTS)

关键代码位置

文件 作用
app/lib/features/search/screens/search_screen.dart 传统搜索页 + AI 引导
app/lib/features/ai_assistant/screens/ai_assistant_screen.dart AI 助手页 + 欢迎示例
app/lib/features/explore/screens/explore_screen.dart 探索页,两种入口并存
app/lib/core/ai/ai_explore_coordinator.dart AI 流程编排 + 系统提示词
app/lib/core/ai/tools/search_dishes_tool.dart 多条件搜索工具
app/lib/core/ai/tools/get_random_dish_tool.dart 随机推荐工具
app/lib/core/ai/tools/get_dishes_by_ingredient_tool.dart 同食材查询工具
app/lib/core/ai/tools/get_dish_detail_tool.dart 菜品详情工具
app/lib/core/platform/speech_recognition_channel.dart 鸿蒙语音识别通道
app/lib/core/platform/text_to_speech_channel.dart 鸿蒙 TTS 通道

搜索与 AI 推荐的协作架构

复制代码
┌─────────────────────────────────────────────────────┐
│                     用户输入                          │
│                                                      │
│  "寿喜锅"          "想吃点热乎的鸡蛋"    "给我惊喜"   │
│     │                    │                   │       │
│     ▼                    ▼                   ▼       │
│  ┌──────────┐     ┌──────────┐        ┌──────────┐  │
│  │ 传统搜索  │     │ 智能检测  │        │ AI 入口  │  │
│  │ 关键词匹配│     │ 自然语言? │        │ 直接进入 │  │
│  └────┬─────┘     └────┬─────┘        └────┬─────┘  │
│       │                │                    │        │
│       ▼                ▼                    ▼        │
│  ┌──────────┐     ┌──────────┐        ┌──────────┐  │
│  │ 搜索结果  │     │ 搜索结果  │        │ AI 助手  │  │
│  │ 列表展示  │     │ + AI 引导 │        │ 意图理解 │  │
│  └──────────┘     └────┬─────┘        └────┬─────┘  │
│                        │                    │        │
│                        ▼                    ▼        │
│                   ┌─────────────────────────────┐    │
│                   │       AI 工具调用层           │    │
│                   │  search_dishes / random /    │    │
│                   │  by_ingredient / detail      │    │
│                   └──────────────┬──────────────┘    │
│                                  │                    │
│                                  ▼                    │
│                   ┌─────────────────────────────┐    │
│                   │    菜品卡片 + 详情页承接      │    │
│                   └─────────────────────────────┘    │
│                                                      │
├──────────────────────────────────────────────────────┤
│                  鸿蒙原生能力增强                      │
│                                                      │
│  语音输入(SpeechRecognitionPlugin)                   │
│    → 让模糊表达更容易,获取更丰富的意图信息             │
│                                                      │
│  TTS 播报(TextToSpeechPlugin)                       │
│    → 让推荐结果可以被听,支持不方便看手机的场景         │
│                                                      │
└──────────────────────────────────────────────────────┘

常见坑

  • 把 AI 推荐做成"换皮搜索框" --- 如果 AI 只是把用户输入原样丢给搜索,那就失去了语义理解的价值

  • 让 AI 输出替代真实内容页 --- AI 编造的菜品信息不可靠,必须用工具调用真实数据

  • 只强调模型回答,不把真实业务卡片接回来 --- AI 推荐的价值在于"组织方向",真实内容仍需卡片承接

  • 误以为 AI 推荐要取代搜索 --- 搜索适合已知目标,AI 适合模糊探索,两者互补

  • 搜索页不引导到 AI --- 当用户输入自然语言时,应该主动提示"试试 AI 助手"

  • AI 欢迎页没有示例 --- 用户不知道能问什么,示例引导非常重要

  • 鸿蒙端语音输入没有接入 AI --- 语音识别的结果应该直接喂给 AI 助手,而不是只给搜索框

可复用模板

搜索与 AI 协同思路

复制代码
传统搜索适合
  - 已知目标
  - 精确关键词
  - 快速定位

AI 推荐适合
  - 模糊意图
  - 场景表达
  - 灵感探索
  - 随机惊喜

协同方式
  - 搜索页检测自然语言 → 引导到 AI
  - AI 用工具调用真实数据 → 不编造内容
  - AI 输出简短推荐语 → 卡片承接真实内容
  - 详情页继续深入 → 形成完整链路

AI 系统提示词模板(探索型推荐)

复制代码
const systemPrompt = '''
你是[产品名]的 AI 助手,帮助用户从[核心维度]出发探索[内容类型]。

## 工作流程
1. 理解用户意图:提取[维度1]、[维度2]、排除项、场景等信息
2. 调用工具检索匹配内容
3. 基于真实数据给出有温度的推荐

## 输出格式
用纯文本回复,简短(3-5句话以内)。
内容下方会自动展示卡片,不要重复卡片上的信息。

## 风格
- 温暖、有趣,像朋友推荐
- 必须基于工具返回的真实数据
- 没有完全匹配时诚实告知
''';

搜索页自然语言检测模板

复制代码
static bool looksLikeNaturalLanguage(String query) {
  if (query.length < 6) return false;
  const intentWords = [
    '想', '不要', '适合', '推荐', '来个',
    '有', '做', '吃', '喜欢', '清淡',
  ];
  return intentWords.any((w) => query.contains(w));
}

// 检测到自然语言时引导到 AI
if (looksLikeNaturalLanguage(query))
  AiSearchHint(
    onTap: () => context.push('/ai-assistant?q=$query'),
  );

本篇总结

美食探索场景下,AI 推荐比传统搜索更自然,核心不在"模型更强",而在它更适合承接模糊、带场景、带情绪的用户意图

食界探味当前的设计之所以顺,关键在于:

  1. 搜索和 AI 互补 --- 搜索处理精确查找,AI 处理模糊探索

  2. AI 不替代内容 --- AI 负责理解意图和组织推荐语义,真实菜品由卡片承接

  3. 工具调用真实数据 --- AI 不编造内容,4 个工具分别对应不同类型的意图

  4. 搜索页智能引导 --- 检测到自然语言时主动提示"试试 AI 助手"

  5. 鸿蒙语音增强 --- 语音输入让模糊表达更容易,TTS 让推荐可以被听

在鸿蒙设备上,"嘴 → 语音识别 → AI 理解 → 工具调用 → 菜品卡片 → 语音播报"形成了一个完整的闭环,比传统"打字 → 搜索框 → 关键词匹配"的链路更短、更自然。这不是 AI 替代搜索,而是 AI 补了搜索在模糊意图理解上的短板。

相关推荐
小博测试成长之路1 小时前
行业日报 | 2026年6月12日:Claude新模型、鸿蒙开发者大会与AI工程化加速
人工智能·harmonyos
互联网散修1 小时前
鸿蒙实战:从零实现自定义相机(上)——架构设计与核心实现
数码相机·华为·harmonyos·自定义相机
MemoriKu1 小时前
Flutter 相册 APP 收尾优化实战:未分析任务横幅持久隐藏与标签回归测试补强
大数据·人工智能·flutter·elasticsearch·机器学习·搜索引擎·重构
不羁的木木2 小时前
《HarmonyOS 6.1 新能力实战之智感握姿》第一篇:初识智感握姿——能力与场景全解析
华为·harmonyos
狼哥16862 小时前
《新闻资讯》八、产品定制层实现指南
ui·华为·harmonyos
浮芷.2 小时前
六星光芒阵:HarmonyOS API 24 Canvas 高级绘图实战
科技·华为·开源·harmonyos·鸿蒙
狼哥16863 小时前
《新闻资讯》一、应用分层模块化整体实现指南
ui·harmonyos
木咺吟3 小时前
鸿蒙原生应用实战(一):项目搭建与首页开发 — 游戏收藏夹
华为·harmonyos
风华圆舞3 小时前
鸿蒙 + Flutter 如何把 AI 助手嵌进应用页面里——以食界探味为
人工智能·flutter·harmonyos