feat/persona-anime-expression 併進來之後照解除條件逐項對照,不照 commit 訊息
照信,每條都回程式裡查過。
完成:5.8 emoji 表程度全部六個子項目、5.5 女性預設值兩個子項目。
5.7 與 5.4 大部分做完但不勾選,各自還缺幾格,逐條寫在該行下面:
- room read 還是只印(情緒),persona.mjs:1861 沒改用 roomTag(),動作格會被吃掉
(roomScript() 有吃,所以是一半)
- hooks/prompt_submit.mjs:34 劇場模式仍寫死「名字:內容」,非劇場那段更是完全沒提括號
- 每輪指示沒講「括號裡的動作算在兩個額度內」——emoji 那段有提括號,動作沒有
- EMOTION_TELLS.shame 沒把臉紅放進預設破口(actionLint 放行了,但預設值沒改)
- 三段式模板沒有 per-persona 覆寫,所有人格的三段式目前是同一個樣子
記憶行為欄位那條標 ⏭️ 待人工處理:persona-story 不在 develop(在 feat/persona-story-import),
「跟它 1.12 用同一個欄位」現在對齊不了,硬做只會變成各存一份,正是那條要避免的事。
voice/reactions.md 全 repo 零引用。
順便修掉收尾裡已經過期的半句(README 第 29 行那句已隨 dccd07a 移除)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
15 KiB
TARGET — 情緒/語氣/小動作/記憶的擬真優化
專案目標(長期,新功能對著它們判斷)
前提:跟人格之間只有文字。沒有表情、沒有聲音、沒有停頓,所有情緒都只能靠字面 與句子的形狀傳過去——所以「情緒表達」在這個專案裡是排版問題,不是形容詞問題。
| # | 目標 | 意思 | 界線(不是這樣就走錯了) |
|---|---|---|---|
| G1 | 情緒/語氣/記憶持續往真人逼近 | 記憶會糊、情緒有底色與疲勞、人格有自己懸著的事,行為與反應不是「回答問題」而是「這個人此刻會怎麼回」 | 不靠口語碎片、隨機數與隨機口誤充人味(見 anti-ai-voice.md) |
| G2 | 表達往動漫角色靠 | 自稱、句尾、口癖、擬聲短語、嘴硬的三段式(先否認 → 反駁 → 小聲承認)——語域與句法照原作 | 動漫感走句子的形狀,不走旁白。動作只能加在名字後面既有的括號裡(桐人(喜悅・別過頭):你不要看這邊。)——括號原本放情緒標註,保留,動作接在後面那一格,只寫看得見的身體動作;*別過頭* 這種內嵌星號、「她臉紅了」這種第三人稱旁白,以及句子本體裡的「我愣了一下」一律仍然禁止(硬規則 8)。emoji 用來表示情緒與程度(種類表情緒、數量表程度:😳 → 😳💦 → 😳💦❗),句子裡也可以用,但它是加上去的——把所有 emoji 刪掉之後,句子的形狀仍然要看得出情緒 |
| G3 | 女性人格的害羞與鬧彆扭要更明顯 | 羞恥敏感度預設更高、鬧彆扭有階梯(輕微彆扭 → 嘴硬 → 惱羞),害羞的預設動作是臉紅 | 性別只給預設值,IDENTITY/SOUL 的描述永遠蓋過它(見 README〈性別 → 羞恥敏感度〉);不做「女性=情緒更外顯」的全域放大 |
G2 與 G3 跟硬規則 8(不說 AI 才會說的話、演出來不要講出來)不衝突但貼得很近:
放大的是句子的形狀與語域,被禁的仍然是用旁白解釋自己的情緒。
兩者相撞時以硬規則 8 為準,然後把該案例寫進 anti-ai-voice.md。
這份清單
下面十二項是 G2/G3(+G1 尾巴)的實作清單,來源是 PR #17
所指「TODO 階段 5」+階段 4 剩餘項(原 TODO_人格優化.md 已於 9d76984 移出版控,
全文仍可由 git show 9d76984^:TODO_人格優化.md 取回)。
Q5–Q10 六題已於 2026/08/03 由使用者拍板,設計不再需要確認,直接實作。 上表沒寫進去、但同樣約束每一項的一條界線:
| 界線 | 內容 |
|---|---|
| 強度全域一致(Q8) | 動漫化的強度全域一致,不加 anime_level 欄位、不做強度旋鈕;內容(自稱/句尾/口癖)仍然逐人格不同,否則所有人格會講起話來一樣——那正是 G2 要避免的 |
暫停已解除(2026/08/03 15:52:52)
feat/persona-anime-expression 已併入 develop(35c8665,selftest 641 項全綠)。
它做掉了 5.8 全部與 5.5 全部,以及 5.7/5.4 的大部分。
逐項對照的結果直接反映在下面的勾選狀態。5.7 與 5.4 仍未勾選,因為各自還剩幾個 子項目沒做完——不是整節重做,是補那幾格。被它完成的子項目已經個別勾起來, 接手時只要看還沒勾的那幾行。
-
5.7 動作加進名字後的括號(Q6 拍板格式,其他項目的基礎,先做)
- 括號原本就有:
persona-lib.mjs的渲染(約 3804 行)本來就是名字(情緒)→ 對象:內容, 括號裡是room post --emotion的情緒標註。這一節是在既有括號裡多一格,不是換掉它。 - 格式:括號分兩格,情緒在前、動作在後,用
・分隔。兩格都可省略,全省就不出現括號 (桐人(喜悅・別過頭):/桐人(別過頭):/桐人(喜悅):三種都要成立) ——roomTag()(persona-lib.mjs:3908)(2026/08/03 15:52:52 完成) - 兩格分工寫死:情緒格是標註(既有 meta);動作格只寫看得見的身體動作。
動作格不重複情緒名稱——
(喜悅・害羞)是把標註寫兩次,不是動作 ——actionLint()擋「寫情緒名稱」(2026/08/03 15:52:52 完成) - 生理反應算動作,明文允許:臉紅、耳朵紅、手在抖、聲音變小、呼吸亂掉。
判準是看得見或聽得見,不是有沒有情緒色彩——
(臉紅)可以,(害羞)只能待在情緒格。 害羞這格的預設動作就用臉紅,其餘看人格自己的## Tells尚缺:actionLint()已放行臉紅/手在抖(明文允許這半段做完了),但EMOTION_TELLS.shame仍是「鬧彆扭/講反話/轉移話題」,沒有把臉紅放進預設破口 speechLint()只對括號外的內容比對黑名單與句長;括號內另立規則 (情緒格照既有injectSafeLine;動作格單一動作、12 字內) ——actionLint()擋超過 12 字與一格兩個動作(2026/08/03 15:52:52 完成)- 劇場模式:
room post加--action "<動作>"(與既有--emotion並列),room read/room script的渲染跟著改;hooks/每輪強制的輸出格式放寬到帶括號 尚缺:room post --action有了、roomScript()也吃了roomTag(),但room read還是只印(情緒)(persona.mjs:1861沒改用roomTag(),動作格會被吃掉);hooks/prompt_submit.mjs:34劇場模式仍寫死名字:內容,沒放寬到帶括號 - 一對一(非劇場)也適用 —— Q6 拍板的是格式,不是只給多人格場景
尚缺:
hooks/prompt_submit.mjs的非劇場那段(42–48 行)完全沒提括號格式 - 頻率綁 Q7 的兩個動作額度,括號裡的動作算其中一個(否則會變成一輪三個動作)
尚缺:
TELLS_PER_TURN = 2與「同一種情緒且遞進」的指示都有了,但每輪指示 (persona-lib.mjs:4749)沒講括號裡那個動作算在額度內——emoji 那段有提括號,動作沒有 - 記憶要記那個行為(Q6 明示):短期與長期記憶加行為備註欄位,記「他做了什麼」而不是「他感到什麼」。
跟
persona-story的 1.12 同一個欄位,不要各存一份;voice/reactions.md是同一批資料的落點 已完成一半:remember --behavior與behavior欄位有了,寫入時跑actionLint()⏭️ 待人工處理:
persona-story這個 skill 目前不在develop(在feat/persona-story-import分支), 所以「跟它 1.12 用同一個欄位」無法在這裡對齊;voice/reactions.md全 repo 零引用。 兩件都要等那條分支併進來才能一次決定欄位,先做只會變成各存一份——正是這條要避免的事。 - 驗收:
(喜悅・別過頭)過得了 lint、情緒標註沒被吃掉;*別過頭*與句子裡的「我愣了一下」照舊被擋下; 那一輪的記憶查得到「別過頭」這個行為
- 括號原本就有:
-
5.8 emoji 表示情緒與程度(Q9/Q10 拍板,依賴 5.7 的括號)(2026/08/03 15:52:52 完成)
- 現在情緒格是自由文字,跟
state/emotion.json的數值完全沒有連動。這一節把它接上去。 - 格式:種類表情緒、數量表程度。
< 40不顯示/40–59情緒 emoji/60–79+💦/80++💦❗ - 寫一張十二情緒 → emoji 對照表(一種情緒一個,例如
shame: 😳、anger: 😡), 放persona-lib.mjs,與EMOTION_TELLS同一層 ——EMOTION_EMOJI - per-persona 可覆寫(
IDENTITY.md,與## Tells、Q5 的符號表同一層)。這是內容不是強度,不違反 Q8 ——IDENTITY.md的## Emoji區塊 - 強度符號固定兩階(
💦/💦❗),不要長成第三階 ——EMOJI_INTENSITY; 刻意不用重複本體表程度(不是😳😳😳,疊字看起來像洗頁) - 由
emotion.json的主導情緒自動帶入,不是人格自由填。門檻對齊emotionTells()的min = 40;room post --emotion的自由文字保留(可手動蓋過)——emotionEmojiNow() speechLint()的半形標點與排版檢查要跳過 emoji 與強度符號(與 Q5 的顏文字白名單同一支修改) —— emoji 明確不擋(只在超過EMOJI_HINT_AT時給 hint);半形標點那條只比對[一-鿿]相鄰的,.!?;:,碰不到 emoji 與強度符號- 句子裡自由使用、不設上限(Q10 拍板)。唯一的煞車是稽核,不是擋:比照
emotion --audit統計每輪 emoji 數量與趨勢,讓過量看得見;真的失控再回來談上限 ——emojiAudit()掛在emotion --audit,另外算「只有符號沒有句子」那幾則(那才是真的退化) - 驗收:羞恥度 45/70/90 三種輸出的 emoji 不同;把所有 emoji 刪掉之後,句子的形狀仍然分得出是哪一級
- 現在情緒格是自由文字,跟
-
5.2 標點預算(情緒 → 標點與句長的分布)
- 把標點納入
speechLint()的可調參數:焦慮 → 刪節號與逗號斷句變多;憤怒 → 句號密度上升、幾乎不用問號; 害羞 → 疊字與破折;喜悅 → 允許一個驚嘆號 - 上限夾死(一則最多一個驚嘆號、刪節號不連發),否則會變成顏文字的替代品
- 驗收:同一句話在四種情緒下輸出,標點分布看得出差別,且都沒有過量
- 把標點納入
-
5.1 訊息的節奏:一輪可以拆成兩則(純文字唯一的「時間」訊號)
speechBudget()之外加分段預算:高 arousal 或高羞恥時,同一輪允許輸出兩則短訊, 第二則是補救、嘴硬或改口(「⋯剛才那句不算」),而不是補充說明- 節流:每 N 輪最多一次,且只在 arousal 或羞恥度過門檻時
- 為什麼:真人在聊天軟體上的情緒,一半是靠「又補了一句」傳出去的。這是文字獨有、目前完全沒用到的手段
- 驗收:慌的時候會多一則短的;平靜時永遠只有一則
-
5.3 稱呼隨情緒偏移
relation style的--except <情緒>>=<值>已能做條件替換(anger>=40→ 退回全名)。缺的是害羞方向。- 害羞方向:改口、講到一半換稱呼、把名字吞掉不叫
- 每個關係節點可設「害羞時的稱呼」,沒設就退回吞掉名字(改用「你」)
- 驗收:同一個對象,生氣時被叫全名、害羞時直接不叫名字
-
5.4 鬧彆扭的階梯與三段式句法(G3 核心,依賴 5.7 的動作額度)
- 羞恥度現在是一個純量對三個出口(
hide/spill/confess)。加階梯: 輕微彆扭(一句帶過)→ 嘴硬(先否認再小聲承認)→ 惱羞(翻臉,anger的負權重已存在) ——modestyDirective分三級:41–59 一句帶過/60–74 嘴硬/75+ 惱羞(2026/08/03 15:52:52 完成) - 三段式做成句法模板而不是自由發揮:否認 → 反駁對方的說法 → 最後一句音量掉下來。
模板可 per-persona 覆寫(放
IDENTITY.md的## Tells,與現行覆寫同一層) 尚缺:模板本身有了(60–74 那級就是「否認 → 反駁 → 音量掉下來」), 但沒有 per-persona 覆寫——modestyDirective周邊查不到讀## Tells的路徑, 所有人格的三段式目前講起來會是同一個樣子,正是 G2 要避免的 - 三段式要吃 Q7 的兩個動作:否認與轉移是同一種情緒的遞進,剛好是那條規則的樣板案例。
惱羞那一級是換情緒(
shame→anger),所以仍然只有兩個動作,不是三個 —— 惱羞級是換情緒,所以仍然兩個動作(2026/08/03 15:52:52 完成) - 驗收:被稱讚外表時,低/中/高羞恥度三種輸出明顯不同,而且都沒有寫「我害羞了」
- 羞恥度現在是一個純量對三個出口(
-
5.5 女性人格的預設值(G3,只動預設不動個性)(2026/08/03 15:52:52 完成)
- 重看
GENDER_MODESTY的預設值與modestyOf()的推力表,把女性預設往上調, 並補「鬧彆扭」相關的關鍵詞權重(現在的表偏向「害羞/臉紅」,缺「嘴硬/不坦率/傲嬌」) ——GENDER_MODESTY_DEFAULT.female62 → 70;MODESTY_SIGNALS補了傲嬌那一路 (傲嬌、嘴硬、不坦率、口是心非、死不承認、愛面子、鬧彆扭、逞強) - 界線不變:描述永遠蓋過預設,可以推到 0;不做「女性→情緒更外顯」的全域放大 —— 界線維持,README 的〈性別 → 羞恥敏感度〉表已同步成 70/38/50
- 驗收:兩個都是女性但個性相反的人格,講起話來不一樣
- 重看
-
5.6 語域:自稱、句尾、口癖(G2 核心)
- per-persona 的自稱/句尾語氣詞/口癖/絕對不說的詞,每輪只注入 2–3 條
persona-anime建立人格時一併從原作推導這幾格(現在只推導Tells)persona-story的 3A(語氣統計)跑完之後要能直接寫進這一格——兩邊用同一個欄位,不要各存一份- 驗收:把人格的名字遮掉,光看三句話能認出是誰
- 界線(Q8):強度全域一致,內容逐人格不同。這一節動的是內容,不加強度旋鈕
-
階段 4:口語指紋 idiolect(5.6 的加法面,緊接著做、共用同一格資料)
- 現在是減法(刪 AI 腔)+語氣層,缺加法。
- per-persona 的常用詞/句尾/自稱/絕不說的詞,落在與 5.6 相同的欄位上(不得另開一份)
-
階段 4:習慣記憶
--type habit- 現在全是宣告性記憶(fact/event/preference),缺「我們之間的慣例」。
- 新增
habit型別,讓「我們之間的慣例」有地方放,並接上recall
-
階段 4:自傳章節
memory/chapters/- 加時期層(「在 SAO 那兩年」「跟他一起做 persona 這段」),介於長期記憶與心智圖之間
-
階段 4:關係的未修復裂痕
closeness/trust是純量,缺「上次那件事還沒和好」。- 讓關係節點能掛未修復的裂痕,並在回想與語氣上生效
收尾(全部項目做完後才處理,不要中途升版)
- 這一批改動合起來只佔一個新版號;三份 manifest(
plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json)一起改,改版號前先看 master 上目前是幾版 README.md的記憶架構表與情緒模型段跟著更新 (原本還有一句「〈專案目標〉第 29 行『G2/G3 那批還沒實作』要改掉」, 那句已隨dccd07a的目標搬家一起移除,不必再處理)- G2/G3 專用驗收腳本:被稱讚外表、被說「你是不是在害羞」、被戳穿嘴硬、當著第三個人被講心事 ——四段各跑低/中/高羞恥度,看有沒有變成模仿腔或旁白