我做了个不联网的 AI App:0 台服务器是怎么办到的
这个 App 有 AI,但我没有服务器。不是没钱买,是故意不买。代价我会一条条交代清楚。
这个 App 有 AI 功能,但我没有服务器。
不是没钱买,是故意不买。
前两篇讲了「吃好饭」怎么在 27 天里做出来、为什么定价 ¥18。这篇讲架构,也是我个人最想讲的一篇。
一、这是个反潮流的选择
现在做一个带 AI 的 App,标准姿势基本固定了:
用户注册账号 → 数据存你的云端数据库 → App 请求打到你的后端 → 后端拿着你的 API Key 去调模型 → 结果返回给用户。
这套架构成熟、好用、所有教程都这么教。它还有个巨大的商业优势:数据在你手里。你能看到用户怎么用、能做推荐、能做增长分析、能拿留存曲线去融资。
代价是你得养一套东西:服务器、数据库、鉴权、日志、备份、合规。以及一笔每个月都要交的账单。
这笔账单会反过来定义你的产品。有了固定成本,你就必须有固定收入,于是你必须做订阅;做了订阅,你就必须让用户天天打开。
我不想走这条路。所以吃好饭的架构是这样的:
零自建服务器。数据全部存在用户手机本地。AI 请求从手机直连 AI 服务商,不经过我任何一台机器。
二、三块拼图
第一块:本地存储,用 Hive。
所有数据——家庭档案、冰箱库存、菜谱、账单、青团团的成长记录——都写在手机本地的 Hive 数据库里。没有远程同步,没有账号体系,打开就能用。
人话翻译: 你的冰箱里有什么,只有你的手机知道。我不知道,我也没有任何办法知道。
第二块:AI 走 BYOK(Bring Your Own Key)。
用户在设置里填自己的 API Key。App 拿着这个 Key,从手机直接向 AI 服务商发请求,响应直接回到手机。
整条链路上没有我的服务器。我既不中转请求,也不看到内容,更不承担 token 费用。
人话翻译: 你自己去 AI 厂商开个户,钥匙在你手上。App 只是替你按按钮,账单是你和厂商之间的事,我不插在中间。
第三块:备份走用户自己的 iCloud。
App 有 iCloud 备份,写进的是用户自己 Apple 账户下的 iCloud 容器。我配置了容器标识,但容器里的东西属于用户,不属于我。
另外还有一条「导出同步码」的路,用来在家人设备之间搬数据。
人话翻译: 备份是你的苹果账号在备份,跟我没关系。我连你有没有备份都不知道。
三、代价是什么
这一节最重要。一个只讲好处不讲代价的架构介绍,可信度是零。
代价一:换手机很麻烦。
没有账号,就没有「登录即恢复」。换手机你得走 iCloud 恢复,或者用导出同步码手动搬。
这两条路都比「输入密码」麻烦。有些用户会在这一步骂人,我认。
顺便必须说清楚:本地存储意味着数据可能丢。 手机丢了、系统重装、误删 App,如果你没备份,数据就是没了。我做不到「绝不丢数据」这种承诺,也不会这么写。请自己定期备份,这不是免责声明,是真的请你去点一下那个备份按钮。
代价二:我看不到任何用户数据,调 bug 全靠用户描述。
这个是真的疼。
传统架构下,用户说「AI 给我配的餐里有我忌口的东西」,我去日志里一捞,请求、上下文、模型返回,一目了然,十分钟定位。
我现在只能问:您能截个图吗?您档案里忌口是怎么填的?您用的哪个模型?当时冰箱里有什么?
有时候来回问三四轮还复现不出来。有些 bug 我到现在都不确定修没修好,因为我没法验证。
没有可观测性,是我为这套架构付出的最大的一笔工程代价。
代价三:有一整类功能我永远做不了。
- 云端排行榜——我不知道别的用户吃了什么。
- 家庭实时同步——只能靠导出导入这种笨办法。老婆刚买的菜,我这边不会自动亮起来。
- 跨设备实时协作——iPad 和 iPhone 是两台各自独立的设备。
- 基于全体用户行为的推荐——做不了,也不想做。
这些不是「暂时没做」,是架构上就堵死了。除非推翻重来。
代价四:BYOK 的门槛,是我目前最大的没解决好的问题。
我得承认这个。
对工程师来说,「去开个 API Key 填进来」是十秒钟的事。对我妈来说,这句话里每个词她都不认识。
这直接把一大批用户挡在了 AI 功能门外。我在引导流程里做了详细的图文步骤,但那还是一道墙。
我没有好办法。能想到的替代方案(我出面中转、送体验额度)都要求我有服务器,那就回到起点了。这是这套架构最硬的疙瘩,我暂时只能承认它在那。
四、换来了什么
无账号。 打开就用,不要手机号,不要微信授权,不要「同意用户协议」。
无广告。
无数据收集。 不是「我们承诺不滥用您的数据」,是我根本没有收集数据的通道。这两句话的强度差得很远——前者是承诺,后者是事实。
服务器成本 0。
最后这条最关键,因为它决定了前面几条能不能长期成立。
我这个项目目前唯一确定的固定成本,是苹果开发者账号 ¥688 一年。没有服务器账单,没有数据库账单,没有模型 token 账单。
这意味着我不需要靠订阅活着。
这不是道德优越感,是结构决定的。一个每月要烧几千块服务器费的产品,就算创始人再理想主义,账单也会一步步把他推向订阅、推向广告、推向数据变现。我把这条路从架构层面堵死了,就不用天天靠意志力抵抗它。
上一篇讲定价时我说「订阅在我这里没有道德基础」,说的就是这件事。
五、那 AI 怎么才能聪明?——Context 工程
这一节是给工程师看的,但每段后面我都会翻译。
先说清楚问题在哪。
我没有后端,做不了模型微调、做不了 RAG 服务、做不了向量数据库。模型还是用户自带的——可能是个很强的旗舰模型,也可能是个很便宜的小模型。
所以在我这套架构里,AI 好不好用,基本不取决于模型多大,取决于我会不会攒 context、会不会选、会不会压缩。
这是本地 Agent 的真功夫。核心代码在 lib/services/ai_engine/context_engine.dart。
分层组装 system prompt
每次请求,我按固定优先级分层拼装 system prompt:
- 人设层 —— 青团团是谁、怎么说话
- 安全红线层 —— 过敏、忌口。这一层永不截断
- 此刻状态层 —— 冰箱现有什么、哪些临期、今天吃没吃、打卡状态
- 用户画像快照 —— 家庭成员、口味偏好、地域、预算区间
- 已装技能片段 —— 用户买了减脂教练,就注入减脂领域的判断规则
- 聊天记忆 —— 结构化提取的长期记忆
- 滚动摘要 + 最近对话 —— 早期对话压成摘要,最近几轮保留原文
超出 token 预算时,从低优先级往上截断。
也就是说,token 不够的时候,先砍掉最近的闲聊,再砍摘要,再砍技能片段……安全红线是最后一个走的,实际上它永远不会走。
人话翻译: 上下文空间不够的时候,宁可让团团忘记你上周聊过什么,也绝不能让它忘记你花生过敏。这个顺序是硬编码的,不是模型自己判断的。
这点我想强调一下:安全约束不能交给模型「注意一下」。 提示词里写一句「请注意用户过敏」是不可靠的,尤其在长上下文里。它必须是工程上的硬保证——这一层在拼装顺序里排第二,在截断顺序里排最后。
记忆管理
聊天记忆不是无限攒的。
- 封顶 30 条。 超了就淘汰。
- 入库前去重。 同一件事说三遍不会占三个坑。
- 安全类记忆最后淘汰。 「我不吃香菜」这条会一直待着,「我今天想吃辣的」会先被挤出去。
为什么封顶?因为记忆越多,每次请求的 token 成本越高——而这个成本是用户在付。一个无节制往上下文里塞历史的本地 Agent,是在花别人的钱。
人话翻译: 团团的脑容量是有限的,而且我故意把它限死了,不然你的 API 账单会变难看。
这里坦白一件事:30 这个数字是我拍的。
不是实验出来的,是我觉得「差不多够用又不会太贵」。我没有 A/B 测试的条件——没有服务器,就没有实验平台。这类参数在我这套架构里全靠手感,这也是零服务器的隐性代价之一。
记忆是可见、可改、可删的
App 里有个页面叫「团团记住的你」。
打开就能看到它到底记了你哪些事,一条条列着。可以改,可以单条删,可以一键清空。
这不是为了显得透明。既然记忆会影响 AI 给你的建议,你就该有权知道它记了什么、并且能改掉。模型记错了(这很常见),你不该只能重装 App。
人话翻译: 它记住的每一件事,你都能翻出来看,看着不顺眼就删掉。
一个具体例子
你问「今晚吃什么」,实际发出去的不是这五个字,而是一整包:
你是青团团 → 妈妈花生过敏、爸爸忌辣(不可截断)→ 冰箱里有西红柿两个、鸡蛋半盒、五花肉一块,五花肉后天到期 → 家在四川,本周餐饮预算还剩 180 → 装了「一周备餐大师」技能 → 记忆:不吃香菜 → 最近三轮对话。
人话翻译: 该说的都说清楚,再普通的模型也能给个像样的答案;什么都不说,再强的模型也只能瞎猜。
六、一个观点
我想用一个不那么技术的说法结尾。
现在很多 App 把「我们不收集您的数据」印在宣传图上,当成卖点。
我觉得这件事本身就有问题。
对一个工具类 App 来说——一个记冰箱的、一个记账的、一个写笔记的——不碰你的数据本该是默认设置,而不是需要额外表扬的美德。
它变成卖点,是因为默认值已经被行业改坏了。改坏的原因也很实在:数据能变现,能拿去讲增长故事。于是「不收集」从基线变成了需要付出成本才能坚持的选择。
我这套零服务器架构,说到底不是什么技术创新。它就是把默认值改回去而已。
它有代价。前面第三节我一条条列了:换机麻烦、bug 难查、一整类功能做不了、BYOK 有门槛。这些代价是实打实的,我没有办法把它们说成优点。
但我愿意付。因为付完之后,我可以在这个 App 的介绍里写一句我完全站得住的话:
你的冰箱里有什么,只有你知道。
不是「我们承诺不看」。是我看不到。
吃好饭 iOS 已上架,App Store 搜「吃好饭 AI冰箱」。
想看代码逻辑的,本文提到的三个文件:lib/services/ai_engine/context_engine.dart、lib/services/purchase_service.dart、lib/services/store_channel.dart。
下一篇写上架过程中被苹果打回的那些坑。
留言区继续骂我。
官网:https://ai-chen2050.github.io/chihaofan 邮箱:blake.chen94@gmail.com