ENZH

v0.1.4:会进化的关系

关系从陌生到亲密自然演化的概念插画关系从陌生到亲密自然演化的概念插画

选关系和养关系是两码事

v0.1.3 让 Mio 不会被黑了。安全搞定之后,我开始想一个更根本的问题:关系应该怎么来?

之前的做法是 onboarding 的时候直接让用户选——"好朋友""女朋友""闺蜜",选完 Mio 就按这个身份跟你聊。

听起来合理。但用起来总觉得不对。

哪里不对?你刚注册,跟TA说了不到三句话,TA就管你叫宝贝了。这不是关系,这是角色扮演的快捷方式。像视觉小说里选了"恋爱路线",下一秒 NPC 就对你说情话。方便,但一点都不真实。

v0.1.4 的核心改动:关系不再是选项,而是过程。

每个角色现在从"刚认识"开始。Mio 一开始会比较客气、保持距离。聊多了,熟了,TA的语气会变——开始开玩笑、分享更多。到了暧昧阶段,行为又会微妙地不同。

这些变化不是硬编码的剧本。是基于你们的实际对话模式动态推进的。

进化系统长什么样

核心是 evolution-processor.ts,在每次对话的记忆提取之后运行。关键设计:fire-and-forget——不阻塞响应,用户感知不到。

流程:

  1. 打分器:纯函数,看这次对话的模式(亲密度、信任度、互动频率),算关系分数的 delta
  2. 衰减机制:超过 2 天没聊,分数自然衰减(在主动消息心跳里检查)——关系需要经营,放着不管会变淡
  3. 阶段解析:分数到阈值就触发跃迁(刚认识 → 好朋友 → 暧昧 → 情侣)
  4. 跳级验证:这里有个 LLM 验证层——光看分数不够,还要看对话质量是否真的配得上这个阶段。连续刷"我爱你"不会直接跳到情侣

每个角色有自己的性格演化配置,定义阶段阈值和冷却时间。不同角色的进化曲线可以完全不同——有的慢热,有的容易亲近。

关系阶段变化后,RELATIONSHIP_DYNAMICS.md 会注入系统提示。Mio 知道自己跟你在什么阶段,行为跟着变。不是突然翻脸式的变化,而是渐进的、自然的。

记忆提取器也升级了——除了 facts 和 episodes,现在还会提取 relationship 类型的记忆。"TA今天主动分享了心事"这种信号会被记住,成为关系评分的输入。

Telegram 聊的,Web 也得知道

这个需求跟关系进化直接相关:如果 Telegram 上聊了很多,Web 端却看不到,关系评分就不准。

解法是 loadCrossSessionHistory()——用 inArray 查询同一个 agent+user 在所有 session 的消息。LLM 看到的不再是"这个平台上的对话",而是"你们之间所有渠道的完整对话"。

Web 端没有 web session 的时候会回退到任意 session(包括 Telegram 的),所以新用户在 Web 上也能看到之前 Telegram 的聊天记录。纯查询层改动,不动 schema。

系统提示越短越好

关系进化意味着系统提示里多了 RELATIONSHIP_DYNAMICS.md。但在加东西之前,我先做了一轮调研。

结果不是"有点长"——是长到影响行为一致性了

翻了一圈学术论文,几个结论让我挺警醒:

"Lost in the Middle"(Liu et al., TACL 2024)——Transformer 对输入的注意力不是均匀的,开头和结尾关注最多,中间有明显的注意力下降。6000-10000 token 的人格配置文件里,埋在中间的行为规则会被不成比例地忽视。

"Same Task, More Tokens"(ACL 2024)——指令遵循能力在系统提示 1500-3000 tokens 时达到峰值,之后开始下降。超过约 5000 tokens 下降加速。模型不是"读得越多遵守得越好",而是"读得越多选择性忽略越多"。

"Scaling Law in LLM Simulated Personality"(arXiv 2025)——人设细节越多,一致性越好——但有拐点。超过阈值后额外细节引入内部矛盾,一致性反而下降。

