
先说结论这个项目如果只写成“我做了一个鸡尾酒配方库”技术上是不准确的。Naniya 真正要解决的问题是用户家里已经有一些酒和原料今天晚上到底能做什么如果还差一件材料补什么最划算如果不想照经典配方能不能基于当前材料给出一个可执行的自由调方案。这就把问题从“展示一个列表”变成了一个小型推荐系统用户酒库 - 经典酒款匹配 - 补 1 样材料推荐 - 自由调结构生成 - 灵感调酒师生成 - 保存为个人记录CSDN 版重点把功能拆成可验证的工程模块如果只从用户界面看Naniya 像是几个 Tab 和一批鸡尾酒卡片。但工程上我更关心的是每个功能有没有清楚的数据入口和兜底路径。目前这条链路可以拆成pages/cellar/cellar - cloudfunctions/getInventory - utils/inventory-config.getAvailableDrinks - pages/cellar-results/cellar-results - RESULT_TABS: 经典 / 自由调 / 补材料CSDN 这类技术平台我会重点记录这些模块边界而不是把文章写成产品宣传。因为后面一旦酒款、材料、用户记录继续扩张最容易出问题的不是页面样式而是材料 ID、库存状态、标准酒单和自定义材料之间的对应关系。1. 页面结构不是按“内容频道”拆而是按用户动作拆Naniya 现在不是一个完整网页产品它当前的主入口是微信小程序。真实用户能看到的核心入口是今日根据酒库状态给出当晚推荐用户可以换一杯或进入酒款详情。酒单浏览经典酒款也可以按风味、材料和“差 1 样可做”等条件筛选。酒库记录家里已有的基酒、利口酒、果汁、糖浆、香料和自定义材料。我的保存原创酒款、我的特调、喜欢、收藏和调过记录。灵感调酒师输入一句场景、情绪或物件再选择“今晚能喝 / 开脑洞特调”和酒感强度生成一杯可保存的特调。这个拆法的好处是每个入口都对应一个明确动作而不是堆功能。比如“酒库”不是资料库它会影响今日推荐、经典可做列表、补材料建议和灵感调酒师的材料边界。从小程序结构看主 Tab 是pages/index/index、pages/menu/menu、pages/cellar/cellar、pages/mine/mine。围绕它们扩展出pages/cellar-results/cellar-results、pages/custom-drink/custom-drink、pages/games-cocktail/games-cocktail等页面。2. “今晚能做什么”先看酒库而不是先看热门首页推荐会先读取用户酒库再用已有材料去计算可做酒款。这个判断比“随机推荐一杯经典酒”更贴近家庭场景。实现上首页会读取库存再调用材料匹配函数得到availableDrinks。如果用户有库存就优先从可做酒款里推荐如果没有库存才退回通用酒单。constavailablegetAvailableDrinks(DRINKS,items);constinStockCountObject.keys(items).filter(iditems[id]inStock||items[id]unlimited).length;这里的关键不是算法复杂而是产品判断新手打开工具时最有用的问题不是“经典鸡尾酒有哪些”而是“我现在能不能马上做一杯”。3. 结果页分成三类经典、自由调、补材料cellar-results里有三个结果 TabconstRESULT_TABS[{key:available,label:经典},{key:structure,label:自由调},{key:recommend,label:补材料},];这三个 Tab 对应三种不同意图经典当前材料已经够直接照配方做。自由调不一定是某个经典酒名但能按结构出杯比如长饮、酸甜、气泡、短饮。补材料告诉用户只差哪一个材料就能解锁更多经典酒款。“补材料”不是随便列购物清单而是只收敛到“刚好差 1 样系统材料”的情况。代码里会排除缺太多、缺自定义材料或无法解析材料的酒款if(hasOtherMissing||missingSysIds.size!1)return;这个取舍很重要。它避免把用户推向一长串难以行动的采购清单而是把建议压缩成“今天补一瓶/一件最有价值的材料”。4. 自由调不是让模型瞎编而是先用材料角色搭结构自由调这块不是简单问模型“给我一杯鸡尾酒”。小程序里有一个结构生成层会把材料拆成角色base基酒骨架acid酸度sweetener甜度sparkling / lengthener拉长aroma / bitter / salt香气和修边比如长饮结构大致是一份基酒 一份拉长材料再用少量酸甜和香气修边。酸甜结构则是基酒 酸 甜先保证入口张力和平衡。这类规则不花哨但能解决一个真实问题家里材料不完整时工具不能只说“不符合经典配方”还要给出“能不能按结构做一杯”的答案。5. 灵感调酒师的难点不是生成而是可执行和可保存灵感调酒师入口在pages/games-cocktail/games-cocktail。用户可以输入一句场景比如“雨夜旧书店”“朋友来家里”“只用我的材料调一杯”再选择模式和酒感强度。这里我做了几个边界输入长度有限制避免一上来就变成无限聊天。有“今晚能喝”和“开脑洞特调”两种模式分别对应可执行优先和创意优先。有“轻一点 / 适中 / 酒感强”的酒感选择。如果用户表达了“只用我的材料”会进入更严格的酒库材料模式。生成后不是只展示一段文字而是能保存到我的特调和调过记录。云函数侧的aiBartenderCreate也不是直接返回模型文本。它会先做安全预检、意图归一化、材料范围读取、结构化生成、校验、兜底再决定是否返回给前端。换句话说产品真正需要的是“可进入业务闭环的结构化结果”不是一段看起来很会调酒的散文。6. 为什么这个项目适合用云开发和 Node.js这个小程序的状态并不适合全部塞到前端用户酒库、收藏、喜欢、原创酒款和调过记录需要持久化。标准酒单和搜索索引需要统一维护。灵感调酒师需要服务端封装模型调用、校验和兜底。图片、二维码、分享和审核状态也都更适合放在云函数和云数据库侧。当前后端是多云函数组织例如getInventory、saveInventory、getDrinkAvailabilityIndex、aiBartenderCreate、saveCustomDrink、toggleFavorite等。这样做的好处是每个能力边界比较清楚坏处是后期要格外注意公共校验、数据结构和函数调用链路的复用。7. 这篇复盘里我真正想留下的经验如果你也在做 AI 小程序尤其是工具类小程序我会建议先问三个问题用户打开产品时要完成的动作是什么AI 生成的结果能不能进入保存、复用、二次调整这些产品闭环失败时能不能给出可信兜底而不是硬编一个答案对 Naniya 来说答案不是“做一个更大的鸡尾酒配方库”而是围绕酒库做一个家庭调酒工作台知道家里有什么知道今晚能做什么知道差一件材料能多做什么也能把偶然调好喝的一杯保存下来。理性饮酒未成年人请勿饮酒。#微信小程序 #Node.js #AI #云开发