我的作品 吃有数

cmlanche() · September 18, 2026 · 15 hits
Shipped

吃有数

拍照识别卡路里,科学减肥

吃有数的开发故事

从2025年11月17日的第一条提交 init calshot,到2026年9月17日的 1.9.4。

十个月,1225 次提交,三个名字,三端一套业务代码。

这不是一份功能清单,是这个产品真正走过的路。


起点:问题比名字更清楚

吃有数一开始并不叫吃有数。仓库叫 Calshot,产品想解决的事也很窄:

拍一张照片,把这一顿记下来。

不是不知道该少吃、该多动。真正让人放弃的,是每一顿都要搜索、估重、换算、填写。一顿饭花几分钟不算难,难的是早餐、午餐、晚餐,日复一日。

2025 年 11 月中旬,项目按阶段开工。后端先于客户端:Spring Boot、MySQL、MyBatis-Plus、Redis,图像识别接火山云豆包。阶段文档里写得很工程化——上传、识别、确认、写入食物日志;前一天剩余热量最多补 50%,运动消耗也按一半加回预算。这些后来成了产品里不太显眼、但很「吃有数」的细节。

第二天,Flutter 客户端生成。导航从英文改成中文。底部 Tab、进度页、目标、食物日志、发帖换会员,都在同一周里陆续出现。

那一周的提交信息几乎全是「update」「修复编译不过」「补充未完成的功能」。这很像一个人同时在写服务端、调模型、画页面:先让闭环转起来,再谈漂亮。

第一周结束时,产品已经能做这些事:拍照识别、确认入账、看当天摄入与运动、记体重、设目标。它还不是一个健康管理平台,只是一个能把照片变成记录的原型。

但原型很快暴露一件事:AI 能说出「这像一碗牛肉面」,却未必知道用了多少油、面有几两、汤喝了多少。 对中餐尤其如此。同名菜品的原料、做法和分量可以差出一整个热量区间。

所以产品从第一天就不能把识别结果当成答案,只能把它当成可编辑的初稿。这个判断后来几乎决定了整条记录链路:改名称、改分量、改餐次、改时间、识别前补糖油盐和烹饪方式,都不是「高级功能」,而是诚实的前提。


三个名字:从技术语言回到人话

名字换了三次,每一次都对应一次定位收束。

2025.11 · Calshot

能力原型。仓库、包名、服务端 group 都还带着这个词。重点是验证「照片能不能成为饮食记录的起点」。

2025.12.20 · CalSnap

更像一款以相机为核心的消费级应用。文档、宣传总纲、PRD 都切到这个名字。Slogan 是「3 秒记录,科学减重」。

2026.01.12 · 吃有数

不再强调 AI 多神奇,而是强调记录变轻、数据可理解。

CalSnap 那一个月,产品第一次形成完整闭环:首页展示当天摄入、运动和剩余预算;追踪蛋白质、碳水、脂肪;支持食物库、收藏和自定义食物;识别结果可以改。同期接上短信登录、微信支付、支付宝、苹果内购(iOS 走 RevenueCat),官网也在 12 月 7 日上线。

12 月 24 日,语音识别热量进了主路径。不方便拍照时,可以说「中午一碗牛肉面,加一个卤蛋,汤只喝了一半」。几天后,识别设置被放到更显眼的位置:用户可以自己补 prompt,也可以点「少油」「加糖」「带酱」。

到2026年1月8日,一次识别支持多图和餐次标记。聚餐不再被强迫塞进一张照片。

四天后,应用名称改为吃有数。

「有数」不是说镜头能把每一滴油精确到小数点。它表达的是一种更现实的状态:不必把生活过成实验室,但至少知道今天大概吃了多少、蛋白质够不够、离目标还有多远。

技术语言让位给用户语言,是这个项目真正开始像一个产品的时刻。


不要做另一个薄荷健康

仓库里有一份很早的竞争策略文档,标题直接写着「个人开发者」。对面是薄荷健康:千万用户、食物库、社区、商城、课程、问诊。

策略写得很克制:不要试图做另一个薄荷健康。

垂直、极简、中餐、外卖、3 秒记录。界面少一点,识别快一点,把精力放在记录入口和首页反馈上,而不是内容生态。后来对照竞品时,这个选择被说得更清楚:

  • 薄荷健康更像一座完整的体重管理商场;
  • MyFitnessPal 的护城河是数据库和设备连接;
  • YAZIO 把食谱和断食结合得更成熟;
  • Cal AI 把「拍一下」做到最前面。

吃有数选的是另一条路:少做商城和大社区,把记录方式适应生活,而不是让生活适应记录方式。拍照、语音、文字、标准库、自定义食物和食物组,几条入口并存。今天拍、明天说、后天从常用里点一下。

早期 PRD 里甚至把「社交分享」标成 P2。后来结伴、小圈、发帖领会员都做了,但它们始终是增长和陪伴,不是产品的第一句话。第一句话一直是:今天还能吃多少。


从「一顿饭」拉长到「一段生活」

