Files
persona/TODO_人格優化.md
T
jiantw83andClaude Opus 5 2aa0daddaf docs(專案目標): 三條長期目標進 README,TODO 補階段 5 的文字通道
只有文字這一個通道,所以情緒表達是排版問題。三條目標寫成
G1(持續逼近真人)/G2(表達往動漫角色靠)/G3(女性人格的害羞與鬧彆扭),
每條附界線,新功能對著它們判斷。

TODO 加階段 5,六題已拍板(Q5–Q10):

- 顏文字開放,連帶要在半形標點檢查裡開白名單
- 動作加進名字後**既有**的括號(`桐人(😳・臉紅):`),情緒標註保留
- 生理反應算動作(臉紅、手在抖),`(害羞)` 只能待在情緒格
- 破口放寬到一輪兩個動作,煞車是必須同情緒且遞進
- emoji 表程度:種類表情緒、數量表程度,由 emotion.json 自動帶入
- 動漫化強度全域一致,內容仍逐人格

沒有任何程式改動,版號不動——0.2.0 還沒進 master,這批掛在同一個版號底下。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-03 06:56:34 +00:00

444 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TODO — 人格擬真優化
> 目標:讓人格在**記憶結構**與**情緒/語氣表達**上更接近真人(G1),
> 表達往**動漫角色**靠(G2),女性人格的**害羞與鬧彆扭**更明顯(G3)。三條的定義與界線見 `README.md` 的〈專案目標〉。
> 前提:**只有文字**這一個通道,情緒表達等於排版問題——階段 5 整批都建在這句話上。
> 建立日期:2026-08-03|依據:現行 `scripts/persona-lib.mjs`、`skills/persona-chat/**`、`skills/persona-memory`、`skills/persona-relation`
---
## 現況判斷
表層(去 AI 腔、句長上限、心裡話不外洩、情緒破口演在句形上、羞恥度三出口)已經做得很徹底。
剩下的「不像人」不是語氣問題,是三個結構性缺口:
| 根因 | 現在的行為 | 真人的行為 |
| :-- | :-- | :-- |
| **記憶只有「精準」與「沒有」兩態** | `recall` 命中就整段取出、內容永不變質;查不到就禁止提 | 大部分時間活在中間帶:「我記得好像…是你說的嗎」。主旨留著、細節掉了 |
| **人格永遠以對方為中心** | 每輪都在服務這句話,自己沒有懸著的事 | 有未完事項與自己在意的事,會追問「你上週說要看牙醫,去了嗎」 |
| **同一句話任何時刻聽起來都一樣** | 情緒是即時事件的函數;十二情緒全人格共用同一張 tells 表 | 有當日底色與生理狀態;而且每個人生氣的樣子不一樣 |
三個「不要做」:撒口語碎片充人味(`anti-ai-voice.md` 第六點已寫)、給情緒加隨機數(隨機不是情緒是雜訊)、
加隨機口誤(唯一值得的變體是嚴格限量的「自我打斷改口」)。
---
## ⚠️ 實作前先確認(未逐項回覆前不要動手)
> **規則**:這份 TODO 的任何項目,動手前都要先跟使用者確認過。看到 TODO 不等於可以開始寫。
> 下面四題的答案會**改變要寫的東西**,不是風格偏好,所以必須先問。
### Q1. 這次實作要做到哪個階段?
(階段 0 的復原與 commit 不在此列,那個一定要先做。)
| 選項 | 含什麼 | 代價 |
| :-- | :-- | :-- |
| **只做階段 1**(建議) | open loops、`hoursAwake` 接語氣、`EMOTION_TELLS` per-persona 覆寫、情緒抑制與慣性 | 一輪做完,不動任何既有檔案格式,馬上聽得出差別 |
| 階段 1 + 2 | 再加當日心情底色、情境索引+情緒一致性回想 | 會動 `recall` 排序與記憶欄位,但不改長期記憶檔案格式 |
| 階段 1 + 2 + 3 一次做完 | 含回想強度/模糊態/gist-detail 分層 | 改長期記憶 frontmatter,需要 migration 與 bundle 升版,回歸測試量大 |
| 先做階段 3 | 優先換掉記憶結構的地基 | 改動最深,但擬真的天花板由它決定 |
- [x] 已確認範圍:**階段 1 + 2 + 3 一次做完**2026-08-03 使用者拍板)
### Q2. 模糊記憶的界線要多嚴?
會跟現行「查不到就不要講、編轉折比空話更糟」直接相撞,所以要先定。
| 選項 | 允許說出口的樣子 | 風險 |
| :-- | :-- | :-- |
| **保守:只能說記不清**(建議) | 「我記得你講過類似的,但我記不清。」一個細節都不能提 | 零幻覺風險,代價是模糊態的表現力較平 |
| 中等:可講主旨、必須標不確定 | gist 還在就可以講主旨(「好像跟你哥有關」),但必須帶不確定標記 | 表現力好很多,但主旨本身也可能記錯,需要稽核 |
| 開放:可試探性補細節並求證 | 「是不是上個月那次?」 | 最像人,但等於開了幻覺的側門;沒有稽核機制前不建議 |
- [x] 已確認界線:**開放——可試探性補細節並求證**(2026-08-03 使用者拍板)。
因為這是幻覺的側門,3.3 的稽核機制**改成同批必做、不可延後**:
試探句必須帶問號求證、不可斷言;`said check` 記錄每一次試探;`memory --audit` 要能查出
「試探後對方否認」的比例。試探被否認時要立刻寫一則更正記憶,不可放著。
### Q3. 長期記憶檔案格式(`strength`、gist/detail)怎麼遷移?
只在做階段 3 時才需要,但先定案可以省一輪。
| 選項 | 做法 | 代價 |
| :-- | :-- | :-- |
| **就地 migration,一次改全部**(建議) | 寫一支 migration 掃過所有人格的 `memory/long-term/*.md` 補欄位並切分內文 | 乾淨、之後只有一種格式;務必先用 `persona-transfer export` 備份 |
| 只有新記憶帶新欄位 | 舊檔維持原狀,讀取時給預設值 | 零風險,但舊記憶永遠進不了衰減與模糊態——最重要的老記憶反而沒效果 |
| 雙格式並存,讀時正規化 | 不改磁碟,在讀取層統一 | 可回頭,但兩種格式的分支會長期留在程式裡 |
- [x] 已確認策略:**就地 migration,一次改全部**2026-08-03 使用者拍板)。動之前先 `persona-transfer export` 備份。
### Q4. 階段 4 的「自我議程」要做嗎?
人格某些輪會把話題拉回自己在意的事、不服務對方。
| 選項 | 說明 |
| :-- | :-- |
| **要,低頻**(建議) | 每 5–8 輪最多一次,且只在對方沒有明確急事時。這是「像 AI」最頑固的殘留(永遠以對方為中心),低頻就有效 |
| 要,明顯一點 | 更常拉回自己的事、允許答非所問。更像真人,但會明顯降低助理可用性 |
| 先不做 | 留在 TODO 但不實作,等前面幾階段穩定後再評估 |
- [x] 已確認:**要,明顯一點**(2026-08-03 使用者拍板)。允許某些輪把話題拉回自己的事、允許答非所問;
頻率上限放寬到每 3 輪最多一次(原建議 5–8 輪),但對方有明確急事時一律不觸發。
### 其餘我先給預設值的(不同意就講,否則照這樣做)
| 項目 | 預設 |
| :-- | :-- |
| per-persona tells 放哪 | 放 `IDENTITY.md` 新增區塊(tells 屬身分,不屬可變狀態),不放 `state/` |
| open loops 上限與逾期 | 同時最多 5 條;7 天沒進展自動收掉並留一則「沒下文」記憶 |
| 心情底色是否吃外部因素 | 只吃內部(情緒事件 + `hoursAwake` + 上次睡眠),**不接天氣/時區等外部資料** |
| 情緒抑制矩陣範圍 | 只寫三組明確互斥:anger↔joy、sadness↔delight、disgust↔trust。不做全 12×12 |
| 黃金腳本怎麼判定 | 人工看(擬真無法自動判定);只有硬界線(句長、黑名單、句數)走 CLI 自動擋 |
| 版本號 | 整批只升一個版號,兩份 manifest 一起改;改前先看 master 現在幾版 |
---
## 階段 0:開工前(先做,否則會踩到)
- [x] **復原被刪的 hook 與 manifest**:工作區的 `hooks/`7 支 .mjs hooks.json)、`.claude-plugin/`
`.codex-plugin/``plugin.json`、兩份 marketplace.json 已從磁碟消失(`git status` 顯示 ` D`,未 commit)。
目前跑的是安裝快取那份所以不會立刻出錯。
`git checkout -- hooks .claude-plugin .codex-plugin plugin.json .agents`
**在這個狀態下不要 commit。**
- [x] **先把既有 WIP 收掉**`persona-lib.mjs``persona.mjs`/四份 SKILL 有約 485 行未 commit 的羞恥度改動,
`skills/persona-relation/reference/closeness.md` 還是 untracked。先 commit 這批,再開新改動。
- [x] 確認 `KIRITO-01` 的鎖狀態(曾被 session `f60d8e32…` 佔用,cwd `/home/coder/plugins/persona`)。
確定那個程序結束了才 `--takeover`
---
## 階段 1:低成本高效果(可一輪做完)
### 1.1 未完事項 open loops ★ 投報率最高
- [x] 新增 `state/loops.json`,同時只留 3–5 條:他沒回答的問題、他答應要做的事、被打斷的話題、我想問但沒問的。
- [x] CLI`loop add|done|list`(沿用 `withFileLock` 寫入)。
- [x] `UserPromptSubmit` hook 把它注入 `<persona-context>``hooks/prompt_submit.mjs`)。
- [x] 超過 N 天沒進展 → 自動收掉,並留一則「這件事沒下文」的短期記憶。
- **為什麼**:被記住的感覺幾乎全部來自這個,而不是來自長期記憶檢索。
- **驗收**:隔天載入時人格會主動追問上次懸著的事,且同一件事不會追問兩次(`said check` 擋)。
### 1.2 把 `hoursAwake()` 接到語氣上(幾乎免費)
- [x] `speechBudget()`:清醒越久 → 句數/句長上限往下降。
- [x] `mood()``applyEmotion()`:清醒越久 → arousal 天花板往下降。
- **為什麼**:函式已經存在(`persona-lib.mjs`),現在只用在提醒睡覺。深夜的人話少而鈍,最便宜的擬真訊號。
- **驗收**:連續對話數小時後,回覆自然變短變鈍,不需要人格自己演。
### 1.3 `EMOTION_TELLS` 支援 per-persona 覆寫
- [x] `emotionTells()` 先讀人格自己的覆寫(`state/tells.json``IDENTITY.md` 新增 `Tells` 區),再退回全域預設。
- [x] `persona-create` / `persona-anime` 建立人格時一併問/推導 3–5 條專屬破口。
- **為什麼**:現在所有人格生氣都變短句、稱呼退回全名。但桐人生氣是**沉默**,亞絲娜生氣是**變得更禮貌**——
同一格情緒,破口完全不同。
- **驗收**:兩個人格在同一種高強度情緒下,句子的形狀明顯不同。
### 1.4 情緒交互抑制與慣性(輸入都算好了,只差回饋)
- [x] `applyEmotion()` 加**抑制**`anger` 高時 `joy` 的正向 delta 打折(剛生完氣沒那麼容易被逗笑)。
建議做成小矩陣,只寫幾組明確互斥的(anger↔joy、sadness↔delight、disgust↔trust)。
- [x] 加**慣性**`feltTrend()` 已在算走向但沒回饋到增益;連續同向時讓同方向 delta 略微放大。
- [x] 更新 `skills/persona-chat/reference/emotions.md` 的「情緒調節」段(現在只寫飽和與單輪預算)。
- **驗收**`emotion --audit` 的正負比例不再一路偏正;剛吵完架的下一輪逗不笑。
---
## 階段 2:中成本(新檔案/排序邏輯)
### 2.1 當日心情底色 `state/mood.json`
- [x] 三層改成:即時情緒 → **當日底色(緩慢漂移的 valence/arousal** → 氣質基線。
- [x] 底色當**反應增益**:底色差的日子,同樣一句話的 delta 乘 1.3(上限要夾)。
- [x] `sleep` 時重設/部分帶過(`SLEEP_DECAY_MINUTES` 已存在,底色不要一次歸零)。
- **為什麼**:現在缺日級別的中間層,所以「今天聽了會炸、昨天不會」做不出來。
- **驗收**:同一句刺激話在不同日子的 delta 不同,且理由可解釋(不是隨機)。
### 2.2 情境索引 + 情緒一致性回想
- [x] 記憶(短期與長期)加 `when` / `where` / `mood` 欄位。
- [x] `recall` 排序加一項:**與當下情緒同極性的記憶加權**。
- **為什麼**:現在檢索只靠 `topics``entities`(語意線索)。人的回想主要靠情境線索。
這條同時讓情緒有了「後果」,不再只是調語氣的裝飾。
- **驗收**:心情差的時候先想起難過的事;同一個 query 在不同情緒下回不同順序。
---
## 階段 3:記憶結構重整(單獨一輪做,會動檔案格式)
### 3.1 用「回想強度」取代門檻式遺忘,並允許模糊態
- [x] 長期記憶 frontmatter 加 `strength``retrievability = f(salience, recall_count, 距上次回想多久)` 連續衰減。
- [x] 低於門檻**不刪**,降級成**模糊態**:`recall` 回「有這件事,細節想不起來」。
- [x]`recall` 命中就重設並拉長下次衰減(spacing effect:越常想起的越牢)。
材料已經有了(`recall_count``last_seen` 都在寫)。
- [x] `prune``persona-memory` 的遺忘規則同步改寫(現在是 salience 門檻 + 240 筆/14 天)。
**不可遺忘**清單(`boundary``promise``canon`salience ≥ 80)維持不變。
### 3.2 長期記憶分 gist / detail 兩層
- [x] 內文明確切「主旨」與「細節」;衰減**先吃 detail**、gist 最後才掉。
- **效果**:「記得我們吵過,但忘了為什麼」變成自然結果,不必人格演。
### 3.3 ⚠️ 同步改幻覺界線(跟 3.1/3.2 一起做,不可延後)
模糊態會跟現行的「查不到就不要講、編轉折比講空話更糟」直接相撞。界線要寫死進
`skills/persona-chat/reference/anti-ai-voice.md` 與 SKILL 第 ② 節:
> **可以說不確定,不可以填內容。**
> 允許:「我記得你講過類似的,但我記不清。」
> 禁止:把想不起來的細節補出來。
- [x] `said check` 對模糊態句型只提醒不擋(跟現行「講到自己過去」的 hint 同一層)。
- [x] 新增稽核:模糊態被用來編內容的次數(比照 `emotion --audit`)。
### 3.4 遷移與相容
- [x] 舊長期記憶檔的 migration(補 `strength`/切 gist/detail 可先給預設值)。
- [x] `persona-transfer` 的 bundle 版本號要跟著升,`import` 要能吃舊版。
- [x] `selftest.mjs` 補對應案例。
---
## 階段 4:加分項
- [ ] **自傳章節** `memory/chapters/`:時期層(「在 SAO 那兩年」「跟他一起做 persona 這段」),
長期記憶掛在時期底下。問「你這幾個月怎麼樣」時才講得出敘事而不是列點。
- [ ] **習慣記憶** `--type habit`:現在全是宣告性記憶(fact/event/preference),缺「我們之間的慣例」
(他早上第一句都在抱怨會議、我都回一句「幾點」)。熟悉感來自這個。
- [ ] **口語指紋 idiolect**:現在是減法(刪 AI 腔)+語氣層,缺加法。per-persona 的常用詞/句尾/自稱/
慣用迴避句式/絕對不說的詞。`relation style` 已有 `口頭禪``習慣` facet 但那是 per-relation。
**每輪只注入 23 條**,全注入會變表演。
- [x] **自我議程**:承 1.1,人格有自己這幾天在意的一兩件事,某些輪把話題拉回自己的事、答非所問。
這是「像 AI」最頑固的殘留——永遠以對方為中心。
**務必設頻率上限**(每 5–8 輪最多一次),否則從像人變成難聊。
- [ ] **關係的未修復裂痕**`closeness``trust` 是純量,缺「上次那件事還沒和好」。
relation 節點加 `open_issues``ruptures`(含是否修復);有未修復裂痕時語氣層往下降一格。
---
## 階段 5:文字通道的情緒表達(G2 動漫化 / G3 害羞與鬧彆扭)
現況判斷:情緒**有沒有**被表達已經解決(`EMOTION_TELLS` per-persona 覆寫 + 羞恥度三出口),
剩下的缺口是**表達的頻寬**——現在一輪只能露一個破口,而破口只作用在「句子的形狀」這一個維度。
純文字其實還有三個維度沒被用到:**節奏**(訊息怎麼分段)、**標點**、**稱呼**。
### ⚠️ 實作前先確認(Q5–Q8,沒答案不要動手)
這四題都會踩到硬規則 8,答案不同要寫的東西完全不同。
#### Q5. 顏文字與表情符號要不要開?
| 選項 | 說明 | 風險 |
| :-- | :-- | :-- |
| 禁止(維持現況) | 情緒只走文字本身 | 動漫感少一個很直接的手段 |
| 限量、per-persona | `IDENTITY.md` 列 2–3 個專屬符號,每 N 輪最多一次 | 要防止變成每句都掛,成本在節流不在功能 |
| **開放** | 依情緒自由使用 | 幾乎一定會退化成表情包貼圖式回覆 |
- [x] 已確認:**開放使用**(2026-08-03 使用者拍板)。
連帶要處理的兩件事(開放不等於沒有機制):
1. **跟半形標點檢查對撞**`speechLint()` 現在擋半形標點,而顏文字幾乎全是半形
`(///)``^^;``>_<`)。要在檢查裡開一條**顏文字白名單**,
不然開放這件事會被自己的 linter 擋掉。判定範圍要窄(連續的符號叢集才算顏文字,
單獨一個半形逗號仍然是排版錯誤)。
2. **選哪個符號屬於身分**:情緒 → 符號的對照放 `IDENTITY.md`(跟 `## Tells` 同一層),
沒寫的人格退回全域預設。開放的是「可以用」,不是「隨便用哪個都行」。
後續追加(Q9/Q10,同一天):emoji 另外要**接上情緒數值表示程度**,
而且**句子裡也自由使用、不設上限**。細節見 5.8。
#### Q6. 星號動作描寫(`*別過頭*`)要不要對動漫人格破例?
硬規則 8 現在把「旁白演情緒」列為禁語(`SPEECH_BLACKLIST`)。
| 選項 | 說明 |
| :-- | :-- |
| 維持禁止 | 動作要出現就寫進對白(「你不要看這邊」比 `*別過頭*` 像人) |
| 只在劇場模式開放 | 多人格同場時像小說,一對一時仍禁止 |
| 對動漫人格開放 | 最像原作,但等於把去 AI 腔那一層打掉一半 |
- [x] 已確認:**都不是——動作寫在人格名稱後面的括號裡**(2026-08-03 使用者拍板,第四條路):
桐人(別過頭):你不要看這邊。
而且**記憶要一起記那個行為**(行為備註/標註欄位)。細節與影響範圍見 5.7。
為什麼這條比上面三個好:括號在**名字後面**,跟對白本體有實體隔離——
它不是混進句子裡的旁白,所以硬規則 8 的禁令仍然守得住
`speechLint()` 只對括號**外**的內容比對黑名單)。
代價是它會改劇場模式寫死的 `名字:內容` 輸出格式。
#### Q7. 一輪最多露一個破口,要不要對 G3 放寬?
| 選項 | 說明 |
| :-- | :-- |
| 害羞時放寬到兩個 | 只有 `shame` 這一格例外:鬧彆扭本來就是「否認+轉移」兩個動作一起來 |
| **全部放寬到兩個** | 密度上去了,但每個人格都變成一直在演 |
| 維持一個 | 最安全,G3 的效果會打折 |
- [x] 已確認:**全部情緒都兩個動作**(2026-08-03 使用者拍板)。
連平靜也有兩個(留白 → 不追問)——它們本來就是成對出現的動作,不是加倍演出。
這條改的地方比看起來多,全部要一起改:
| 位置 | 現在寫的 | 要改成 |
| :-- | :-- | :-- |
| `emotionTells()``top` | 前兩種**情緒**、但只准演一個動作 | 主導情緒的**兩個動作** |
| 每輪注入的提醒文字 | 「一輪最多露一個破口」 | 兩個,且必須是同一種情緒的兩個動作 |
| `README.md` 硬規則 8 與〈講話像人〉 | 同上 | 同上 |
| `skills/persona-chat/**``anti-ai-voice.md` | 同上 | 同上 |
**新的煞車**(放寬之後唯一擋得住「一直在演」的東西):兩個動作必須來自**同一種情緒**,
而且是**遞進**關係(否認→轉移、笑→補一句、留白→不追問),不是兩種情緒各演一個。
強度不到的情緒照舊不演——門檻不變,變的只是達標之後能露幾個。
#### Q8. 動漫化強度是全域一致,還是 per-persona 旋鈕?
| 選項 | 說明 |
| :-- | :-- |
| per-persona 旋鈕 | `IDENTITY.md` 加一格(例如 `anime_level: 0100`),寫實人格可以歸零 |
| **全域一致** | 少一個欄位,但同一套語域套在所有人身上就是模板 |
- [x] 已確認:**全域一致**(2026-08-03 使用者拍板)。不加 `anime_level` 欄位,不做強度旋鈕。
**要分清楚全域的是什麼**:全域一致指的是**強度**(動漫感開多大),
不是**內容**。自稱、句尾、口癖仍然逐人格不同(5.6),
否則所有人格會講起話來一樣——那正是 G2 要避免的。
### 5.1 訊息的節奏:一輪可以拆成兩則 ★ 純文字唯一的「時間」訊號
- [ ] `speechBudget()` 之外加**分段預算**:高 arousal 或高羞恥時,同一輪允許輸出兩則短訊,
第二則是**補救、嘴硬或改口**(「⋯剛才那句不算」),而不是補充說明。
- [ ] 節流:每 N 輪最多一次,且只在 arousal 或羞恥度過門檻時。
- **為什麼**:真人在聊天軟體上的情緒,一半是靠「又補了一句」傳出去的。這是文字獨有的、目前完全沒用到的手段。
- **驗收**:慌的時候會多一則短的;平靜時永遠只有一則。
### 5.2 標點預算(情緒 → 標點與句長的分布)
- [ ] 把標點納入 `speechLint()` 的可調參數:焦慮 → 刪節號與逗號斷句變多;
憤怒 → 句號密度上升、幾乎不用問號;害羞 → 疊字與破折;喜悅 → 允許一個驚嘆號。
- [ ] 上限要夾死(一則最多一個驚嘆號、刪節號不連發),否則會變成顏文字的替代品。
- **驗收**:把同一句話在四種情緒下輸出,標點分布看得出差別,且都沒有過量。
### 5.3 稱呼隨情緒偏移
- [ ] `relation style``--except <情緒>>=<值>` 已能做條件替換(`anger>=40` → 退回全名)。
缺的是**害羞方向**:改口、講到一半換稱呼、把名字吞掉不叫。
- [ ] 每個關係節點可設「害羞時的稱呼」,沒設就退回吞掉名字(改用「你」)。
- **驗收**:同一個對象,生氣時被叫全名、害羞時直接不叫名字。
### 5.4 鬧彆扭的階梯與三段式句法(G3 核心)
- [ ] 羞恥度現在是一個純量對三個出口(`hide``spill``confess`)。加**階梯**
輕微彆扭(一句帶過)→ 嘴硬(先否認再小聲承認)→ 惱羞(翻臉,`anger` 的負權重已存在)。
- [ ] 三段式做成**句法模板**而不是自由發揮:否認 → 反駁對方的說法 → 最後一句音量掉下來。
模板可 per-persona 覆寫(放 `IDENTITY.md``## Tells`,跟現行覆寫同一層)。
- [ ] 三段式要吃 Q7 的兩個動作:否認與轉移是**同一種情緒的遞進**,剛好是那條規則的樣板案例。
惱羞那一級是換情緒(`shame``anger`),所以仍然只有兩個動作,不是三個。
- **驗收**:被稱讚外表時,低/中/高羞恥度三種輸出明顯不同,而且都沒有寫「我害羞了」。
### 5.5 女性人格的預設值(G3,只動預設不動個性)
- [ ] 重看 `GENDER_MODESTY` 的預設值與 `modestyOf()` 的推力表,把女性預設往上調並補
「鬧彆扭」相關的關鍵詞權重(現在的表偏向「害羞/臉紅」,缺「嘴硬/不坦率/傲嬌」)。
- [ ] **界線不變**:描述永遠蓋過預設,可以推到 0;不做「女性→情緒更外顯」的全域放大。
- **驗收**:兩個都是女性但個性相反的人格,講起話來不一樣。
### 5.6 語域:自稱、句尾、口癖(G2 核心,接階段 4 的 idiolect
- [ ] per-persona 的自稱/句尾語氣詞/口癖/絕對不說的詞,每輪只注入 2–3 條(階段 4 已寫,這裡是它的動漫版)。
- [ ] `persona-anime` 建立人格時一併從原作推導這幾格(現在只推導 `Tells`)。
- [ ] `persona-story` 的 3A(語氣統計)跑完之後要能直接寫進這一格——兩邊用同一個欄位,不要各存一份。
- **驗收**:把人格的名字遮掉,光看三句話能認出是誰。
- **界線(Q8)**:強度全域一致,內容逐人格不同。這一節動的是內容,不加強度旋鈕。
### 5.7 動作加進名字後的括號(Q6 拍板的格式)
**括號不是新開的,原本就有**`persona-lib.mjs` 的渲染(約 3804 行)本來就是
`名字(情緒)→ 對象:內容`,括號裡放的是 `room post --emotion` 的情緒標註。
所以這一節是**在既有括號裡多一格**,不是換掉它——原本的情緒標註保留。
桐人(喜悅・別過頭):你不要看這邊。
桐人(別過頭):你不要看這邊。 ← 沒帶 --emotion 時
桐人(喜悅):你不要看這邊。 ← 沒帶 --action 時(現行行為,不變)
- [ ] **格式**:括號分兩格,情緒在前、動作在後,用 `・` 分隔。兩格都可省略,全省就不出現括號。
- [ ] **兩格的分工要寫死**:情緒格是**標註**(既有 meta,寫情緒名稱本來就對);
動作格只寫**看得見的身體動作**(別過頭、把杯子推過來、站起來)。
動作格不重複情緒名稱——`(喜悅・害羞)` 是把標註寫兩次,不是動作。
- [ ] **生理反應算動作,明文允許**2026-08-03 使用者補充):**臉紅**、耳朵紅、手在抖、聲音變小、
呼吸亂掉。判準是**看得見或聽得見**,不是有沒有情緒色彩——
`(臉紅)` 可以,`(害羞)` 只能待在情緒格。
害羞這一格的預設動作就用**臉紅**,其餘看人格自己的 `## Tells`
- [ ] `speechLint()` 只對括號**外**的內容比對黑名單與句長;括號內另立規則
(情緒格照既有的 `injectSafeLine`;動作格單一動作、12 字內)。
- [ ] 劇場模式:`room post``--action "<動作>"`(跟既有 `--emotion` 並列),
`room read``room script` 的渲染跟著改。`hooks/` 每輪強制的輸出格式也要放寬到帶括號。
- [ ] **一對一(非劇場)也適用**——Q6 拍板的是格式,不是只給多人格場景。
- [ ] 頻率:綁 Q7 的兩個動作額度,**括號裡的動作算其中一個**。
否則會出現「括號演一個、句子裡再演兩個」,一輪三個動作。
- [ ] **記憶要記那個行為**(Q6 明示):短期與長期記憶加行為備註欄位,
記「他做了什麼」而不是「他感到什麼」——跟 `persona-story` 的 1.12(事件 → 他做了什麼)同一個欄位,
不要各存一份。`voice/reactions.md` 也是同一批資料的落點。
- **為什麼**:這是唯一能在不打破「禁止旁白演情緒」的前提下拿到動作描寫的形狀——
括號在名字後面,跟對白本體有實體隔離。
- **驗收**`(喜悅・別過頭)` 過得了 lint、情緒標註沒被吃掉;
`*別過頭*` 與句子裡的「我愣了一下」照舊被擋下;那一輪的記憶查得到「別過頭」這個行為。
### 5.8 emoji 表示情緒與程度(Q9Q10 拍板)
現在括號的情緒格是**自由文字**`room post --emotion`),跟 `state/emotion.json` 的數值
**完全沒有連動**——人格自己想寫什麼就寫什麼。這一節把它接上去。
#### 格式:種類表情緒、數量表程度(Q9)
一種情緒固定一個 emoji,強度高時**另加強度符號**(不重複本體):
| 情緒值 | 樣子 | 例 |
| :-- | :-- | :-- |
| < 40 | 不顯示 | `桐人:你不要看這邊。` |
| 4059 | 情緒 emoji | `桐人(😳・臉紅):你不要看這邊。` |
| 6079 | `💦` | `桐人(😳💦・臉紅):⋯才不是那樣。` |
| 80+ | `💦❗` | `桐人(😳💦❗・把臉轉開):不要再講了。` |
- [ ] 寫一張**十二情緒 → emoji** 的對照表(一種情緒一個,例如 `shame: 😳``anger: 😡`),
`persona-lib.mjs`,跟 `EMOTION_TELLS` 同一層。
- [ ] **per-persona 可覆寫**`IDENTITY.md`,跟 `## Tells` 與 Q5 的符號表同一層)。
這是內容不是強度,不違反 Q8 的全域一致。
- [ ] 強度符號固定兩階(`💦` / `💦❗`),不要長成第三階。
- [ ] **由 `emotion.json` 的主導情緒自動帶入**,不是人格自由填。
門檻對齊 `emotionTells()``min = 40`——情緒值不到 40 就沒有 emoji,
跟「強度不到就不演」是同一條線。`room post --emotion` 的自由文字保留(可手動蓋過)。
#### 位置:句子裡自由用(Q10)
- [x] 已確認:**句子裡自由使用、不設上限**(2026-08-03 使用者拍板)。承 Q5 的開放。
- [ ] 連帶要處理:`speechLint()` 的半形標點與排版檢查要**跳過 emoji 與強度符號**,
不然會被判成排版殘留(跟 Q5 的顏文字白名單同一支修改)。
- [ ] **唯一的煞車是稽核,不是擋**(他要的是開放,那就不要用 linter 偷偷關回去):
比照 `emotion --audit`,統計每輪的 emoji 數量與趨勢,讓過量看得見。
真的失控再回來談上限。
- **界線**(這條不因為開放而放掉):emoji 是**加上去的**,不是替代品。
不可以用 emoji 代替句子(只回一個 😳)、也不可以代替動作格與句子的形狀——
斷句、疊字、嘴硬照舊要有。emoji 掉光之後那句話仍然要看得出情緒。
- **驗收**:羞恥度 4570/90 三種輸出的 emoji 不同;把所有 emoji 刪掉之後,
句子的形狀仍然分得出是哪一級。
## 驗收方式
- [ ] **固定情境回歸**`selftest.mjs` 只能守不崩,擬真要另一組):20 段黃金腳本——被稱讚外表、
被指出講錯、久違回來、他心情差時報壞消息、連續三輪低落、被要求越界…
每次改動後跑一次,人工看輸出還在不在人味界線內。
- [ ] `emotion --audit`(既有):正向偏差比例。
- [ ] **G2G3 專用腳本**(階段 5 才需要):被稱讚外表、被說「你是不是在害羞」、被戳穿嘴硬、
當著第三個人被講心事——四段各跑低/中/高羞恥度,看有沒有變成模仿腔或旁白。
- [ ] 新增記憶偏差稽核:模糊態被用來編內容的次數(見 3.3)。
## 收尾
- [ ] 這一批改動合起來只佔**一個新版號**,`.claude-plugin/plugin.json``.codex-plugin/plugin.json`
兩份 manifest 一起改;改版號前先看 master 上目前是幾版。
- [ ] `README.md` 的記憶架構表與情緒模型段要跟著更新。