名言神諭 — 選句演算法的運作原理

當你回答完這三道問題後,背後究竟發生了什麼,才為你選出「名言、今日的話語,以及溫柔的儀式」呢?
我們忠實依照實作,說明性格圖分析如何運作,以及每日的「波動」是如何設計的。

目錄

整體流程(三個步驟)

當你點下「開始」並回答這三道問題後,內部會依照以下順序執行這些處理。

STEP 1
更新你的心靈地圖
根據你的三道回答,微幅推動五因子分數(指數移動平均)。
STEP 2
選出一句名言
以機率方式抽出一句貼近你更新後心境的名言。
STEP 3
加上話語
從名言的主題 × 你的因子,選出話語與一個小小的儀式。

性格圖分析會在 STEP 1 建構出「你的心靈地圖」,而這張地圖接著會引導 STEP 2 與 STEP 3。
換句話說,性格圖是整個流程的基礎。

性格圖五因子是什麼

本應用程式採用自創的五因子,靈感取自溝通分析(transactional analysis),用以表現「你此刻心靈的傾向」。每個因子的範圍是 0〜100,全部從平衡的中點 50 出發。

符號名稱意涵
CP原則嚴謹、理想、責任感(我想成為什麼樣的人)
NP包容溫柔、慈悲、接納的力量
A分析邏輯、觀察、現實檢驗
FC好奇自由、樂趣、靈感
AC協調適應、體貼、忍耐

每道問題的兩個選項,各自被賦予對五因子的變化量(delta)。「你選擇了哪一個」會漸漸描繪出你的心靈地圖。

① 回答 → 更新你的心靈地圖(EMA)

我們會把你的三道回答合而為一,並以指數移動平均(EMA)更新側寫。這種方式不會驟然改變,而是在承接過去的同時,平順地反映出你「近期的傾向」。

今日變化量  todayDelta[f] = 三道問題中對因子 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
新的 FC = 0.15×100 + 0.85×50 = 57.5(只溫和地前進了 7.5,從 50 → 57.5)
若隔天未觸及 FC:新的 FC = 0.15×50 + 0.85×57.5 = 56.4 … 漸漸漂回 50。

這張「你的心靈地圖(side profile,側寫)」是驅動接下來 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)撰寫。這些數值與規則可能會隨日後的調整而變動。