改名之后,产品的时间尺度开始变长。

2026 年 1 月。 鸿蒙适配启动。iOS 桌面小组件第一次进仓库,卡片一开始是异常的。会员价格整体下调,永久会员从 288 降到 168,新手会员改为 7 天。深度识别、重新识别、付费墙统一,都在这个月发生。

2026 年 2 月。 为了过审:换 Logo、改隐私协议、给 AI 生成内容加标记。食物库支持切到本地来源。经期开始以「体重标记」的形式出现——男性不展示。产品还没有把周期当成一等公民,但已经承认:有些体重波动不是昨天多吃了。

2026 年 3 月。 这是记录系统成型的一个月。苹果健康同步、喝水(含快捷容量和自定义目标)、轻断食、身体围度。小组件开始展示三大营养素和喝水。语音也可以记运动。

喝水是一个很小、但很能说明产品判断的功能:高频、低信息量。150、250、350、500 毫升直接出现。为了记一杯水打开长表单,是典型的产品摩擦。

2026 年 4 月。 结伴减肥完成。健康分析上线。轻断食从日历提醒改成常驻通知,iOS 不再走服务端推送。围度支持自定义。iOS 退款后会员资格没有取消,被当成事故修掉。

2026 年 5 月。 结伴信箱、待确认入圈、底栏角标、UGC 大模型审核。熟人关系一旦做出来,就要处理已注销好友、隐私百分比、打气和已读。社交功能的成本,从来不是第一版 UI。

到这里,吃有数已经不是「拍照算热量工具」。时间尺度变成四层:

  • 一顿饭:识别、校正、入账;
  • 一天:摄入、运动、饮水、营养素;
  • 一周或一个月:体重趋势、打卡、断食;
  • 更长时间:BMI、围度、进度照片、目标变化。

单日体重更像天气,长期趋势才接近气候。这个判断写进了后来几乎所有进展页的设计里。


过审、付费、增长:产品开始碰到真实世界

健康 App 做出来只是一半。另一半是商店、支付和「人为什么愿意留下来」。

支付比功能更早成为现实问题。2025年12月10日,微信、苹果、支付宝三条链路写进提交;第二天发现 iOS 必须走苹果支付,随后接入 RevenueCat。安卓微信支付要等应用上架才能申请,于是入口一度被关掉。2026 年 8 月才重新打通,又因为审核风险暂时隐藏。支付从来不是「接一个 SDK」——它跟着平台规则、上架状态和回调可靠性一起走。

苹果审核留下了三份专门文档:内购产品定位(Guideline 2.1)、订阅时长(3.1.2)、隐私(5.1.1)。审核团队提交了 7 个内购,却只找到 3 个。回复模板里要从沙盒账号、设置页、付费购买按钮一步步写起。2 月为了过审换 Logo、改隐私协议;9 月华为要求登录页必须勾选隐私协议。上架不是发布按钮,是一轮轮把产品翻译成审核语言。

增长路径从第一周就埋下了:发帖获取会员。后来演变成审核后台、质量分、共建积分、会员任务,再变成「免费领会员」活动——小红书和抖音发帖、评论、点赞阶梯兑换。2026 年 9 月,活动整页 H5 化,永久会员门槛提到 300 赞。发帖从「换几天会员」变成一套可运营的增长系统,也逼着产品补上远程开关、测试账号屏蔽、审核搬到 Web 后台。

2026 年 7 月,女性周期从备注升级成上下文:首页和目标页展示经期或黄体期,黄体期可自动小幅上调热量。它不是给所有人套同一个结论,而是可开关、可配置。同月,1.7.0 成为后来对外讲产品故事的基准版本。

会员本身也在反复定价。永久会员从 288 到 168,再设计下线倒计时;新用户 7 天会员从首页挪到引导页第一屏;免费用户日记累计 10 篇。付费墙、额度、任务、案例面板,都是在「记录要轻」和「模型调用要付钱」之间找平衡。


工程上的一次长大:一套业务,三端双壳

鸿蒙不是 8 月才出现的。2026 年 1 月就已经在适配保存图片和语音页。真正的结构变化发生在 8 月 15 日前后:

  1. 业务代码抽到 packages/calshot_app
  2. iOS / Android 一个壳,鸿蒙一个壳;
  3. 同一分支上三端都能编过。

共享包的 pubspec 注释写得很具体:磁盘只放一份 assets,壳工程用符号链接声明,否则安装包会打两份。这类细节不是架构图上的框,是踩过坑之后留下的约束。

原生叠层底栏也试过。iOS 26 和鸿蒙一度改走系统原生 Tab,随后是一串修复:挡住点击、加号偏下、鸿蒙手势被占、子页 SafeArea、首帧闪原生栏。8 月 21 日,iOS 26 原生底栏被移除,三端重新统一成 Flutter 自绘导航。能用系统能力就用,用不顺就收回来——这比坚持「更原生」更接近独立开发的节奏。

