打开冰箱,番茄、半碗熟米饭、半个洋葱,还有几样东西——单看都是食物,凑一起却不像一顿饭。朋友那边有菠菜和鹰嘴豆,另一位有胡萝卜和酸奶。谁都没有像样的计划,合起来却几乎凑成一餐。

打开网易新闻 查看精彩图片

这个再普通不过的晚饭时刻,成了 New Dish 的起点:一个本地优先的社区厨房,把一到三户人家的食材,变成一份真实、安全的食谱。

一个人也能用。输入手头有的东西、拍一张食材清单、或者直接拍冰箱,New Dish 会给出食材建议,请你逐项确认,套用整组的过敏与偏好,再去匹配一份有据可查的食谱。

作者设想的付费人群是合租室友、共享公寓、宿舍、小型社区厨房,以及想减少食物浪费的环保小组。付费版可以加共享每周食材库、保质期提醒、购物清单和私密家庭组。核心版本不注册、不产生 API 账单也能用。

从 CrowdChef 缩到一个小场景

第一版叫 CrowdChef,设想的是附近家庭互相发现、拼凑剩菜。听起来有趣,但摊子太大:定位、陌生人、信任、约时间、食品安全,全都在有人真正下厨之前就冒出来了。

于是想法被压缩成一个更小、更真实的瞬间,作者列了几条边界:

  • 一个人就该能用;
  • 几个认识的邻居或室友可以加入;
  • 每个人的过敏原都当作全组红线;
  • 结果必须是真能吃的食谱,不是 AI 即兴发挥;
  • 营养数据必须来自数据源,不能由模型自信地猜。

缩小之后反而更好。卡通界面和会动的辣椒向导 Peper 是后来才加的——晚饭规划该有点友好感,而不是像填税务软件。

识别归识别,事实归事实

架构上,New Dish 刻意把识别、食谱事实和呈现分开。流程是:冰箱照片或食材标签,经本地 OCR 与目标检测,交给人确认,再叠加过敏与饮食偏好,匹配经过核验的开放食谱,最后输出食谱、授权图片、步骤和来源营养,由 Peper 本地朗读。

印刷体食材清单用浏览器里的 Tesseract.js 处理。OCR 之前先缩放图片,做灰度、对比度增强,第一次结果弱时再跑一遍高对比度。冰箱照片则用 DETR ResNet-50 目标检测模型,通过 Transformers.js 在 Web Worker 里跑,图片不出浏览器。

最关键的是推理之后那一步:应用不自动相信它。作者第一次测冰箱照片,识别器只找到一个正确的词——苹果,周围全是无意义的碎片。流程技术上成功了,结果却没用。

修法是一串约束:把 OCR 输出和食谱数据集构建的词表比对,丢掉随机文本碎片,合并单复数重复项,冰箱检测要求更高置信度,只预选可靠建议,并且每一个食材都要用户亲手确认。

这次翻车改变了产品。一个自信的模型,不等于一个正确的模型。

不让语言模型编晚饭

早期原型让小语言模型直接生成食谱,很兴奋,直到作者问了自己一个更重要的问题:这东西我真会做出来吃吗?

一句通顺的话,不是食谱存在的证据。营养数据同理——模型能生成格式漂亮的卡路里和宏量营养素,和这顿饭毫无关系。

所以最终架构改用 UniTools Recipes v1,一个 CC BY-SA 4.0 的开放食谱集。每条记录包含食材用量、缩放规则、详细步骤、时间、授权图片,以及来源提供的每份卡路里、蛋白质、碳水与脂肪。

浏览器把确认过的食材和这份数据匹配,剔除与所选过敏原冲突的食谱,套用纯素、素食、无麸质、无乳制品、高蛋白、简单、限时等偏好,再按人数缩放用量。没有安全食谱匹配时,New Dish 会直接说没有,而不是为了不留白屏硬造一份。

可选的本地语言助手以 SmolLM2 360M Instruct 为主,Qwen2.5 0.5B Instruct 兜底,都走 Transformers.js,有 WebGPU 用 WebGPU,否则用 WASM。它们被明确排除在食谱事实和营养之外,只负责措辞——那里出错是麻烦,不是危险。Peper 的声音用本地 Kokoro 82M,加载失败就退回设备自带语音。

过敏排除对整组生效,当前清单包括花生、坚果、乳制品、蛋、麸质、大豆、鱼、贝类、芝麻、芥末、芹菜、羽扇豆和亚硫酸盐。界面仍提醒用户核对包装和交叉接触——软件没法替你检查厨房。邻居名字由用户自取,只存在浏览器里,图片和食材留在设备上,不需要账号。

整个应用是无构建的静态站点,托管在 GitHub Pages 上。

开放模型换来的四件事

作者认为开放创新在这里不是装饰,而是决定这个想法能不能落地。用闭源 API,每次拍照扫描、每次食谱请求、每句语音指令都可能变成计费请求,一个小工具在拿到第一个付费用户之前就先贵起来了;还得把别人家厨房和饮食习惯的照片传到他们没选的服务器上。

本地跑开放模型给了四个自由:隐私,冰箱照片和食材清单不出设备;低成本,用起来不产生增长的推理账单;可替换,SmolLM2、Qwen、DETR、Tesseract、Kokoro 都能换,不必围绕某一家供应商重做产品;诚实,模型输出可以被约束在它擅长的范围内,食谱和营养来自可检查的开放数据。

最值钱的是能对模型说不——加置信度阈值、加食材词表、要求人工确认,或者在安全敏感环节把它整个拿掉。闭源黑盒给的干预点要少得多。

第一个用户就是作者自己,站在冰箱前,指望相机功能看懂他肉眼已经看见的东西。它第一次并不漂亮,只回了一个正确的苹果和一堆胡话。这反而是最有用的反馈,因为它暴露了一个危险假设:把“模型返回了东西”当成“模型看懂了图片”。加上食材词表校验和置信度阈值后,他重跑那次失败输出,只有苹果活了下来。

目前还没有人为 New Dish 付过钱。作者选择直说,而不是为参赛编造增长数据。但产品已经收到几个真实需求:支持单人、显示每份核验营养、允许自定义邻居名字、绝不编造食谱。下一个真正的测试,是把它放进合租家庭用一周,看能不能帮他们救回至少一顿本来会放弃的晚饭。