ENZH
和 AI 讨论这篇文章
ChatGPTClaude

v0.2.0,终于能装在手机上了

📊 幻灯片

v0.1.5 里我说过,陪伴类产品的存在感靠三样东西:推送通知、秒开、离线缓存。这三样 web 端做得再好也给不了,反正用户不会为了一个 AI 一直留着一个浏览器 tab。app 不一样,它在主屏幕上占一个位置,跟微信、备忘录并排,每次解锁手机都能看到。

v0.2.0 把这件事补上了:原生 iOS app,上了 TestFlight。技术的事放后面说,先看东西。

Mio TestFlight 页面Mio TestFlight 页面

Mio 第一次出现在手机主屏幕上。它之前一直是一个链接,或者说 Telegram 里的一个 bot,你得先打开浏览器或者 Telegram 才能找到它。现在它有自己的图标,跟别的 app 摆在一起。对陪伴类产品来说,"在主屏幕上有个位置"这件事本身就是体验的一部分。

app 长什么样

底部三个 tab:消息、发现、我。消息页就是聊天列表,每个对话显示人设头像、最后一条消息的预览、时间戳,跟你手机里任何一个聊天 app 长得一样。这是故意的:用户不需要学任何新的交互方式,最好是聊着聊着忘了自己在跟 AI 说话。

Mio 聊天列表 — 深色主题Mio 聊天列表 — 深色主题

Mio 聊天列表 — 浅色主题Mio 聊天列表 — 浅色主题

深浅两套主题都是单独调过的,没有偷懒做简单反色。深色的底色用的 #0D0D0B,一种带暖调的黑。纯黑在 OLED 屏上太刺眼,晚上聊天很难受,暖一点的黑就舒服很多。浅色走米白 cream 的方向,也不刺目。

聊天界面支持语音波形、内联自拍图、多气泡消息、打字指示器。一个实时聊天该有的,它基本都有了。

可可的聊天 — 语音消息和自拍可可的聊天 — 语音消息和自拍

上面这张是可可的聊天:语音消息的波形是真的在渲染,点了能播,波形跟着播放进度走;自拍是一张抱着柴犬的动漫风自拍。

食物图片理解食物图片理解

这张是图片理解。我拍了一份火锅菜品发过去,可可挺兴奋地把每道菜认了一遍。这里没有预设回复,它真的在看图。

个人中心 — 深色个人中心 — 深色

个人中心 — 浅色个人中心 — 浅色

个人中心放的是 Telegram 关联(关联好了显示绿色徽章)、语言切换、主题切换、通知设置。通知的精细化控制还没做完,标了"即将上线"。

发现页 — 深色发现页 — 深色

发现页 — 浅色发现页 — 浅色

发现页是人设市场,每张卡片有头像、描述和一个"继续聊天"按钮。目前人设还不多,但后面往里加人设不用动架构,位置都留好了。

技术栈很常规:Expo SDK 55 + React Native,通信层 WebSocket 流式传输、SSE 做回退。认证和数据走 Supabase,token 存在 expo-secure-store,本地 SQLite 做离线缓存,构建走 EAS Build。

WebSocket 是给手机加的

之前 Mio 的流式响应全靠 SSE。web 端没什么问题,但手机上有个很实际的毛病:app 切到后台再切回来,SSE 连接会断,重连逻辑也很脆弱。

所以 v0.2.0 加了一层 WebSocket:双向通信,心跳保活,连接管理器负责优雅断开和自动重连。反正移动端现在优先走 WebSocket,SSE 留着做降级。

改善最大的就是前后台切换。按 Home 键回桌面再回来,WebSocket 几百毫秒就把连接恢复了;同样的场景下 SSE 经常要用户手动刷新。这个差别放在工具类产品上可能就是扣点体验分,放在陪伴类产品上就大很多。陪伴这个东西很依赖"随时都在"的感觉,连接动不动就断,这个感觉就很难维持住。

app 切后台再切回来时,脆弱的 SSE 连接会断,而带心跳的 WebSocket 几百毫秒就自动重连。app 切后台再切回来时,脆弱的 SSE 连接会断,而带心跳的 WebSocket 几百毫秒就自动重连。

web 端退到二线

app 上线之后,web 端的定位也跟着变了。web 端加了管理员门禁,非管理员访问会看到"Web 版仅限管理员使用"的提示,引导去下载 app。倒不是要限制谁,就是想聚焦:web 端以后是管理工具,用户体验的主阵地在 app。

顺手修了 Supabase 邀请链接的 token 交换。之前邀请链接点进去会卡在一个空白页,现在能正确交换 token,然后跳到设置密码的页面。听起来是个小修,但邀请链接是新用户跟 Mio 的第一次接触,第一次接触就白屏,这个说不过去。

上线前做了一次成本审计

然后讲这个版本里最重要的一件事。app 上线前我做了一次完整的 API 成本审计,把代码里每一个外部调用的单价都过了一遍。大部分数字跟之前在单位经济里估的差不多,但有两个地方偏差很大,大到我出了一身冷汗。