同月发生的事还有很多,几乎像把产品又做了一轮:

  • 食谱库与膳食计划上线,主 Tab 从断食改成食谱入口;
  • 相机双 Tab,接入 AI 减法:拍饭前和饭后,按实际吃掉的分量入账;
  • 桌面小组件统一三端视觉,补上 2×2 小尺寸和轻断食卡片;
  • 官网升级到 chiyoushu.com,补文档、SEO 和账号注销页;
  • Android 接入 Health Connect。

8 月 31 日,版本到 1.8.0。用餐详情支持语音/文字 AI 修正,条码、心情日记、自由断食可选最长时长,在 9 月继续补上。到 1.9.4,产品已经覆盖 iOS App Store、华为、小米、荣耀、OPPO、vivo 和鸿蒙应用市场。

技术栈没有戏剧性的推倒重来。后端仍是 Java 17 + Spring Boot,客户端仍是 Flutter,识别仍走大模型,语音走腾讯云 ASR,分析后来接了 OpenPanel。变的是边界:业务和壳分离、三端行为对齐、小组件跨进程刷新、识别额度与会员权益绑在同一套规则上。


一条一直没变的原则

回头看提交历史,功能在涨,原则几乎没变。

AI 负责把空白表单变成一份八成可用的草稿,人负责补上镜头看不见的两成。

深度识别、多图、语音、文字、AI 减法、识别设置、分量编辑、事后改餐次和时间,都是这条原则的不同入口。没有一条在承诺「一张照片就算准」。热量与营养结果写进商店文案、隐私政策和几乎每一篇对外说明:估算,不替代医生或营养师。

另一条原则是关于摩擦的。记录方式必须迁就生活:拍不了就说,说不清就搜,常吃的建成自己的食物或食物组。喝水点一下。没吃完拍剩余。走出餐厅也能补记昨天。

第三条是关于时间的。首页先回答今天还能吃多少;进展页把点放回趋势里。经期、盐分、睡眠造成的体重抖动,不应该被红色数字审判。

功能可以变多。这三条如果丢了,吃有数就会变回又一个卡路里计算器,或者又一个假装精确的 AI。


时间线

2025.11.17 init calshot。后端阶段 3、4 同一天合入。豆包识别、卡路里补偿、BMI。

2025.11.18 Flutter 客户端生成。中文导航、底部 Tab、进度与目标。

2025.11 下旬 换模型、优化提示词;图库识别;首页营养素进度;发帖换会员。

2025.12.01 短信登录;用餐/称重提醒。

2025.12.07 官网;异步识别。

2025.12.10–11 微信 / 支付宝 / 苹果支付;iOS 改走 RevenueCat。

2025.12.20 应用名改为 CalSnap。

2025.12.24 语音识别热量。

2026.01.08 多图识别 + 餐次标记。

2026.01.12 应用名改为吃有数。

2026.01.15 鸿蒙适配启动。

2026.01.22 iOS 小组件。

2026.02 过审:换 Logo、隐私协议、AI 生成标记。

2026.03 苹果健康、喝水、轻断食、围度。

2026.04 结伴减肥、健康分析、自定义围度。

2026.05 结伴信箱、圈子、UGC 审核。

2026.06 会员任务体系;OpenPanel;图标更新。

2026.07 经期相位与热量调整;免费领会员活动;1.7.0。

2026.08.11 食谱库与膳食计划。

2026.08.15 业务抽包,iOS/安卓/鸿蒙双壳。

2026.08.16 AI 减法。

2026.08.20 官网 chiyoushu.com。

2026.08.31 1.8.0;用餐详情语音修正。

2026.09 经期改版、免费领会员 H5、日记、条码;1.9.4。


现在,以及还没做完的事

今天的吃有数,核心功能可以收成六句话:

  1. AI 拍照识别中餐,结果可改;没吃完用 AI 减法。
  2. 不方便拍就语音、文字或食物库;常吃的建成自己的模板。
  3. 首页先告诉你今天还能吃多少,并追踪三大营养素。
  4. 体重、围度、进度照片、打卡,把单日数字变成长期变化。
  5. 运动、健康同步、喝水、轻断食、可选的经期上下文。
  6. 食谱、AI 分析、心情日记、熟人结伴、桌面小组件。

它更适合经常吃中餐、外卖、食堂,懒得逐项搜索,又愿意确认一下 AI 草稿的人。它不适合替代诊疗,也不适合假装实验室级精度。

十个月前,问题被理解成「怎样识别一盘菜」。后来才发现用户真正要的是四件事:这顿饭能不能轻松记下;今天的状态能不能一眼看懂;AI 不确定时能不能方便地改;一个月后能不能看到自己到底发生了什么。

仓库还叫 calshot。包名、url scheme、服务端 group 都还留着出生时的名字。产品已经不叫这个了。这很像独立开发者的项目:走得很快,旧名字来不及擦干净,但方向一次比一次清楚。

吃有数,不是让每一口都变成压力;是让每一个选择,心里多一点数。


No Reply at the moment.
You need to Sign in before reply, if you don't have an account, please Sign up first.