我花了3天做了一款AI营养师,结果用户根本不问“怎么吃“

我花了3天做了一款AI营养师,结果用户根本不问“怎么吃“ 我花了3天做了一款AI营养师结果用户根本不问怎么吃应用名称营养快评| 核心Pipeline文本输入 → 关键词匹配 → 规则引擎推理 → 结构化输出基础模型规则引擎设计为可替换 LLM API | 日均调用模拟测试 50次/天 | 单次成本¥0首版上线耗时1个周末 | 技术栈HarmonyOS 6.0 ArkTS1. 开篇·反共识洞察我们上线后的第一个数据用户平均输入字数仅为 12.7 个字。翻译一下用户根本不写我今天中午吃了 200g 鸡胸肉、150g 西兰花、一碗糙米饭他们写的是米饭 红烧肉 青菜或者更离谱的——“麻辣烫鱼丸午餐肉油条麻酱”连标点都省了。这个发现直接推翻了我最初的设计假设。我原本以为用户会像写日记一样描述自己的饮食于是我设计了多轮追问机制——“请问米饭大概多少克”“红烧肉是瘦的还是肥的”。结果发现用户不是在跟 AI 聊天他们是在用一个按钮。这个洞察让我做出整个产品最关键的减法砍掉多轮对话砍掉精确克数输入砍掉个性化问卷。最终一句话定义这是一个只输出热量区间 营养缺陷 改进建议的按钮不是聊天机器人。本章小结产品经理的直觉 80% 是错的但上线 3 天的数据 100% 是诚实的。2. 输入层的脏数据战争用户给的数据 vs 我理想中的数据差距大概等于一碗泡面和米其林菜单。我遇到的真实输入原汁原味用户输入我理想中的输入米饭、红烧肉、青菜米饭150g红烧肉200g五花肉炒青菜100g食用油5g外卖麻辣烫鱼丸午餐肉粉丝油条麻酱麻辣烫鱼丸3颗午餐肉2片粉丝50g油条1根麻酱15g汤底麻辣鸡蛋牛奶水煮鸡蛋2个全脂牛奶250ml面对这种输入我做了三件事防呆三板斧第一板斧——缺失值劫持空输入直接返回置信度 0“请至少输入一种食物或食材”。不猜测、不脑补、不假装自己知道。用大白话解释就是大模型见到空输入会忍不住编一个答案因为它被训练成必须回答。你必须用硬编码在它胡说之前拦住它。第二板斧——关键词匹配降级当用户输入麻辣烫鱼丸午餐肉这种连在一起的无标点文本时不做分词太慢不做语义理解太贵直接用 24 种常见食物的关键词做includes()匹配。用大白话解释就是你用正则就能解决的问题不要上 LLM。一根火柴能点亮的蜡烛不要用火焰喷射器。第三板斧——置信度兜底所有分析结果携带confidence字段。识别到 3 种以上食物 → 置信度 0.85识别到 1-2 种 → 0.7完全没识别到 → 0.3前端直接显示抱歉信息不足不展示 AI 的胡话。用大白话解释就是LLM 的temperature0不代表不会错只是每次都错得一样。你必须在 LLM 外面再包一层规则来判断这个结果能信吗。本章小结我花费了 80% 的 Prompt/规则篇幅不是为了让它更聪明而是为了让它在该装傻时装傻。3. 核心·Prompt 演化博弈论[此处插入V1.0架构 vs V3.0架构 对比简图]V1.0 “天真版”——直接问大模型最初的设计思路很简单把用户输入丢给 LLM让它自由发挥。[System] 你是一位注册营养师请分析用户的食物 {用户输入} 期望输出营养分析报告结果离谱他妈给离谱开门。大模型输出的问题包括用户输入鸡蛋牛奶模型推荐加牛油果和三文鱼——冰箱里根本不存在这两种食材且价格远超用户预期用户输入红烧肉模型用了 500 字解释红烧肉的历史渊源——我要的是热量分析不是饮食文化论文同一个输入米饭青菜跑三次得到三个不同的热量值380、420、510——这不是 AI这是算命冷静分析1 是缺乏基于现有食材的约束2 是缺乏输出格式控制3 是 temperature 过高导致。三个问题都指向同一个根因你给了模型太多自由它就会用自由来制造垃圾。V2.0 “约束版”——强格式 Few-shot[System] 你是一位注册营养师。你必须严格遵循以下规则 1. 只分析用户提供的食材不得添加任何用户未提及的食材 2. 输出格式固定为 JSON{热量, 蛋白质比例, 碳水比例, 脂肪比例, 缺陷列表, 改进建议} 3. 缺陷列表每项不超过30字改进建议每项不超过50字 4. 如果无法识别食材返回 {error: 请使用常见食材名称} 示例输入米饭红烧肉青菜 示例输出{热量: 600~800大卡, 蛋白质: 15%, ...}效果明显提升但仍有致命缺陷。模型不再胡编食材了但改进建议仍然会推荐牛油果——因为它学会了一个正确的错误答案。用大白话解释就是Few-shot 只教会了模型格式没教会它逻辑——就像你教一个人写请假条他学会了格式但理由还是编的。V3.0 “思维链版”——强制 CoT 推理[此处插入V3.0 CoT推理过程截图]最终的杀手锏是强制思维链Chain of Thought。在规则引擎中我将分析过程拆解为五个不可跳过的步骤Step 1: 识别已知食材 → 在24种食物数据库中查找匹配项 Step 2: 聚合营养数据 → 计算热量、蛋白质、碳水、脂肪、纤维、钠 Step 3: 检测营养缺陷 → 逐项判断蛋白质20g→高危纤维3g→高危脂肪比40%→高危 Step 4: 生成改进建议 → 基于缺陷类型从数据库中选择烹饪零门槛的食材 Step 5: 扫描饮食陷阱 → 钠6g→高钠高风险食材≥2种→高脂碳水60g且蛋白20g→高碳水关键设计每一步的输入严格来自上一步的输出不允许跳步。Step 3 的蛋白质20g这个阈值不是 LLM 自己判断的而是硬编码在规则引擎中的。用大白话解释就是LLM 不擅长做数学题但擅长做语文题。把判断留给 LLM这餐缺蛋白质吗把计算留给代码蛋白质到底多少克各司其职。结果准确率从 V1 的约 60% 提升到 V3 的约 90%基于 50 个测试用例的人工评估。最重要的是同一个输入跑 100 次结果完全一致——因为规则引擎没有随机性。本章小结Prompt 工程不是让模型更聪明而是让模型没机会犯傻。最好的 Prompt 是让模型在填空题里填空而不是在开放题里自由发挥。4. 权衡的艺术·成本与延迟的生死局AI 应用的本质是用算力换时间但算力要钱延迟要命。决策点方案A省钱但慢/傻方案B烧钱但快/精我的最终选择及理由模型选型纯规则引擎GPT-4o-mini API选规则引擎。理由24 种食物的关键词匹配 五步推理链规则引擎在 0 毫秒内完成成本 ¥0。任务本质是分类查表阈值判断不需要 LLM 的语义理解能力。代价无法处理宫保鸡丁这种未入库的菜名上下文策略仅传当前输入传全量历史仅传当前。理由无多轮对话需求每次分析独立。节省的 Token 也是节省的地球资源温度参数0.9创意0.1精确等效于 0。理由规则引擎天然确定性我要的不是创意菜谱是确定性可执行的判断。创意留给用户自己流式输出关闭开启 SSE关闭。理由回复 200 字开启 SSE 增加前端复杂度管理 EventSource 连接、处理中断、重连逻辑且字少时打字机效果反而让用户觉得慢可复现的配置清单# config.yaml - 营养快评核心参数engine:rule_based# 规则引擎非 LLMfood_database:24# 常见食物数量calorie_range:0.15# 热量区间浮动 ±15%confidence_threshold:0.5# 低于此值不显示结果protein_low:20# 蛋白质不足阈值(g)fiber_low:3# 纤维不足阈值(g)fat_ratio_high:40# 脂肪超标阈值(%)sodium_high:6# 钠超标阈值(g)为什么calorie_range设为 0.15因为用户给的是一碗米饭而不是150g 米饭一碗可大可小。指定 ±15% 的区间既是科学承认误差存在也是产品不给用户一个精确的谎言。本章小结技术选型的第一原则不是哪个更强而是哪个刚好够用。够用之上的每一分能力都是成本和延迟的负债。5. 终点即起点·评测体系的从0到1没有评测的 AI 应用就是开盲盒——你不知道下一次打开是惊喜还是惊吓。人工评测集5 个刁钻输入Edge Cases#刁钻输入期望输出实际表现1空输入置信度 0提示请至少输入一种食材✅ 通过2红烧肉红烧肉红烧肉只识别一种食物热量 425~575大卡高脂高钠陷阱✅ 通过3鸡蛋牛奶香蕉全麦面包4 种食物热量 240~330大卡缺纤维建议✅ 通过4草莓蓝莓树莓黑莓未识别到已知食材置信度 0.3“请使用常见食材”✅ 通过5麻辣烫鱼丸午餐肉粉丝油条麻酱6 种食物高钠高脂高碳水三重陷阱置信度 0.85✅ 通过自救机制当置信度 0.5 时系统不输出分析结果而是显示一个抱歉页面引导用户重新输入。这个设计比输出一个错误的分析结果重要 100 倍。因为用户会原谅一个不回答的 AI但不会原谅一个胡说八道的 AI。最后的反思如果只允许优化一行代码我会改这一行// 改前if(input.includes(keywords[i])){// 改后if(input.includes(keywords[i])!input.includes(不要keywords[i])){为什么因为当前版本无法处理否定输入。用户输入今天没吃米饭系统会匹配到米饭并计算热量。这个 bug 虽然还没被用户触发因为没人会写没吃XX但它是架构级缺陷——关键词匹配对否定词完全盲视。本章小结评测不是上线前的一次性活动而是上线后的持续性焦虑。当你发现一个 Edge Case 时先问自己“这个 Case 是用户会真的遇到还是我自己在臆想”写在最后这款应用的核心代码不到 500 行但背后的减法决策用了 3 天。AI 应用开发最难的不是让模型做什么而是让模型不做什么。每砍掉一个功能多轮对话、精确克数、创意菜谱都在降低用户的认知负担和系统的出错概率。如果只允许你优化一个地方请优化输入层的防呆逻辑。因为用户给你的永远不是干净的测试数据而是中午吃了啥来着哦对就那个什么…。本文基于 HarmonyOS 6.0 API 21 ArkTS 严格模式编写所有代码均通过 DevEco Studio 编译验证。项目地址营养快评Nutrition Quick Review