名言神谕 — 选取算法的运作原理

当你回答完三个问题后,幕后会发生什么,来选出属于你的「名言、今日之语,以及温柔的仪式」呢?
我们将忠实于实现,讲解性格图谱分析如何运作,以及每日的「波动」是如何设计的。

目录

整体流程(三个步骤)

当你点击「开始」并回答三个问题后,内部会按以下顺序运行下列处理。

STEP 1
更新你心灵的地图
根据你的三个答案,将五因素的分数轻轻地推动(指数移动平均)。
STEP 2
选取一句名言
以概率抽取一句贴近你更新后心境的名言。
STEP 3
添上话语
从名言的主题 × 你的因素中,选出话语与一个小小的仪式。

性格图谱分析会在 STEP 1 中构建「你心灵的地图」,而这张地图随后会引导 STEP 2 与 STEP 3。
换言之,性格图谱是整个过程的基石。

性格图谱五因素是什么

本应用使用受交互分析(transactional analysis)启发的独有五因素,来表达「你心灵当下的倾斜」。每个因素的取值范围为 0〜100,均从平衡的中点 50 出发。

符号名称含义
CP原则严格、理想、责任感(我想成为怎样的人)
NP接纳温柔、慈悲、包容的力量
A分析逻辑、观察、现实检验
FC好奇自由、乐趣、灵感
AC协调适应、体谅、忍耐

每个问题中的两个选项,都各自被赋予了对五因素的变化量(增量)。「你选择了哪一个」会逐渐勾勒出你心灵的地图。

① 答案 → 更新你心灵的地图(EMA)

我们将你的三个答案合并为一,并用指数移动平均(EMA)来更新画像。这种方法不会骤然改变,而是在承载过往的同时,平滑地反映出你「近期的倾向」。

今日增量  todayDelta[f] = 3 个问题中对因素 f 的变化量之和(理论上为 −6〜+6)
今日分数  todayScore[f] = clamp( 50 + (50/6) × todayDelta[f] , 0, 100 )
更新       profile[f] = clamp( α × todayScore[f] + (1−α) × 此前的 profile[f] , 0, 100 )
            α(平滑系数)= 0.15

这个公式意味着什么

具体示例:当好奇(FC)在今天的三个问题中以最大值 +6 移动时
todayScore_FC = 50 + (50/6)×6 = 100
new FC = 0.15×100 + 0.85×50 = 57.5(从 50 → 57.5,只温柔地前进了 7.5)
如果第二天没有触及 FC:new FC = 0.15×50 + 0.85×57.5 = 56.4 …… 逐渐朝 50 回归。

这张「你心灵的地图(画像)」是驱动接下来 STEP 2 与 STEP 3 的唯一输入。这正是性格图谱分析的核心。

② 选取一句名言(余弦相似度 × 抽样)

每句名言都对五因素带有一份亲和度(例如,某句名言可能为 {CP:0.7, A:0.5, FC:0.3})。我们将其与你心灵地图中「倾斜的方向」相匹配。

1. 方向上的契合(余弦相似度)

我们从画像中减去 50,使其成为一个表示「相对于中心朝哪个方向偏倚」的向量,再测量它与名言亲和度向量之间的余弦相似度(方向的接近程度,−1〜+1)。关键在于我们看的是方向,而非大小,因此与「你心灵当下所朝向的方向」产生共鸣的名言会得到高分。

2. 冷却(避免重复)

3. 从前 8 名中按概率抽取一句(softmax 抽样)

我们取得分最高的前 8 句名言,并按 softmax(温度 0.15)的权重抽取一句。与其固定锁定那唯一最接近的名言,越接近的越容易出现,却永不被保证 — 这是一种保留了「命运之感」的概率抽取。当你心灵的地图完全均匀时,则退化为均匀抽取。

简而言之:一句名言的方向越接近你当下心灵的倾斜,它就越容易出现。但最近见过的会被回避,而抽取则从顶层候选之中进行。

4. 名言的波动 — 暗影之卡(每周约两天)

当由日期决定的哈希满足 hash("quote-shadow|date") % 7 < 2(约 2/7,大致每周两天)时,我们会使用「暗影画像」来选取名言。暗影画像以中点 50 为轴将每个因素镜像(mirror[f] = 100 − profile[f]),因此当下处于低位、通常不被看见的元素会被当作高位来处理。

