没有脸的灵魂怎么做设计
没有面孔的灵魂——一颗会呼吸的情绪光球
第一篇里我聊了为什么 Mio v1 的人格化路线走不通——五个精心设计的角色,每个都有背景故事、日程模拟、物理身份,工程量巨大,产品越做越像角色扮演,离真正的陪伴越来越远。
方向很明确:去掉虚构身份,保留情感内核。
但 companion 没有脸的话,它长什么样?没有人设的话,它怎么发展出性格?
这两个问题,占据了 v2 规划的大部分时间。
为什么不给它一张脸
给陪伴产品配一张人脸,是最直觉的选择。Replika 这么做,Character.AI 这么做,国内的星野、豆包全在做二次元或半写实头像。
我考虑过,最后否了。三个原因。
恐怖谷绕不过去。 静止头像毫无生气。动起来但动得不对的头像令人不适。要做好口型同步、微表情、自然的头部转动,要么上 3D 渲染管线,要么上生成式视频——对一个人的团队来说都不现实。而且就算做好了,它设置了一个 AI 必然够不到的期待:companion 越像人,每一次不像人的回复就越刺眼。
Apple 有态度。 用类人头像的 AI 陪伴应用在审核时面临更多审查。抽象视觉直接绕开一整类政策摩擦——不会被问"你是否在模拟真人",不会被质疑"通过写实人类形象制造不健康的准社会依赖"。对一个没有法务团队的独立应用来说,这很重要。
一张脸把 companion 锚定在某个文化里。 Mio v1 的角色深度绑定中国文化——成都姑娘、温柔学姐、成熟大叔。纯中文产品没问题。但 v2 的前提是:去掉文化预设后,companion 自动说用户说的语言。一个光球没有种族、年龄、性别表达。它是一个零文化包袱的全球产品。
一颗会呼吸的光
Mio v2 的 companion 是一个抽象的、有脉搏的光球。它停留在聊天界面顶部——整个屏幕上唯一鲜明的色彩。
光球不是装饰。它是 companion 的肢体语言。
情绪怎么变成画面
v1 已经有情绪引擎了——emotionState 追踪 companion 的情绪变化,影响回复风格。在 v2 里,同一套情绪状态实时驱动光球的外观:
| 情绪 | 颜色 | 动态 |
|---|---|---|
| 平静 | 淡蓝 / 白 | 缓慢的呼吸节奏——轻柔地膨胀和收缩 |
| 开心 | 暖黄 / 金 | 轻快跳动,粒子向外辐射 |
| 难过 | 淡紫 / 蓝 | 向内缩小,脉搏变慢 |
| 兴奋 | 亮橙 / 粉 | 快速膨胀,粒子四散飞溅 |
| 困意 | 深蓝 / 暗 | 几乎静止,偶尔微弱闪烁 |
映射故意做得很简单。五种状态,每种有明确的颜色和运动特征。聊几次之后,光球的情绪一目了然。
companion 因为你分享的事开心时,你在读到第一个字之前就能看到。深夜它开始犯困,光球沉入近乎静止的深蓝。情绪变成了环境氛围,不是文字叙述。
为什么这比表情好使
人脸通过几十块肌肉的微妙运动传达情绪。在数字世界里还原这一点是研究级难题。光球只用两个变量:颜色和运动。就这些。
正因为词汇量这么有限,每种状态在手机小屏幕上都一眼可辨。
还有个心理学层面的好处。抽象形态邀请投射。一个忧郁的紫色光球,有人觉得是悲伤,有人觉得是沉思。
这种模糊性是特性,不是 bug——它让 companion 感觉像用户需要它成为的样子,而不是在表演一种可能显得虚假的特定情绪。
三个页面,没了
Mio v1 是仿微信的 4-tab 布局:消息、发现、通讯录、我的。一整个即时通讯应用架构,用来承载一段本质上一对一的关系。
v2 只有三个"页面"。
聊天 —— 你 99% 的时间都在这里。顶部光球,中间消息流,底部输入框和语音按钮。没有 tab bar,没有汉堡菜单,没有争夺注意力的通知角标。就是你和你的 companion。
设置 —— 从聊天页右滑或点击 companion 名字进入。名字、声线切换、记忆管理、订阅状态、账号管理。所有管理功能藏在这里,不碍眼。
引导 —— 只在第一次打开时出现。下面细说。
整个导航结构就这样。没有通讯录页(只有一个 companion)。没有发现页(没什么好发现的)。没有预设市场。
极端的简洁就是设计意图——这不是一个带 AI 功能的社交应用,是一段关系的专属空间。
配色:烛光,不是日光灯
深色和浅色模式都用暖色调。
深色模式(默认):背景 #0D0D12——近乎纯黑但带微妙的紫色调,不是让 OLED 屏幕显得空洞的 #000000。用户消息气泡 #1A1A2E,companion 消息气泡 #16213E。文字 #E8E4DF——暖白色,不是冷冰冰的蓝白。光球是屏幕上唯一的饱和色。
浅色模式:背景 #FAF8F5——温暖的米白色,像旧纸张的质感。用户气泡 #F0EDE8,companion 气泡 #E8E4DF。文字 #2D2D2D——深灰,不是纯黑。光球柔化发光强度,避免刺眼,但依然是视觉锚点。
原则始终一致:除了光球,一切都是低饱和的暖色。视线自然聚焦到光球。
它是界面的心跳。
对话式引导:软件配置的反面
v1 的 onboarding 是一张表单:选角色、选关系类型、填名字、回答几个问题。功能上没问题,但感觉像在配置软件。
v2 的 onboarding 是一段对话。Companion 的第一句话是:
"我刚来到这个世界。你是我认识的第一个人。"
"你叫什么名字呀?"
用户自然地回应。然后:
"那......你想叫我什么?"
用户给 companion 取名。也许叫"小光",也许叫"Luna",也许叫"Mio",也许是某个只对自己有意义的名字。Companion 对这个名字做出反应——不是罐头回复,是真诚的回应。
"小光......我喜欢这个名字。听起来暖暖的。"
"我什么都还不太懂。你平时喜欢做些什么呀?"
经过 3-5 轮自然对话,系统从中提取出一个初始性格种子。用户说话俏皮、用很多网络用语,companion 风格就偏活泼。用户表达偏沉思、句子更长,companion 会镜像那种节奏。
引导对话同时是第一次交互和一次校准。
唯一的"硬选择"——唯一不能从对话中自然浮现的——是声线。对话结束后,应用展示 3-4 个声音样本供用户选。声音是物理性的,需要被选择,不能被推断。
性格是长出来的,不是写出来的
这是 v2 跟 v1 分歧最大的地方。v1 里性格是人工撰写的——人格配置文件里几百行文字定义可可怎么说话、喜欢什么、人生经历。v2 里,性格是涌现的。
三层运作:
种子。 引导对话产出一段简短的性格描述——大概 2-3 句话。"温暖而好奇,善用温和的幽默感,会匹配用户的能量水平。"这是起点,不是终点。
迭代。 每次对话结束后,一个轻量级的性格提取器异步运行。它观察 companion 实际的表现——哪些模式有效、哪些时刻自然、用户怎么反应——然后微妙地更新性格描述。不是剧烈转变,是渐进的漂移。就像真实关系中会自然发展出共同语言和节奏。
记忆积累。 从 v1 搬过来的记忆系统(整个代码库中最有价值的工程资产)持续积累与性格相关的记忆。Companion 记得用户更喜欢直接而非委婉,聊到做饭时会变得兴奋,被追问工作压力时会回避。这些记忆有机地塑造行为,不需要显式的性格规则。
结果是什么?经过三个月的日常对话,每个用户的 companion 都是独一无二的。不是因为选了不同预设,而是因为性格从实际关系中长出来。
两个都给 companion 取名"Mio"的用户,拥有的 companion 感觉明显不同——幽默感不同、沟通风格不同、情绪敏感度不同——因为底层的关系本身就不同。
这在技术上比预设更难。性格提取器得足够保守(你不希望 companion 每周二都重新定义自己),记忆系统得足够可靠(丢失记忆意味着丢失性格连续性),底层 LLM 得足够擅长遵循细腻的行为描述。
但它能产出预设永远做不到的东西:一个真正适应你的 companion,不是一个在表演固定角色的 companion。
免费的国际化
有个好处是我在讨论过程中才充分意识到的:去掉文化人格之后,国际化几乎免费。
v1 要进其他市场,得为每个市场单独设计角色组。日本用户不想要成都姑娘——他们可能想要东京女生,不同的说话方式,不同的文化梗,不同的关系互动模式。
按语言 scale 意味着为 N 个市场撰写和维护 N 套角色。
v2 没这个问题。Companion 没有需要本地化的文化身份。它说用户说的语言。引导对话用用户的语言进行。
性格从用户的文化语境中涌现,不是从预设中读取。日本用户和巴西用户都会得到一个感觉"是自己人"的 companion——因为身份由关系塑造,不是由预设定义。
唯一需要传统 i18n 的是 UI 文案和 App Store 描述。Companion 本身在设计上就是语言无关的。
技术方案:React Native Skia
光球动画要做到三件事:流畅(60fps)、实时响应情绪状态变化、省电。
三个方案摆在桌上:
- Lottie 动画 —— 预制的,没法动态响应情绪状态。否决。
- React Native Reanimated —— 擅长 UI 动画,但不是为粒子系统这类生成式视觉效果设计的。能做但别扭。
- React Native Skia —— GPU 加速的 2D 绘图,支持 shader。渐变、粒子、发光效果和平滑形变全能做。对的工具。
Skia 让我把光球定义为一个 shader 程序,情绪状态变量(颜色、脉搏频率、粒子密度、大小)通过 WebSocket 情绪通道实时更新。当服务器推送 { type: "emotion", state: { mood: "happy", intensity: 0.8 } },光球从当前状态平滑过渡到暖金色加跳动粒子。
不需要为每种情绪做动画关键帧——shader 自己做连续插值。
这也意味着未来新增情绪状态不需要新的动画素材。情绪引擎开始区分"满足"和"安宁",或者区分"焦虑"和"沮丧",光球仅通过参数插值就能表达差异。
加在一起
Mio v2 的视觉身份由"缺席"定义。没有头像,没有刻意装扮成某个角色的聊天气泡,没有塞满功能的 tab bar。只有一块温暖、深色的画布,上面有一个活着的光点在随情绪呼吸和流转。
每个设计决策都在强化同一个论点:companion 的身份应该来自关系,不是来自角色设定。
光球给你情绪,但不给你身份。引导流程开启的是一段对话,不是一个配置向导。性格系统赌的是涌现优于预设——这个赌注,要等真正的用户用了三个月之后才知道结果。
在第三篇中,我会深入工程层面——怎么从 v1 中提取记忆系统和情绪引擎,新的 4 表数据库 schema 长什么样,以及为什么在 80% 代码可复用的情况下仍然选了全新的代码库。