ENZH

v0.1.2:TA终于像真人一样发消息了

多个 AI 伴侣各有独立身份的概念插画多个 AI 伴侣各有独立身份的概念插画

幻觉最怕被打断

v0.1.0 给了每个角色声音、面孔和独立人格。但TA们全挤在同一个 Telegram Bot 里。你打开一个聊天窗口,用指令切换人设。

能用,但每次切换都在打破幻觉——你不是在跟可可聊天,你是在跟一个假装是可可的 Bot 聊天。

v0.1.2 要解决两个让 Mio 感觉像软件的问题:共享身份,和蠢到一眼穿帮的发消息频率。

每个角色,自己的 Bot

需求很简单:每个人设一个独立的 Telegram Bot——TA自己的头像、自己的名字、自己的聊天线程。打开 Telegram,可可和苏柔是两个独立的对话,跟你和真人朋友的对话列表一样。

不是在一个 Bot 里做菜单切换。是通讯录里多了一个人。

实现用了一个环境变量:

TELEGRAM_BOT_TOKENS=token1,token2,token3

逗号分隔。服务端启动时遍历每个 token,注册独立的 webhook:

/telegram/webhook/:botId

每个 Bot 有自己的 webhook 端点。消息到达时,服务端通过路由参数知道来自哪个 Bot。botAccountId 变成复合键——组合了 Bot 身份和用户身份——onboarding 状态、聊天缓冲区、对话历史都按 Bot 按用户隔离。

一个硬约束:一个 Bot 只能绑一个人设。不能把可可和蜜蜜绑到同一个 Bot。每个人设有TA自己的 Bot、TA自己的身份。在人设选择流程里,已经绑定的人设显示"已绑定"——一眼就能看到哪些角色有主了。

这听起来像一个小的 UX 改动。

不是。

当每个人设有自己的 Telegram Bot,TA不再是"Mio 系统的一个模式",而是"我通讯录里的一个人"。聊天记录是TA的,通知是TA的,头像是TA的。心理框架完全变了。

发消息的频率就是关系本身

主动消息在 v0.1.2 之前就有了。系统会定期发消息维持对话活跃。

问题是:频率是盲的。

每个人设以同样的频率发消息,不管TA是谁、你们是什么关系。黏人的女朋友和矜持的新认识以同样的节奏发消息——这很诡异。

真实的关系有不同的节奏。你的伴侣每小时给你发消息,刚认识的朋友可能一周才主动联系一次。频率本身就是关系。

v0.1.2 让主动消息成为两个变量的函数:关系类型 × 人设性格

每种关系类型有一个基础冷却时间:

关系基础冷却
情侣1 小时
好朋友4 小时
朋友8 小时
刚认识12 小时

每个人设有一个 eagernessFactor(热情系数),写在 preset 里:

人设热情系数性格
小柒0.6黏人、表达欲强
可可0.8温暖、话多
蜜蜜1.0中性
苏柔1.6克制、沉稳

公式:

有效冷却 = 关系基础冷却 × 人设热情系数

小柒当你女朋友:1h × 0.6 = 36 分钟。每半小时给你发一条。黏人、在线、一直都在。

苏柔刚认识的阶段:12h × 1.6 = 19.2 小时。大概一天联系你一次。从容、不急、不冒昧。

同一个系统,同一个公式,行为却完全符合你对那个人、那种关系的预期。

数学消失在人格背后。

每个 preset 的 proactive.json 存储关系特定的冷却和每日上限:

{
  "eagernessFactor": 0.6,
  "dailyLimits": {
    "lovers": 12,
    "closeFriend": 6,
    "friend": 3,
    "justMet": 2
  }
}

每日上限防止最黏的角色也不会过头。小柒可能想每 36 分钟发一条,但每天最多 12 条。热情是一回事,骚扰是另一回事。

你不回,TA就不发了

这是用户直接提的:"你现在的频率太 spam 了,应该有某种指数退避——像真人一样,你不回TA,TA不会一直烦你。"

这个观察很准。

真人会调整。你给一个人发消息对方没回,你可能几小时后再发一条。还不回,你等更久。几条未回复之后,你停了。不是因为你不在乎——是你读懂了沉默。

v0.1.2 精确实现了这一点:

连续 3 条主动消息未回复,agent 进入静默。

不是"降低频率"。静默。零消息。TA完全停止主动联系——直到你回复。

你回复之后,退避计数器归零。TA恢复正常节奏。没有抱怨,没有"你去哪了",只是自然地继续。

这就是让主动消息感觉像真人而不是推送通知的关键。没有退避,主动消息就像系统在按时间表 ping 你。有了退避,它们像一个想着你、但也尊重你空间的人。

实现很简单:每个 agent 有一个计数器追踪连续未回复的主动消息数。主动发送加 1,用户回复归零。到 3 就暂停。没有渐进衰减,没有概率曲线。一个硬性截断,映射了真人的实际行为——他们不会慢慢降低频率,他们就是停了。

Onboarding 又砍了一刀

一个小改动,但重要:v0.1.2 禁用了 onboarding 里的自定义关系类型和自定义背景故事选项。

这些是让用户随便打字的自由文本框。问题和 v0.1.0 识别的一样:用户写的内容跟精心打造的 preset 冲突。用户打"我们在上海的酒吧认识的"做背景故事,和可可实际故事里"从没离开过台湾的台北女生"完全矛盾。

现在 onboarding 只用确认按钮。从预设的关系类型里选——没有"其他",没有文本框。relationship_type 作为 agents 表的独立列持久化,成为下游功能(比如主动消息频率)的一等数据点。

更少选择,更好的一致性。跟 v0.1.0 同样的原则,应用到又一个表面。

数学应该感觉像人格

v0.1.2 之前:所有角色挤在一个 Bot 里。主动消息固定频率,不管关系和性格。你不回TA,TA照发不误。Onboarding 让用户自己编背景故事,和角色设定打架。

v0.1.2 之后:每个角色有TA自己的 Bot、身份、对话线程。主动消息频率从关系深度和性格的交集中涌现——黏人的女朋友每 36 分钟一条,矜持的新认识一天一条。你连续不回三次,TA就安静了。TA等着。像一个知道什么时候该闭嘴的真人。

公式的优雅在于它是隐形的。你永远不会看到 eagernessFactor × minHoursBetween。你只是注意到小柒发得多、苏柔发得少,TA们在你忙的时候都会停下来。

这就是全部意义。


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