适合谁看在做内容探索型产品的人想知道 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 MapString, 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)}, ), ),这个设计的巧妙之处在于不替代搜索— 搜索页仍然正常展示搜索结果智能识别— 通过关键词检测判断输入是否像自然语言无缝引导— 点击后带着原始 query 跳转到 AI 助手产品逻辑— 搜索无结果时也显示这个提示给用户一条退路比如用户在搜索页输入今晚想吃点热乎的搜索结果无因为没有菜名叫热乎的 提示试试用 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 Futurevoid 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.dartAI 助手页 欢迎示例app/lib/features/explore/screens/explore_screen.dart探索页两种入口并存app/lib/core/ai/ai_explore_coordinator.dartAI 流程编排 系统提示词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 推荐比传统搜索更自然核心不在模型更强而在它更适合承接模糊、带场景、带情绪的用户意图。食界探味当前的设计之所以顺关键在于搜索和 AI 互补— 搜索处理精确查找AI 处理模糊探索AI 不替代内容— AI 负责理解意图和组织推荐语义真实菜品由卡片承接工具调用真实数据— AI 不编造内容4 个工具分别对应不同类型的意图搜索页智能引导— 检测到自然语言时主动提示试试 AI 助手鸿蒙语音增强— 语音输入让模糊表达更容易TTS 让推荐可以被听在鸿蒙设备上嘴 → 语音识别 → AI 理解 → 工具调用 → 菜品卡片 → 语音播报形成了一个完整的闭环比传统打字 → 搜索框 → 关键词匹配的链路更短、更自然。这不是 AI 替代搜索而是 AI 补了搜索在模糊意图理解上的短板。