其结果是,一句从不寻常的角度深深产生共鸣的名言,会作为你的「命运之卡」降临。例如,在某一天,对于好奇(FC)很高的人,一句诉说协调(AC)或分析(A)的名言可能会悄然出现,带来洞察、温柔的提醒,或某种补全缺失部分的东西。冷却以及从前 8 名中进行的 softmax 抽样依然适用,因此它仍是一句被精心选出的名言,而非杂音。所说出的话语(今日之语)保持在你一贯的声音之中,让你能温柔地接受这句波动的名言。

这一系列由一个独立于「声音波动」的日期哈希所决定,因此两者未必落在同一天。

关于名言的解读

一句名言的解读(「阅读解读」文字)是绑定在该名言上的固定文本。它并非由算法选出,而是从一开始就附在被选中的名言上。因此,每当某句特定名言出现时,总会显示相同的解读(每句名言对应一份解读)。

③ 选取今日之语与温柔的仪式

这两者从一张「名言的主题」×「你的因素」的网格中选出。文本存放在为每个因素准备的集束(bucket)之中。

主题(10 种):坚持 / 挑战 / 接纳 / 自信 / 休憩 / 学习 / 感恩 / 勇气 / 当下 / 梦想
今日之语:每个集束 6 行(共 360 行)
温柔的仪式:每个集束 5 行(共 300 行)

1. 主题如何决定

从被选中的名言所携带的主题(一个到数个)中,我们挑选其一。

2. 哪个因素的「声音」向你诉说

我们按分数对因素排序(并列时以今日增量来稳定 → 固定的顺序),并原则上以最高位因素(主导因素)的声音来诉说。下文所述的「波动」便在此处登场。

3. 从集束中取一行(带近期重复回避)

在相关的集束内,我们随机选取一行,排除最近出现过的行(最多记住 10 行)。只有当排除它们后再无候选时,我们才允许重复。空集束则退回到共享文本(_default)。

「波动」的设计与频率

为了避免「总是一样所以无聊」,我们在保持轴心(你的倾向)完整的同时,叠加若干层级的波动。

波动 0名言暗影之卡 — 每七天约两天

2/7 (大致每周两天),我们使用「暗影画像」选取一句与你当下处于低位的因素产生共鸣的名言。命运之卡会从与你一贯不同的元素之中,献上一份有力的启示(详情请见 STEP 2 中的「4. 名言的波动」)。该日期哈希独立于声音波动。

波动 1声音因素的波动 — 每七天约两天

当由日期决定的哈希满足 hash("voice|date") % 7 < 2 时,我们会以排名第二的因素的声音来诉说,而非第一位。其概率为 2/7 (约 28.6%,大致每周两天)。「你一贯的自我」的话语与「另一个自我」的话语会轮流到来。其余的五天左右则使用主导因素的声音。

波动 2近期重复回避 — 让同一行不会很快再次出现

今日之语与温柔的仪式各自记住最近 10 行并将其从候选中排除。名言则排除最近 14 天。因为你不会立刻再遇到相同的话语,每个清晨都保持新鲜(只有当候选耗尽时才允许重复)。

波动 3概率抽取 — 即便在相同条件下也不固定于单一结果

名言采用从前 8 名中进行的 softmax 抽取;今日之语与温柔的仪式则在集束内进行随机抽取。因为即便在相同条件下结果也会有所不同,它便永远不会沦为机械的重复。

在这些之上,画像本身也会在 STEP 1 中每天略有偏移,因此主导因素、主题,以及你产生共鸣的名言,都会随时间温柔地漂移。波动的存在是为了「不让一切变得陈旧」,而其频率被设计得相当克制,以免你迷失自己的倾向(轴心)。

同一天,同一份命运 — 关于确定性

关键数值一览

项目数值含义
因素范围 / 初始值0〜100 / 50相对中点的偏离表达了「倾斜」
EMA 平滑系数 α0.15单独一天的答案影响结果的占比(其余 85% 是过往)
增量缩放50 / 6今日增量 ±6 使 0〜100 饱和
名言冷却14 天回避近期出现过名言的窗口期
名言顶层 N8 句名言保留为抽取资格的顶层名言数量
Softmax 温度0.15越小就越集中于高分(命运之感的强度)
名言暗影之卡频率2 / 7(约 29%)选取与当下低位因素共鸣的名言的天数占比
声音波动频率2 / 7(约 29%)以排名第二因素之声诉说的天数占比(独立于暗影之卡)
今日之语 / 温柔的仪式 近期重复回避各 10为让同一行不再出现而记住的数量
素材库规模名言 351 / 今日之语 360 / 温柔的仪式 300每个集束多行,每日循环

本文档基于应用的实现(OracleEngine 的 ProfileEngine、QuoteSelector 与 AdviceSelector,以及 DailyDrawService)撰写。其中的数值与规则可能会随未来的调整而变化。