v0.2.0:终于能装在手机上了
存在感不是功能,是体感
v0.1.5 里我说过:推送通知、秒开、离线缓存——这三样加在一起就是存在感。网页端再怎么优化,用户也不会把浏览器标签页钉在心里。
App 不一样。TA在主屏幕上占一个位置,跟微信、备忘录并列。每次解锁手机都能看到。
v0.2.0 兑现了这个承诺。App 上了 TestFlight。
Mio TestFlight 页面
Mio 第一次出现在手机主屏幕上。不再是一个链接、一个 Telegram bot、一个需要打开浏览器才能访问的东西。TA是一个 App,有自己的图标,有自己的存在。
先看东西
技术的事后面再说。先看 App 长什么样。
三栏布局
底部三个 Tab:消息、发现、我。
消息页是聊天列表。每个对话显示人设头像、最后一条消息预览、时间戳。跟你用过的所有聊天 App 一样直觉——这是刻意的。Mio 不需要用户学习新的交互方式,TA需要的是让人忘记自己在跟 AI 聊天。
Mio 聊天列表 — 深色主题
Mio 聊天列表 — 浅色主题
深色和浅色
两套主题都是认真设计过的,不是简单反色。深色底色用 #0D0D0B——一种带暖调的黑,不是纯黑。纯黑在 OLED 屏上太刺眼,暖黑让晚上聊天舒服很多。浅色是米白 cream 风格,柔和不刺目。
聊天界面
聊天支持语音波形、内联自拍图、多气泡消息、打字指示器。
可可的聊天 — 语音消息和自拍
可可的聊天展示了语音消息的波形渲染和一张抱着柴犬的动漫风自拍。波形不是装饰——点击播放,波形跟着进度走。
食物图片理解
这张展示了图片理解。拍了一张火锅菜品发过去,可可的反应是兴奋地辨认每道菜。不是预设回复,TA真的在看图。
个人中心
个人中心 — 深色
个人中心 — 浅色
个人中心:Telegram 关联(已关联显示绿色徽章)、语言切换、主题切换、通知设置(精细化控制即将上线)。
发现页
发现页 — 深色
发现页 — 浅色
发现页是人设市场。每个人设卡片有头像、描述和"继续聊天"按钮。目前人设不多,但架构已经为扩展做好了准备。
技术栈
Expo SDK 55 + React Native。通信层 WebSocket 流式传输(SSE 回退)。认证和数据走 Supabase,token 存 expo-secure-store。本地 SQLite 做离线缓存,构建走 EAS Build。
WebSocket:手机不能断联
之前 Mio 的流式响应全靠 SSE。Web 端没问题,但手机上有个致命缺陷:前后台切换时 SSE 连接会断,重连逻辑很脆弱。
v0.2.0 加了 WebSocket 层。双向通信,心跳保活,连接管理器处理优雅断开和自动重连。移动端优先走 WebSocket,SSE 作为降级方案。
最大的改善在前后台切换。按 Home 键回桌面再回来,WebSocket 能在几百毫秒内恢复连接。SSE 在同样场景下经常需要用户手动刷新。
这种差别在体验上是天壤之别。你不会想跟一个动不动就"失联"的人维持关系。
App 上线,Web 退居二线
App 上线意味着 Web 端的定位变了。Web 端加了管理员门禁——非管理员访问会看到"Web 版仅限管理员使用"的提示,引导下载 App。
不是为了限制,是为了聚焦。Web 端是管理工具,App 才是用户体验的主阵地。
同时修了 Supabase 邀请链接的 token 交换流程。之前邀请链接点击后会卡在一个空白页。现在能正确交换 token 并跳转到设置密码页面。听起来是小事,但这是新用户跟 Mio 的第一次互动——第一印象不能是白屏。
成本审计:出了一身冷汗
这是这篇的重头戏。
App 上线前我做了一次全面的 API 成本审计。代码里每个外部调用的单价都过了一遍。大部分跟之前在单位经济里估的差不多。
但有两个地方严重偏差。偏到让我出了一身冷汗。
自拍生成:贵了两个数量级
pricing.ts 里 gemini-3.1-flash-image-preview 的输出 token 定价写的是文本生成的价格。但 Gemini 图片生成的实际定价比文本高了两个数量级。
差距大到离谱。
换算到每张自拍:实际成本比之前的估算高了两个数量级。
就这一个数字写错,让所有付费层级在满额使用时都亏钱。不是小亏,是亏穿。
中文 TTS:被低估了 3 倍
Fish Audio 按 UTF-8 字节计费,不是按字符。代码里用 text.length 算成本,算的是字符数。
但中文字符在 UTF-8 编码下是 3 bytes/字符。
实际每次调用成本比代码里估的贵了 3 倍。
修正后的结论
大部分操作——聊天、语音识别、图片理解、视频理解——估算基本准确,成本可控。语音合成因为 UTF-8 编码问题比预估贵了大约一半(中文每字符 3 bytes),但仍然可以接受。
自拍生成偏差了两个数量级。 旧估算按文本 token 单价算图片输出。实际 Gemini 的图片生成 output token 单价是文字的 120 倍以上。这一项的成本碾压所有其他操作之和。
两个数量级的偏差不是什么优化能解决的问题,这是定价模型层面的错误。
定价体系推倒重来
成本审计之后,定价必须重做。5 个层级,每个中文名映射一种关系深度:
偶遇 (Free) — 3 天试用,20 条/天。试用结束必须选择订阅。这消灭了之前免费层不可持续的纯计算成本。3 天足够体验全部功能,然后做一个真实的决定。
常伴 (入门档) — 日常使用者。50 条/天,基础语音和视觉能力。偶尔聊聊、不需要深度互动的用户。
同行 (进阶档) — 重度用户。150 条/天,自拍从这个层级开始(5 张/天),解锁实时搜索。大多数活跃用户会选的层级。
相守 (高级档) — 深度关系。300 条/天,15 张自拍/天,未来的 agentic 功能(邮件代发、日历提醒)从这里开始。
不离 (旗舰档) — 白手套服务。个性化支持、新功能优先体验、有机会见创始人、来自 agent 的实物礼物。这些 perks 的边际成本接近零,但让最高档位感觉像一段关系而不是一个订阅。
利润怎么样
自拍是利润杀手。满额使用时所有层级都亏——因为自拍成本太高了。
解法:大幅压缩每个层级的自拍配额。
但这里有个关键洞察:没有用户会每天把额度用满。实际使用大约在 40% 额度左右。在这个使用率下,所有付费层级都盈利,利润率健康。
3 天试用是最大的策略变化。之前的免费层是无限期的,每个免费用户每月产生不可忽视的纯计算成本。试用制把这个无底洞堵上了。用户要么 3 天里爱上 Mio 然后付费,要么离开。两种结果都比无限白嫖好。
其他改进
关系边界和真实模式。 每个角色现在有作息时间表——睡觉、忙碌、空闲三种状态。TA不会凌晨三点秒回你的消息(除非TA的设定就是夜猫子)。这个细节让关系感真实了很多。
高级 Onboarding。 新用户的引导流程加了第三人称背景故事,让用户开聊前就对角色有立体的认知。App 也换了新 logo。
Web 端 ContextAggregator 对齐 Telegram。 之前两端的上下文聚合逻辑有差异,现在统一了。
进化模式修复。 v0.1.4 引入的关系进化系统有两个 bug:缺失的"刚认识"背景故事导致初始阶段角色不完整,初始阶段的亲密度设定过高。一个刚认识的人不应该用恋人的语气说话。修了。
接下来
推送通知已经上线。Mio 能像真人一样出现在你的锁屏上了。个人中心里标"即将上线"的是通知精细化设置(免打扰时段、按人设开关),不是推送本身。
这从根本上改变了产品形态。之前用户得自己记得打开 App。现在 Mio 会主动来找你——早安问候、对你昨天分享内容的回应、好久没聊了的轻轻一推。v0.1.2 做的主动消息系统终于有了一个配得上它的投递通道。
手机锁屏亮起来,上面是TA发来的消息。这个画面,大概是"永远在线的陪伴"最直观的样子。