从一句“我想喝会发光的蓝”到一杯真饮料:我的AI汽水机开发全记录

发布时间:2026/9/18 16:22:11
从一句“我想喝会发光的蓝”到一杯真饮料:我的AI汽水机开发全记录 从一句“我想喝会发光的蓝”到一杯真饮料我花了8个月做了一台AI汽水机先说一下这台机器干的事。你对着它说一句“来一杯晚风里的旧书店”它不出三分钟就从几十瓶糖浆、气泡水和酸味剂里给你调出一杯能喝的、带点木质香和微涩回甘的深色汽水。这不是噱头演示是我从硬件到软件全部自己折腾、耗时8个月做完的一台“中配”AI汽水机核心逻辑是用语言模型把自然语言描述“翻译”成一杯真实可饮用的碳酸饮料配方。整台机器能组合出超过50万种不同口味而且绝大多数口味你让任何人类调酒师来复现都会直接懵掉。这篇文章不是晒成品图而是把这台机器的完整设计思路、核心方案选型、硬件组装、AI调度链路以及我在8个月里踩过的坑全部拆开来讲包括很多踩了之后才想明白的细节。如果你也想做一台“能听懂人话”的饮料机或者只是好奇AI Agent怎么和真实物理世界打交道这篇文章值得你花五分钟读完。这个项目我来来回回做了三版第一版是纯按钮选择固定的8种口味第二版加了一个语音识别模块但配方还是写死的直到第三版才把大模型接进来真正实现了任意语言描述到配方映射。最终整台机器可以识别自然语言点单自动列出配方、控制硬件落杯、清洗管路、输出制作报告整个过程不需要手机App。8个月时间主要花在配方的语义映射逻辑和硬件的稳定性调试上真正写代码的时间其实只占了大概三分之一。1. 核心设计思路为什么“AI汽水机”不是噱头而是把“口味”变成了可计算的参数先说清楚这个项目本质解决的问题。市面上所有商用饮料机从头到尾都是“按编号出货”按一下1号键出可乐按一下2号键出雪碧它的配方是厂商预设好的消费者只能做选择题。我的目标是把这台机器的输出从“有限集合”变成“无限集合”让口味本身变成一种可以由语言驱动的参数空间。要做到这一步核心思想是把“口味”拆成三个可量化维度风味基调、口感层次和后调余韵。比如“晚风里的旧书店”被AI拆解成木质香基调、轻微烟熏感、干燥的纸张气息、微苦但回甘的后调。然后在机器内部建立一张风味映射表把“木质香”映射到烟熏风味的糖浆或特定比例的深烘焙风味液“纸张气息”映射到少量坚果类香精“微苦回甘”映射到汤力水底加一点焦糖糖浆。这样语言描述到具体配方的链路就完全走通了。1.1 为什么不直接让AI随机生成配方而是要做“语义映射”最开始我的想法更粗暴直接让大模型给我输出任意配方比如“桂花糖浆15ml、气泡水200ml、青柠汁3ml”。但实测了几轮发现根本没法用。大模型对真实世界的味觉记忆并不具体会生成大量现实中不存在或者互相冲突的配方组合比如同一杯饮料里同时加薄荷和榴莲香精或者推荐了一个根本买不到的原料。所以后面我转变了思路风味映射表是预设好的AI只负责输出“风格描述词”再通过映射表翻译成具体的原料组合。相当于大模型是“创意总监”配方引擎才是“真正的调酒师”。AI负责提供口味想象的自由度配方引擎负责保证结果的真实可饮性。这个解耦是我这个项目里最重要的架构决策没有之一。1.2 50万种口味是怎么算出来的50万这个数字不是随便夸大。我的原料库固定为24种风味糖浆、8种基底液气泡水、汤力水、苏打水、冷萃茶等、12种酸味/苦味调节剂柠檬酸、青柠汁、柚子汁等。每次出杯会从所有原料里任选2到6种组合每种原料的用量有独立的档位5ml档、10ml档、15ml档、20ml档最终再叠加8种基底和碳酸度调节无气、微气泡、重气泡三档。简单做一下组合估算24种糖浆选3种是2024种组合每种还有4个档位光糖浆部分就有远超千种变化再乘上基底选择、附加调节剂和气泡度档位总组合数确实突破了50万。实际实现里我并没有枚举所有组合而是用一套约束规则在生成时动态过滤冲突项这个后面会在配方引擎部分细讲。1.3 中配的定义既不是低成本玩具也不是工业级怪物为什么标题强调“中配”因为很多人在做类似项目时很容易走向两个极端。低配版就是树莓派加几个电磁阀用继电器控制水泵能出杯但精度和稳定性非常差流量全靠计时估算清洗系统几乎没有连续做三杯口感就全变了。工业级高配则是直接用蠕动泵加质量流量计加PLC控制全套下来光硬件就要近两万对个人DIY来说性价比极低。我选择的是中间路线用注射泵和蠕动泵混合方案注射泵负责小剂量风味糖浆精度能到0.5ml蠕动泵负责气泡水和基底液输送流量通过霍尔传感器闭环反馈。整台机器BOM成本控制在3500元左右但硬件的稳定性已经非常接近商用设备的基本需求。2. 硬件选型与整机架构一台“听得懂话”的饮料机到底由什么组成整个硬件系统我从功能上划分为五个子系统核心控制板、语音采集与播放、泵送与定量控制、碳酸化与冷却模块、清洗与废液回收。下面把这五个子系统的选型逻辑和组装过程中的关键细节列出来。核心控制板我选的是ESP32-S3原因有三个自带Wi-Fi和蓝牙便于后续对接大模型API时走无线网络算力足够跑本地语音唤醒词IO口数量刚好满足我这套系统需要控制的8路泵、6路电磁阀和多路传感器。如果你想做更复杂的扩展可以上树莓派但对我来说ESP32-S3加一个串口转USB接到电脑主机已经足够。2.1 泵送系统不同原料为什么用不同的泵方案这是整个项目里踩坑最多的部分。最早我用的是微型隔膜泵可以自吸流量不小但控制精度惨不忍睹启动时有明显的延迟而且流量随液面高低变化。后来改成用小体积的蠕动泵用步进电机驱动蠕动泵的原理决定了流体只在软管里流动不接触泵体清洗非常方便精度也高不少。风味糖浆这种小剂量原料最终选定的是注射泵方案一个20ml的注射器加一个丝杆步进电机分辨率能做到0.02ml对于一次出杯只需要5到15ml的糖浆来说精度完全溢出。气泡水、苏打水这些大流量液体用蠕动泵虽然精度不如注射泵但出液速度快500ml水能在20秒内完成对于饮料机来说这个速度体验才会好。2.2 流量反馈为什么不能只靠泵的转速推算液体体积蠕动泵存在管壁磨损和液体黏度差异的问题同样是转速200转/分钟输送黏稠糖浆和输送水的实际体积相差可能达到15%。我一开始偷懒没有加流量反馈直接按泵速乘时间估算结果做出来的第一杯“柠檬气泡水”味道极其随机轻则偏淡重则齁到咽不下去。后面我在每条输液管路上加了一个霍尔流量计利用液体流动带动磁性叶轮转动产生脉冲控制器通过计算脉冲频率得到实时流量。这样泵启动后的前两秒是开环快速注液等流量计信号稳定后再切到闭环PID调节最终出杯的体积误差控制在3%以内。2.3 碳酸化模块家庭场景下如何实现“刚打出来的气泡感”市售瓶装气泡水放久了气就弱如果你想让这台机器真的比买瓶装水更好喝就要在出杯前做即时碳酸化。我用的是一个小型二氧化碳钢瓶加碳酸化罐的方案先把基底液泵入耐压罐体然后通入CO₂并在低温下持续搅拌30到60秒让二氧化碳充分溶解再通过出液口灌装到杯中。这里的核心参数是“碳酸化温度”和“罐压”。温度越低CO₂溶解度越高所以我整个碳酸化罐都包裹了半导体制冷片把液体温度控制在4到6摄氏度罐内压力维持在32到38psi。这个条件下打出来的气泡水气泡细密程度和市售玻璃瓶装苏打水相当对比测试盲测过几次朋友基本分不出来差别。2.4 清洗系统AI饮料机最容易被忽视的致命环节如果你的机器一天只做三五杯那无所谓但如果像我这台一样连续出杯管路里残留的糖浆会在几小时内滋生细菌第二天第一杯出来就带一股馊味。清洗系统的设计思路是“每次出杯后自动执行短清洗每天结束后执行深度清洗”。短清洗是制作完成后用纯水正向冲洗所有过液管路15秒把糖浆残液顶出去。深度清洗是每天最后自动运行先用食品级柠檬酸溶液循环冲洗10分钟再用纯水循环冲洗5分钟最后用压缩空气把管路吹干。这部分的成本只增加了大概300元但让这台机器的实用性提升了一个数量级。3. 配方引擎如何把“你的一句话”变成“具体的毫升数”这是整个项目里我花了最多时间打磨的软件模块也是“AI汽水机”和“普通饮料机加个语音模块”之间真正的分水岭。配方引擎负责处理大模型输出的“创意描述”把它变成硬件能执行的精确指令。整个流程分四步解析自然语言输入、识别风味关键词、查映射表生成候选配方、按约束规则校验并输出最终方案。3.1 解析自然语言输入不只是做关键词匹配最开始的实现确实就是关键词匹配提前在代码里写死“柠檬”对应柠檬糖浆“薄荷”对应薄荷糖浆识别到哪个词就加哪个。但这种方案很快遇到瓶颈用户说“一杯夏日傍晚的清爽饮料”时没有任何一个词是直接对应原料的关键词但人类调酒师能听懂这句话想表达的是“清爽、微酸、冰凉、果味偏柑橘类”。所以我在输入端接入了大模型做语义解析。用户说话后先通过语音识别转成文本再把文本发给大模型要求输出结构化JSON格式如下{ mood: [清爽, 冰凉], flavor_profile: [citrus, herbal], intensity: 0.7, sweetness: 0.4, sourness: 0.6, sparkling_level: 2 }这个JSON是配方引擎的输入它不关心用户具体说了什么词只关心用户表达的情绪、风味倾向和强度。后面再用这些字段去风味映射表里找对应的原料组合。3.2 风味映射表把“木质香”变成“8ml烟熏风味液”风味映射表是整个配方引擎的地基。我的做法是先定义一套完整的风味标签体系比如果香类分为柑橘、浆果、热带水果、核果植物类分为草本、木质、辛香、花香甜感类分为焦糖、蜜糖、枫糖、甘草还有苦味、酸味、矿物质感和烟熏感等特殊维度。每个风味标签对应一种或多种原料组合。比如“木质香”的映射是云呢拿风味液5ml加少量苦精“烟熏感”映射到烟熏风味糖浆8ml“干燥纸张气息”这个非常抽象的味道我经过反复调配最终用的是少量坚果味糖浆加微量苦味剂。这并不意味着AI理解了什么是“木质香”而是机器通过映射表把人类语义词和物理世界的原料剂量桥接起来最后达到的效果是你说出的每一个抽象感受都有对应的味觉表达。3.3 配方校验规则为什么生成结果要“过一道安检”大模型输出的风味标签即使再准确直接翻译成配方也可能出现“黑暗料理”。所以配方引擎最后一步是做硬性约束校验我的规则只有四条单杯饮料的原料种类不超过6种避免味道互相掩盖糖浆总用量不超过25ml否则甜度会完全压住其他层次必须有一个“基底液”例如气泡水、冷萃茶不能全是浓缩物苦味剂和酸味剂如果同时存在各自的用量都不得超过阈值的60%这四条规则看似简单但实际运行中过滤掉了大约40%的候选配方。比如大模型曾经生成过“抹茶糖浆12ml、烟熏风味液10ml、柠檬酸5ml、金桔糖浆15ml”的组合一看就是创意爆棚但喝起来肯定要命的东西直接被校验规则拦下。3.4 把抽象描述变成具体参数我用的提示词模板因为大模型的输出格式直接决定了配方引擎能不能正常工作所以提示词设计非常关键。我固定使用的系统提示词是你是一个创意饮料配方设计师。你只负责输出JSON不要输出任何其他文字。用户会给你一句对饮料的描述你需要解析出以下字段 mood整体情绪氛围使用2-3个中文形容词 flavor_profile风味倾向从给定列表中选择1-3个 intensity风味强度0.0到1.0 sweetness甜度0.0到1.0 sourness酸度0.0到1.0 sparkling_level气泡强度0到30为无气3为强烈气泡 不要输出任何你想象中不存在的原料不要尝试包含未在列表中的风味词汇。关键是在提示词里明确限制输出范围和JSON格式让大模型的输出稳定、可解析。如果不做这个约束模型会自由发挥生成一堆花哨但不可用的结果。3.5 本地部署还是调用API我的选择和建议最开始我用的是云端大模型API效果很好但有一个致命问题一旦设备离线整台机器就是一堆废铁。后来我把语义解析这部分逻辑改成了本地部署小模型加云端大模型的双通道方案优先尝试调用本地模型如果置信度不够高再走云端API。本地部署我选的是Qwen系列的小参数量模型量化之后大概占2GB内存在一台老笔记本上就能跑一句话的语义解析耗时在1到3秒之间完全够用。这个方法不仅解决了断网问题还省了API调用费用。如果你也是做类似嵌入式或本地设备的AI功能强烈建议考虑本地小模型加云端大模型结合的方案体验会比单一方案稳很多。4. 软件链路与AI调度从“听到话”到“泵开始转”中间发生了什么整台机器的控制逻辑是一个流水线架构我把它分成五个阶段语音唤醒、语音识别、语义解析与配方生成、配方编译、硬件执行。下面按这个顺序讲清楚每个阶段的实现方式。语音唤醒用的是ESP32上的离线唤醒词引擎喊“小汽”就能唤醒。这样可以避免所有对话都被录下来发给云端隐私上安心很多。唤醒后开始录音录音结束后把音频文件通过Wi-Fi发给电脑端的处理服务。4.1 语音识别中文口语识别方案怎么选语音识别这块我对比过多个方案。在线方案识别率很高但是延迟不稳定有一次用户说完话等了整整18秒才开始动体验太差。最后我本地部署了开源语音识别模型在CPU上跑一段5秒的语音识别耗时约1.5秒准确率对于饮料这种垂直场景足够了。这里有个技巧可以在语音识别之前先做一次简单的音频处理把底噪去掉、音量归一化识别准确率能提升不少。还有一个垂直领域的技巧——提前给识别模型灌入饮料相关的自定义词库比如“气泡水”“汤力水”“糖浆”“不加冰”这些词识别出错率会明显降低。4.2 配方编译从JSON到泵送指令的转换过程配方引擎输出的JSON还只是一个“配方描述”不是硬件能执行的指令。中间还需要一个编译步骤。比如JSON里的“sparkling_level: 2”会被编译成启动碳酸化模块、设定罐压到35psi、碳酸化时长45秒。“base_liquid: bubble_water”会被编译成打开纯净水泵注入150ml纯净水到碳酸化罐等待碳酸化完成再开启出液阀。这个编译层就是把“配方逻辑”和“硬件控制”解耦的关键。如果未来换了不同的硬件方案只需要改编译层的映射关系配方引擎完全不用动。4.3 并发控制与制作时序先做什么后做什么很重要出杯顺序不是简单地从配方里一条一条执行而是要考虑效率和味道的平衡。我优化后的时序是这样的碳酸水准备和风味糖浆泵送可以并行因为风味糖浆是先泵入杯中碳酸水是后灌入两者不存在管路冲突。先把糖浆和调节剂按顺序泵入杯中再启动碳酸化罐的出液阀注满气泡水最后用一个小搅拌电机搅拌3秒完成混合。有一个细节有些风味糖浆在刚注入杯子里时还没和碳酸水混合如果你此时只扒着杯口闻会闻到一股非常浓烈的香精味但搅拌后味道就正常了。所以搅拌步骤不能省搅拌时间也别太长时间太长会让碳酸气泡损失过多。4.4 设备的“主动表达”机器怎么告诉你它做完了机器做完饮料后不只是亮个灯完事。我在出杯口旁边加了一个小型电子墨水屏上面会显示这杯饮料的风味标签、配方组成用人类能看懂的语言描述以及一段自动生成的“品鉴说明”。比如你做了一杯“晚风里的旧书店”屏幕会显示“木质香打底微苦回甘有干燥纸张的余韵建议小口慢饮”。这个功能最初只是觉得酷后来发现它带来了一个非常意外的价值用户在等待饮料时有了阅读内容会觉得制作过程更值得等整体的体验感提升了一大截。5. 8个月开发过程中的关键迭代节点失败复盘有时候比成功经验更有价值这部分是写给那些真的打算复刻或者做类似项目的朋友的。我先承认一个事实这个项目能做到现在的完成度不是因为我一开始就想得很清楚而是因为走了太多弯路把每条死路都试了一遍。5.1 第一版失败记录把AI当成“万能配方生成器”第一版我的架构非常简单粗暴接上大模型API把用户说的话原封不动发给它让它返回配方JSON然后直接执行。结果就是前面提到过的各种问题AI会给不存在的原料、会给互相冲突的用量、执行出来的饮料难喝到怀疑人生。这一版最重要的是让我意识到大模型不应该直接控制物理设备它应该只负责它擅长的“语义理解”部分剩下的全部交给确定性代码去完成。这是我整个项目最核心的认知转变。5.2 第二版失败记录稳定性问题连续出杯时的“翻车”第二版已经做完了配方引擎和基础硬件但连续出杯时会频繁出问题第二杯比第一杯淡第三杯直接管路堵塞。排查下来原因有两个一是流量计校准只做了一次实际流量会随管路内壁附着糖浆而变化二是清洗系统在连续出杯模式下没有触发旧液残留和置换不彻底导致每杯的混合比例都在变。解决方式是增加了一个“流量实时校准”的逻辑每次出杯前先执行50ml纯水过流测量实际脉冲数动态修正流量系数。这样即使管路状态变化每次出杯也能保持相对稳定的精度。同时把清洗逻辑改成了“按杯数触发”而不是“按时间触发”。5.3 第三版为什么最终版本比预期慢了两个月第三版其实是整个项目里最顺利的阶段主要工作是打磨细节和修修补补。但还是比预期晚了两个月原因是碳酸化模块的稳定性。前两版直接用现成的家用气泡水机改的实际连续工作半小时以上就会出现CO₂回压异常导致液体从泄压阀溢出弄得整个桌面都是气泡水。最终解决方案是自己设计了一个带压力传感器的小型碳酸化罐体软件层增加了压力闭环控制根据实时压力值决定CO₂通入的占空比而不是简单的定时开关。这套系统调了大概三周才稳定下来但效果立竿见影连续出杯20杯也不会再出一次事故。6. 常见问题与排查实录一份可以直接照抄的避坑手册最后这部分是很多人私信问的共性问题我整理成一张速查表每一条都是真实遇到并解决过的。现象根因解决方案第一杯正常第二杯偏淡管路中残留纯水稀释了糖浆出杯前先执行20ml“预排液”排掉残留水糖浆滴漏停泵后还在流注射泵密封圈磨损反向虹吸每次使用完执行一次负压回抽定期更换密封圈碳酸化结束后气压过高溢出压力传感器校准漂移每周执行一次双点校准同时在软件中加入罐压上限保护大模型返回的JSON偶尔解析失败模型输出带额外说明文字在提示词中强制“只输出JSON”并用正则兜底清洗非法字符本地模型语义理解太差小模型对抽象描述的推理能力有限增加云端API兜底本地低置信度时自动切换云端清洗后管路仍有异味柠檬酸冲洗后未彻底吹干残留细菌滋生增加压缩空气吹干步骤确保管路内无残余水分6.1 关于“AI生成”的落地心得很多人看到这类项目的第一反应是“这不就是把ChatGPT接进了一台饮料机吗”。实际做完之后我的感受是AI部分反而是整个项目中最简单的一环。真正难的是如何把AI的输出和真实物理世界建立可靠、稳定、可复现的映射关系。语言模型说“加一点苦味”这句话本身没有意义只有当“一点”对应到“2.5ml苦味剂”、“苦味”对应到“安哥斯图拉苦精”时它才变成了机器能理解的指令。我可以负责任地说如果只把AI当作一个“更聪明的语音命令解析器”那它做出来的饮料大概率非常难喝。但如果你把它当作“创意灵感大脑”配上严格约束的配方引擎、稳定可靠的硬件执行层你会得到一个令人惊喜的结果。6.2 给想复刻的朋友的几个具体建议如果你看完这篇也想做一台类似的AI饮料机基于我踩过的坑给你几个非常具体的建议不要一开始就追求“AI任意描述”先把固定20种口味的硬件稳定性做到连续出杯不翻车再考虑接AI风味糖浆的种类控制在20到30种之间太多会导致管路复杂度和成本成倍上升一定要设计清洗系统否则机器放三天再用第一杯几乎一定会喝坏肚子大模型的输出格式必须用JSON Schema严格约束不要给它任何自由发挥的空间流量闭环反馈不是可选功能而是必需功能开环控制的饮料机做不出稳定口感关于预算如果不算人力成本纯物料成本大概4500元ESP32-S3开发板60元、注射泵四个共520元、蠕动泵三个共480元、霍尔流量计六个共180元、碳酸化罐和CO₂钢瓶共1200元、半导体制冷片及电源800元、各种管路阀件接头500元、电子墨水屏180元、其他杂项约500元。我个人的体会是做这类“AI加物理设备”的项目真正的护城河永远不是某一个单独的AI模型而是你把AI能力变得“可用”的那套系统工程能力。8个月下来最大的收获不是这台机器本身而是对“语义到物理参数”这条链路有了极其深刻的体感认知这种认知是光看文档或教程完全无法获得的。