Mood Spirits
2025
想喝一杯的时候,人往往先知道自己是什么感觉,却不一定知道该点什么。Mood Spirits 从情绪、场景和手边材料开始推荐,用户不必先懂酒,也能找到一杯有依据、确实做得出来的鸡尾酒。
这是一个个人项目。我独立完成了产品定义、推荐策略、交互与视觉设计,以及前端实现。比起做一份更完整的酒单,我更想验证的是:模糊的感受,能不能被转译成一次可信又有氛围的选择。
概念阶段,我用三种常见犹豫校准入口:用户只知道自己想放松,却说不出酒名;家里只有有限材料,不想为了配方再采购一整套;看到推荐后仍会追问「为什么是这杯」。
先问此刻的感觉,不先问酒名
传统选酒通常从基酒、酸甜度或酒精度开始,但这些选项更像专业知识,不像用户当下的语言。我把入口改成 Mood Index:用户在 Melancholy、Stressed、Relaxed、Confident、Romantic 等连续情绪之间移动,再补充独处、约会、聚会或商务等场景。
情绪会先被翻译成风味和场合倾向,再参与候选排序。例如 Romantic 更偏甜、花香和层次感;Melancholy 更偏苦、烈和烟熏。用户仍然可以调整这些倾向,不会被一个情绪标签锁定。
先用规则保证可喝,再让 AI 负责表达
配方由本地酒单库和打分规则确定。材料与基酒是强约束,情绪、场景、天气和时间负责调整方向;候选确定之后,AI 才参与解释与氛围文案。推荐逻辑和生成表达分开运行。
- 尊重现实库存:用户选中的基酒和材料必须进入候选约束;
- 遵守经典结构:IBA 配方优先,非经典配方使用 Sour 2:1:1 作为平衡基线;
- 结合当下环境:天气与时间只影响推荐权重,不覆盖材料事实;
- 限制模型职责:AI 解释为什么适合此刻,但不改写已经确定的配方。
实现上,Mood Spirits 用 React、TypeScript 和 Vite 做成一个移动优先的 PWA。推荐先走浏览器里的本地酒单和匹配规则,基酒、材料和配方能不能成立由代码决定;天气服务只改变候选权重,AI 再负责把命中的结果写成解释和氛围文案。图片也不是单点依赖:本地图库、AI 图和 Unsplash 按顺序兜底,Moonshot 请求则通过 Cloudflare Pages Function 代理。
条件冲突时,先尊重事实
情绪、场景和材料并不总会指向同一杯酒。系统先检查用户真正拥有的基酒和材料,再用经典配方与平衡规则判断是否可执行;情绪和场景负责候选排序,天气与时间只做弱调整。如果强约束无法同时满足,结果会降级为 Close match,并明确指出缺少什么、哪些条件没有命中。
- 第一层是事实:基酒、材料与配方是否真实可执行;
- 第二层是结构:酸甜苦烈是否满足可接受的平衡基线;
- 第三层是偏好:情绪与场景如何改变候选顺序;
- 最后才是环境:天气与时间只做小幅修正,不推翻前面的事实。
把「为什么是这杯」留在结果里
结果页里的 Why this drink 直接来自打分过程留下的证据,而不是模型事后补的一段漂亮话。用户可以看到基酒是否命中、场景为何适合、情绪对应了哪些风味,以及天气和时间怎样改变了排序。
- 材料命中是事实证据;
- 情绪与场景是偏好证据;
- 天气与时间是弱环境证据;
- 条件不足时展示 Close match,而不是假装精准。
这种解释也给推荐留出了诚实的退路。当自定义材料没有命中,或条件彼此冲突时,系统会说明它给出的是接近推荐。情绪产品可以有诗意,但不能拿诗意掩盖不确定。
氛围也参与选择反馈
天气和时间会改变候选权重,动效与音乐则把「此刻适合什么」反馈给用户。早晨、午后、夜晚和深夜会出现不同候选;酒体颜色、液面和音乐把结果变成可以感知的状态。
- 液面动画和陀螺仪倾斜,让酒杯对设备动作产生回应;
- 配方翻转把「看到推荐」自然过渡到「准备制作」;
- MusicCard 与双语短句延续酒的情绪,但不会改变推荐结论。
我怎么判断一次推荐是否成立
当前版本只验证推荐链路是否自洽,尚未证明用户一定更喜欢这杯酒。一次推荐至少要同时满足四个条件:用户能完成选择,配方在现有材料下可执行,Why this drink 能对应真实打分证据,条件不足时系统会主动降低确定性。
- 可完成:不懂酒名也能从情绪和场景走到结果;
- 可制作:材料、用量和步骤不会被氛围文案改写;
- 可解释:每条推荐理由都能追溯到实际命中的条件;
- 可质疑:用户能看见 Close match,并知道推荐哪里不完整。
这仍然只是规则与交互层面的验证。下一步需要让真实用户分别完成「只知道情绪」「材料有限」和「条件冲突」三类任务,并由有调酒经验的人复核配方边界,再判断 Mood Index 是否真的比传统筛选更容易。
最后保留下来的克制
最后保留的边界很具体:配方和材料命中由规则决定,Why this drink 必须能回到打分证据。AI 只调整表达,不改推荐结果。