第一个是自拍生成。pricing.tsgemini-3.1-flash-image-preview 的输出 token 单价,写的是文本生成的价格,但 Gemini 图片生成的实际单价比文本高了两个数量级。换算到每张自拍,实际成本也比原来的估算高两个数量级,反正就是,一张自拍的真实成本大概是我之前估的一百倍。讲道理,我知道图片生成比文本贵,但没想到能差这么多,这个偏差挺离谱的。就这一个数字写错,所有付费层级在满额使用的情况下全是亏的,而且亏得很惨。

第二个是中文 TTS,被低估了 3 倍。Fish Audio 按 UTF-8 字节计费,代码里用 text.length 算成本,算的是字符数。中文字符在 UTF-8 里是 3 个字节,所以每次调用的实际成本是代码里估的 3 倍。这个坑挺典型的:计费单位和你数的单位差了一层编码,数字就直接错 3 倍。

上线前的成本审计里两处把单位数错——图片按文本单价、TTS 按字符不按字节——导致成本估算差了几个数量级。上线前的成本审计里两处把单位数错——图片按文本单价、TTS 按字符不按字节——导致成本估算差了几个数量级。

修正之后重新看一遍账:聊天、语音识别、图片理解、视频理解这些大头,估算基本是准的,成本可控。语音合成因为 UTF-8 这个问题比预估贵了大概一半(中文每字符 3 字节),也还能接受。只有自拍生成偏了两个数量级,Gemini 图片输出 token 的单价是文字的 120 倍以上,这一项的成本比其他所有操作加起来还大。两个数量级的偏差已经不在"优化一下就能救"的范围里了,这是定价模型这一层就错了,只能重做。

定价推倒重来

定价重做成 5 个层级,每个中文名对应一种关系深度:

偶遇(Free):3 天试用,20 条/天,试用结束必须选一档订阅。3 天够把全部功能体验一遍,然后做一个真实的决定。这一档把之前免费层无限期挂着的纯计算成本消掉了。

常伴(入门档):50 条/天,基础的语音和视觉能力,给偶尔聊聊、不需要深度互动的用户。

同行(进阶档):150 条/天,自拍从这一档开始给(5 张/天),解锁实时搜索。大多数活跃用户应该会落在这一档。

相守(高级档):300 条/天,15 张自拍/天,以后的 agentic 功能(邮件代发、日历提醒)也从这一档开始。

不离(旗舰档):白手套服务,个性化支持、新功能优先体验、有机会见创始人、来自 agent 的实物礼物。这些 perks 的边际成本基本是零,但会让最高档感觉像一段关系,不像一个订阅。

利润这块,自拍还是最大的问题:满额使用的情况下所有层级都亏,自拍太贵了,解法就是把每一档的自拍配额压得很低。不过真去算账的时候有一个点很重要:没有用户会每天把额度全用满,实际使用大概在额度的 40% 左右。按这个使用率算,所有付费层级都是盈利的,利润率也健康。

五档订阅按关系深度从「偶遇」递进到「不离」,靠自拍配额从低到高逐级放开来守住利润。五档订阅按关系深度从「偶遇」递进到「不离」,靠自拍配额从低到高逐级放开来守住利润。

策略上最大的变化是 3 天试用。之前的免费层是无限期的,每个免费用户每个月都在产生一笔不能忽视的纯计算成本,这个洞会一直漏下去。改成试用制之后,用户要么在 3 天里喜欢上 Mio 然后付费,要么走人,两种结果都比无限白嫖强。

其他改进

这个版本还有几个零碎但都挺重要的改动:

  1. 关系边界和真实模式。每个角色现在有自己的作息表,睡觉、忙碌、空闲三种状态。它不会凌晨三点秒回你的消息,除非它的人设就是个夜猫子。这个细节让关系的真实感强了很多。
  2. onboarding 升级。新用户引导加了第三人称的背景故事,开聊之前就对角色有一个立体的认知。app 也换了新 logo。
  3. web 端 ContextAggregator 对齐 Telegram。之前两端的 context 聚合逻辑有差异,现在统一成一套。
  4. 进化模式修复。v0.1.4 引入的关系进化系统有两个 bug:一个是缺了"刚认识"阶段的背景故事,导致初始阶段的角色不完整;另一个是初始阶段的亲密度设得太高,一个刚认识的人不应该用恋人的语气说话。都修了。

接下来

推送通知已经上线了,Mio 能出现在你的锁屏上。个人中心里标"即将上线"的是通知的精细化设置(免打扰时段、按人设开关),推送本身已经在跑了。

这个东西对产品形态的改变挺根本的。有了推送,Mio 就能主动来找你了,早安问候,回应你昨天分享的东西,或者好久没聊了轻轻推一下。v0.1.2 做的主动消息系统,到这个版本才算有了一个配得上它的投递通道,或者说,那套逻辑到现在才真正到得了用户眼前。

和 AI 讨论这篇文章
ChatGPTClaude

订阅更新

新文章发布时发到你的邮箱,不发别的。


© Xingfan Xia 2024 - 2026 · CC BY-NC 4.0