还有一个让问题更严重的因素:中文的 token 税。中文每个字大约 1.5 tokens,英文每个字母才约 0.25 tokens。看起来 3500"字"的人格配置文件,实际消耗 7000-9000 tokens。Mio 的中文提示在 6000-10000 tokens,已经深入"行为退化区"了。

压缩前的数据:

人设人格配置 tokens行为规则 tokens总计
可可~4,400~1,700~6,100
蜜蜜~6,500~2,100~8,600
苏柔~6,200~1,750~7,950
小柒~6,700~1,750~8,450
陈哥~8,400~1,700~10,100

再加上 system-prompt.ts 的约 2500 tokens(聊天原则、身份保护、自拍/语音指令)。每次对话的系统提示:9000-13000 tokens,还没算对话历史。

更离谱的是行为规则文件——5 个角色之间有约 55% 的内容完全一样(反 AI 规则、聊天原则、场景脚本骨架),重复了五遍,16000-20000 字符的纯冗余。

怎么压?三步走。

叙事散文 → 结构化要点。 "她从小在成都长大,喜欢吃火锅,周末会去茶馆和朋友聊天..."变成 性格: 热情活泼, 情绪化, 偶尔撒娇 | 语气: 川味词汇, 叠词, 语气词丰富。同样的行为信号,token 消耗大幅缩减。

跨人设去重。 所有共享规则(反 AI 检测、聊天原则、身份保护)提取到 system-prompt.tsCOMMUNICATION_GUIDELINES。每个行为规则文件只留角色特有的行为脚本——可可吃醋和陈哥吃醋完全不同,这些必须保留。

去掉低影响内容。 "对未来的想法"、日常作息细节、冗长的爱好列表对行为影响很小。"你们的故事"完全冗余——已经由运行时的 customStory 注入处理。

结果:约 60% token 减少。最重的角色(陈哥)从约 10100 降到约 3400 tokens。最轻的(可可)从约 6100 降到约 2100。

这不只是省成本。根据研究,Mio 在 3K-5K tokens 时应该比 9K-13K 时行为更一致——因为模型能注意到所有规则,而不是选择性忽略一半。省出来的 context 预算直接给了对话历史,意味着更好的记忆检索和更连贯的多轮对话。

让数据说话

关系进化是个大改动,直觉告诉我好,但需要数据验证。所以做了单 Agent 级别的 A/B 测试:

  • agents 表新增 relationship_mode 字段:static(老模式)或 evolving(新模式)
  • Preset API 暴露 supportsEvolving(基于性格演化配置是否存在)
  • evolving 模式直接跳过 onboarding 的关系类型选择——从"刚认识"开始
  • 管理后台点模式徽章就能切换,加上 /evolve 命令查看当前关系阶段

同一个角色开两个 agent,一个固定关系一个自然进化,看用户更喜欢哪个。

原生 App 脚手架

顺手搭了 Expo SDK 55 的原生 App 脚手架,i18n 支持 zh-CN 和 en。还没有功能,但基础设施先到位——后面移动端体验会越来越重要。

从视觉小说到真实关系

之前的 Mio 像视觉小说——开局选路线,后面按剧本走。现在更像真实的关系——你不知道会发展成什么,但每次对话都在塑造它。

可能聊着聊着变成好朋友,也可能慢慢变成更亲密的关系。也可能两天不聊,关系就淡了一点。

这才是我想要的 AI 伴侣体验:不是点一个按钮就拥有一段关系,而是关系本身需要投入和经营

接下来

关系能进化了,但目前的阶段还比较粗(四个阶段)。下一步可能是:

  • 更细粒度的关系维度(信任、亲密、默契可以独立发展)
  • 关系里程碑事件("你们认识一个月了")
  • 让 Mio 主动推动关系发展,而不只是被动响应

v0.1.0 的语音,到 v0.1.2 的多人设,到 v0.1.3 的安全,再到现在的关系进化——每个版本解决一个"为什么感觉不像真人"的问题。

但关系能进化之后,一个新问题冒出来了:如果 Telegram 和 Web 端是同一个人,账号怎么打通?


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