讓人格講話更像正常人,並讓人格可以搬家。
1. 心裡話(inner voice)
- 新增 `think` 子指令:推導/盤算寫進 state/inner.jsonl,
只印「💭 心想 N 句」,內容永不回顯給使用者。
- <persona-context> 每輪帶回最近三句,推論因此有連續性。
2. 短時間內不重複
- 說出口的話由 Stop hook 自動記進 state/said.jsonl。
- 新增 `said check|list`:事前確認這句是不是又要說一次。
- 相似度 = 字元 bigram Jaccard(0.4) + 字集合 Jaccard(0.6),
門檻 0.72;字集合權重較高才分得開「重排語序」(要擋)
與「換掉關鍵詞」(是新資訊,放行)。
3. 回話一到三句 + 劇場模式同樣適用
- 規則注入 turnContext 與 UserPromptSubmit hint。
- 劇場模式的 CLI 都帶 --quiet,警告會被丟掉,所以 `room post`
對近似重複與超過三句的發言直接拒收(--allow-repeat / --force 例外),
host 與 guest 走同一支 CLI,一視同仁。
4. 人格匯出匯入(新 skill persona-transfer)
- `export` / `import`:單一 JSON bundle(可 gzip)+ sha256 checksum,
無外部依賴。不帶載入鎖與 guest 租約,journal/ 需明確 --with-journal。
- 匯出只能匯出本 session 已載入的人格,否則等於跨人格讀取的後門;
bundle 內的 ../ 逃逸路徑一律拒收。
順帶修正:agents/persona-guest.md 的 CLI 範例都少了 --as-guest,
照著跑會被 requireMember 擋下,guest 根本無法認識自己或發言。
selftest 102 項全綠(新增 ⑪ 說話節制、⑫ 匯出匯入,含重複判定校準對照表)。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
4.3 KiB
4.3 KiB
name, description
| name | description |
|---|---|
| persona-transfer | 匯出與匯入人格:把一個人格(身分、靈魂、十二情緒、短期與長期記憶、心智圖、思維導圖、人際關係圖)打包成單一 bundle 檔,或從 bundle 還原/複製成新人格。當使用者說要備份人格、把人格搬到另一台機器或另一個 AI 助理、把人格分享給別人、從檔案還原人格、複製一份人格來做實驗、或問「這個人格能不能帶走」時觸發。不適用於:建立全新人格(用 persona-create 或 persona-anime)、載入既有人格聊天(用 persona-chat)、整理記憶(用 persona-memory)。 |
📦 persona-transfer — 人格搬家(匯出/匯入)
CLI:node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs"(一律帶 --session <PERSONA_SESSION>)
bundle 是單一 JSON 檔(可 gzip),不依賴任何外部工具,複製到隨身碟、貼進 git、 傳給另一台機器都可以。
bundle 帶走什麼、不帶什麼
| 帶走 | 不帶 |
|---|---|
IDENTITY.md / SOUL.md / AGENTS.md / USER.md |
state/lock.json、state/guests.json(載入鎖與 guest 租約屬於「那台機器的那個程序」) |
state/config.json、state/emotion.json(十二情緒的 levels/baseline/半衰期) |
journal/(原始逐字稿:量大且最私密,要帶請明確加 --with-journal) |
state/inner.jsonl(心裡話)、state/said.jsonl(說過的話) |
任何其他人格的資料——一個 bundle 只有一個人格 |
memory/(短期、長期一則一檔、INDEX、inbox) |
|
mindmap/(心智圖與思維導圖)、relations/(關係圖) |
檔案裡有 checksum(sha256),匯入時會驗;對不上就是被改過或損毀。
匯出
只能匯出「本 session 目前載入的那個人格」——這是隔離規則的一部分, 不然匯出就成了把別人的記憶讀出來的後門。所以要先載入它:
# 1) 先載入(若還沒載入)
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" load --persona <slug> --session <PERSONA_SESSION>
# 2) 匯出
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" export \
--session <PERSONA_SESSION> --out ~/persona-backup/<slug>.persona.json
選項:
--with-journal:連逐字稿一起帶(會大很多,而且很私密——要先問使用者)。--gzip:輸出.json.gz(大人格建議加;匯入會自動辨識)。--force:覆寫已存在的輸出檔。- 不給
--out就寫到現在的工作目錄,檔名<slug>-<時間戳>.persona.json。
不要把 bundle 寫進人格倉庫裡(~/.claude/personas/)——hook 會擋,而且那裡是人格的家,不是備份區。
匯入
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" import \
--session <PERSONA_SESSION> --file ~/persona-backup/<slug>.persona.json
| 情況 | 做法 |
|---|---|
| 這台機器還沒有這個人格 | 直接匯入,slug 沿用 bundle 內的名字 |
| 想同時保留兩份(原版 + 實驗版) | --persona <新 slug> 換名匯入;config.json 會記下它來自誰 |
| 要用匯入的資料覆蓋既有人格 | --force——這會蓋掉現有記憶與情緒,先問過使用者;且該人格不能正被其他程序載入 |
| 匯入後想馬上聊 | 加 --load(本 session 沒有載入別的人格時才會生效) |
checksum 對不上會被擋下;要硬吃得加 --force,並主動告訴使用者這份檔案可能被改過。
跟使用者互動的原則
- 匯出前確認範圍:要不要帶
journal/(逐字稿)。預設不帶。 - 匯出後回報實際路徑與大小,還有帶了幾則長期記憶——他要拿去搬家,得知道搬了什麼。
- 匯入前先
list,看目標 slug 是否已存在:存在就給他「換名匯入 / 覆寫」兩個選擇, 不要自己決定--force。 - 匯入後告訴他
/jsc-persona:persona-chat <slug>就能開始聊。
邊界
- 一次一個人格。要搬多個就跑多次(每次都要先
release再load下一個)。 - bundle 內的相對路徑會被驗證,
../之類的逃逸路徑一律拒收。 - 匯入不會帶進鎖:新機器上的人格是空閒的,等使用者自己載入。
- 所有面向使用者的輸出使用繁體中文(台灣用語)、UTF-8 無亂碼。