2026-07-29 14:37:20 +00:00

jsc-persona — AI 人格化記憶聊天

一套讓 AI 成為某個人、而不只是回答問題的 plugin。 以 OpenClaw 相同的人格描述IDENTITY.md 五欄位 + SOUL.md 四段落)建立人格, 再用 hook 強制的人格鎖與跨人格隔離,把 十二情緒語意分析短期/長期記憶心智圖/思維導圖人際關係圖 綁在一起。

可同時安裝於 Claude Code、Codex、Antigravity、OpenCode skills 是共通標準,鎖與隔離的強制執行需要 hook,目前只有 Claude Code 支援(見「跨助理支援度」)。


七條硬規則

規則 怎麼做到
1a. 用與 OpenClaw 相同的描述建立人格 persona-create 逐項索取 Name / Creature / Vibe / Emoji / Avatar(連括號提示文字都照 OpenClaw 原文),SOUL.md 沿用 Core Truths / Boundaries / Vibe / Continuity 段落結構
1b. 動漫作品+角色名快速建人格 persona-anime 先上網蒐集該角色的公開設定(至少 3 個獨立來源),映射成上述五欄位與 SOUL,再把設定固化成 canon 基礎記憶(每則帶來源 URL)+原作人際關係圖+情緒基線
2. 同一個人格只能被一個程序載入(Sub Agent 不限) state/lock.jsonsession_id 為主鍵、15 分鐘心跳租約;同一 session 的 sub agent 沿用同一把鎖,跨 session 搶佔會被拒;租約過期才可接手(並強制回報)
3. 禁止跨人格讀取資料 PreToolUse hook 對 Read/Write/Edit/Glob/Grep/Bash 做路徑判定(含 ../、symlink、$PERSONA_HOME 繞路),非當前人格一律 deny;CLI 也驗 --session 防止冒用身分
4. 邀請人格用 Sub Agent 一起聊,且只顯示對話 persona-invite 建聊天室 + guest 唯讀租約 + persona-guest sub agent;同時開啟劇場模式hook 每輪強制「只輸出 名字:內容」、停掉所有系統提醒,CLI 有 --quietroom script(乾淨對話稿)
5. 腳本用 Node.js scripts/*.mjshooks/*.mjs,只用 Node 內建模組(fs/path/os/crypto),無 npm 依賴
6. 由使用者呼叫才載入並鎖定 人格不會自動附身:SessionStart hook 只列出可用人格,等使用者下 /jsc-persona:persona-chat <slug>;載入即取得獨占鎖並綁定該 session
7. 短期記憶轉入長期記憶有成文條件 R1R6 六條規則寫在程式裡(promotionCandidates),candidates 子指令會列出達標的候選與依據,hook 在達標時提醒固化

架構

flowchart TB
  subgraph P["主程序(一個 session = 一個人格)"]
    U["使用者訊息"] --> H1["UserPromptSubmit hook<br/>注入 情緒+短期記憶+命中的長期記憶+關係"]
    H1 --> A["語意分析:意圖/主題/實體/情感/需求"]
    A --> E["情緒評估 → 十二情緒 deltas"]
    E --> R["以人格語氣回覆"]
    R --> W["記憶回寫(短期)"]
    W --> H2["Stop hook:情緒衰減+續租+固化提醒"]
  end
  subgraph G["Sub Agent(受邀人格,唯讀)"]
    GA["persona-guest"]
  end
  subgraph S["人格倉庫 ~/.claude/personas"]
    PA["alpha/IDENTITY SOUL 記憶 情緒 心智圖 關係圖"]
    PB["beta/|…"]
    RM[".rooms/room/transcript.jsonl"]
  end
  P -->|"只能碰自己"| PA
  GA -->|"只能碰自己"| PB
  P <-->|"唯一合法交流管道"| RM
  GA <--> RM

人格倉庫(預設 ~/.claude/personas/<slug>/,可用 PERSONA_HOME 覆寫)

<slug>/
├── IDENTITY.md              # 身分卡:Name / Creature / Vibe / Emoji / AvatarOpenClaw 同欄位)
├── SOUL.md                  # 靈魂:Core Truths / Boundaries / Vibe / Continuity + 情緒傾向
├── AGENTS.md                # 操作規則(與個性分離)
├── USER.md                  # 對使用者的畫像(事實/推測分開)
├── state/
│   ├── lock.json            # 載入鎖(session_id + 心跳租約)
│   ├── guests.json          # guest 唯讀租約
│   ├── emotion.json         # 十二情緒 levels / baseline / 半衰期
│   └── config.json
├── memory/
│   ├── short-term.jsonl     # 短期記憶(語意分析後;上限 240 筆 / 14 天)
│   ├── long-term/*.md       # 長期記憶(一則一檔 + frontmatter
│   ├── INDEX.md             # 長期記憶索引(自動產生)
│   └── inbox/room-*.jsonl   # 當 guest 時留下的見聞,待本體消化
├── mindmap/
│   ├── semantic.mmd         # 心智圖:概念的長期關聯(Mermaid mindmap
│   └── threads/*.mmd        # 思維導圖:單一話題的推理鏈(Mermaid graph,短期)
├── relations/
│   ├── graph.json           # 人際關係圖(親近度/信任度/連線)
│   └── graph.mmd            # Mermaid 呈現(自動產生)
└── journal/YYYY-MM.jsonl    # 原始逐字 + 情緒史(hook 自動寫)

十二情緒

六正向 六負向
喜悅 joy、信任 trust、期待 anticipation、感激 gratitude、平靜 serenity、驚喜 delight 憤怒 anger、悲傷 sadness、恐懼 fear、厭惡 disgust、羞愧 shame、焦慮 anxiety
  • 每種 0100,各有不同半衰期(驚喜 60 分最快、信任 720 分最慢),每輪自動朝 baseline 指數衰減。
  • 由十二情緒推導 valence(正向/中性/負向)與 arousal(高張/平穩/低張),決定語氣與句長。
  • 主導情緒取「超出基線最多」的前三名,所以個性底色不會永遠霸榜。
  • 觸發規則與事件→delta 對照表:skills/persona-chat/reference/emotions.md

短期 → 長期的轉入條件(R1R6

寫在 scripts/persona-lib.mjspromotionCandidates(),用 candidates 子指令查:

規則 條件 建議固化為
R1 單筆顯著度 ≥ 60 event / fact
R2 同一 topic ≥ 3 筆,或 ≥ 2 筆且平均顯著度 ≥ 45 preference
R3 單筆情緒變動總量 ≥ 25 event(帶情緒錨點)
R4 intent=commit 或命中承諾/界線關鍵詞 promise / boundarysalience ≥ 80,不可遺忘)
R5 同一人物(entity)≥ 2 筆 relationship(並更新關係圖)
R6 短期記憶 ≥ 40 筆(容量壓力) 依顯著度清出空間

沒命中任何規則的就讓它被裁掉——遺忘是功能。達標時 Stopremember 都會提醒去跑 /jsc-persona:persona-memory

劇場模式(多人格對話只顯示對話)

invite 成功即開啟(leave 沒有客人時自動關閉,也可 room theater --on/--off 手動切):

  • UserPromptSubmit hook 每輪注入強制規則:輸出只能名字:內容, 不得出現指令、指令輸出、狀態、分析、旁白、摘要。
  • Stop hook 在劇場模式完全不發系統訊息(提醒會破壞畫面)。
  • CLI 提供 --quiet(成功時零輸出)與 room script(只有 emoji 名字(情緒):內容 的乾淨對話稿)。
🪼 Lumi(喜悅42/期待31):所以你真的一個人把那台舊鐘修好了?
🌙 Shen(平靜50/信任38):修好了。它現在慢三分鐘,我決定不修那三分鐘。

HooksClaude Code

Hook 做什麼
SessionStart 清死鎖、接續人格、把 PERSONA_SESSION=<session_id> 與規則注入上下文
UserPromptSubmit 注入 <persona-context>:身分、情緒、短期記憶、關鍵詞命中的長期記憶、相關人際關係;劇場模式時追加「只輸出人格對話」的強制規則;並記原始逐字
PreToolUse 人格隔離與鎖驗證的唯一強制點deny 帶原因)
Stop 情緒隨時間衰減、續租、記錄回覆、達固化條件時提醒(劇場模式時完全靜音)
SubagentStop 解除 guest sub agent 的 pin
SessionEnd 釋放鎖與 guest 租約,人格才能被下一個程序載入

session_id 只有 hook 拿得到 → 注入上下文 → skills 呼叫 CLI 時必須帶 --session hook 會驗證是否相符。這是「一人格一程序」與「跨人格隔離」不能被繞過的關鍵


Skills 目錄

persona-create

建立人格:以 OpenClaw 相同的五個身分欄位與 SOUL 段落訪談使用者,初始化情緒基線、記憶、心智圖與關係圖,並立即取得載入鎖。

  • Claude Code / Antigravity/jsc-persona:persona-create Codex$persona-create

persona-anime

用「動漫作品+角色名」建立人格:上網蒐集角色公開設定 → 映射成 OpenClaw 五欄位與 SOUL → 固化成 canon 基礎記憶(附來源)+原作關係圖+情緒基線。

  • Claude Code / Antigravity/jsc-persona:persona-anime 《作品》 角色名 Codex$persona-anime

persona-chat

載入人格並對話:取得獨占鎖 → 每輪做語意分析 → 更新十二情緒 → 回想記憶與關係 → 以人格語氣回覆 → 寫回記憶。

  • Claude Code / Antigravity/jsc-persona:persona-chat <slug> Codex$persona-chat

persona-invite

邀請另一個人格透過 persona-guest sub agent 加入聊天室,進入劇場模式(畫面只留 名字:內容 的人格對話);結束後讓它離場並把見聞留在它自己的 inbox。

  • Claude Code / Antigravity/jsc-persona:persona-invite <slug> Codex$persona-invite

persona-memory

記憶固化:依 R1–R6 條件把短期記憶轉入長期(一則一檔)、淘汰雜訊、更新心智圖與思維導圖、消化 guest inbox、重建索引。

  • Claude Code / Antigravity/jsc-persona:persona-memory Codex$persona-memory

persona-relation

人際關係圖維護:節點/連線、親近度與信任度調整、輸出 Mermaid 關係圖。

  • Claude Code / Antigravity/jsc-persona:persona-relation Codex$persona-relation

persona-status

載入狀態與鎖管理:誰被哪個程序鎖住、guest 租約、釋放、接手死鎖、清理殘留。

  • Claude Code / Antigravity/jsc-persona:persona-status Codex$persona-status

Agents

  • persona-guestagents/persona-guest.md)— 受邀人格的 sub agent,唯讀、被綁死在自己的人格目錄。

CLI 與自我測試

所有狀態變更都經過 scripts/persona.mjsNode.js ≥ 18,只用內建模組,無 npm 依賴):

node scripts/persona.mjs --help
node scripts/persona.mjs list
node scripts/persona.mjs candidates --session <PERSONA_SESSION>   # 看哪些短期記憶該固化
node scripts/persona.mjs room script --session <id> --room <room> # 乾淨對話稿(劇場模式用)
node scripts/selftest.mjs     # 68 項驗證:鎖、隔離、情緒、固化條件、劇場模式、hooks

檔案結構:scripts/persona-lib.mjs(核心:鎖/隔離/情緒/記憶)、scripts/persona.mjsCLI)、 hooks/*.mjs(六個 hook)、scripts/selftest.mjs(自我測試)。


跨助理支援度

助理 skills hooks(鎖/隔離強制) 受邀人格 sub agent
Claude Code /jsc-persona:<name> 完整 jsc-persona:persona-guest
Codex $<name> ⚠ 需自行以子任務模擬
Antigravity /jsc-persona:<name>
OpenCode 依描述自動觸發

沒有 hook 的助理仍會遵守 CLI 層的檢查(--session 綁定、require_ownerrequire_member、 guest 唯讀),但那是自律而非強制:真正的 deny 只有 Claude Code 的 PreToolUse 做得到。


安裝 / 更新 / 移除

指令中的 repo 網址換成你的:https://gitea.jsc.idv.tw/plugins/persona.git Claude / Codex 從 git URL 安裝(會 clone 遠端),請先把本 repo push 到 gitea。

Claude Code

claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/persona.git
claude plugin install jsc-persona@jsc-plugins

# 更新
claude plugin marketplace update jsc-plugins
claude plugin update jsc-persona@jsc-plugins

# 移除
claude plugin uninstall jsc-persona@jsc-plugins
  • 工作階段內 slash 版(等價):把 claude plugin 換成 /plugin
  • 本機開發(免 push):claude plugin marketplace add /home/coder/plugins/persona 後再 install。
  • 安裝後重啟工作階段讓 hooks 生效;用 /hooks 確認六個 hook 都在。

Codex

codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/persona.git
codex plugin add jsc-persona@jsc-plugins
codex plugin marketplace upgrade jsc-plugins   # 更新
codex plugin remove jsc-persona@jsc-plugins    # 移除

Antigravityagy

agy plugin install <url> 目前只支援 github.comgitea 請 clone 後用本地路徑。

git clone https://gitea.jsc.idv.tw/plugins/persona.git ~/plugins/persona
agy plugin install ~/plugins/persona
# 更新:git -C ~/plugins/persona pull && agy plugin uninstall jsc-persona && agy plugin install ~/plugins/persona

OpenCode

git clone https://gitea.jsc.idv.tw/plugins/persona.git ~/plugins/persona
mkdir -p ~/.config/opencode/skills
cp -r ~/plugins/persona/skills/* ~/.config/opencode/skills/

Windows PowerShellcp -r A BCopy-Item A B -Recurse -Force~$HOME

headless 一次性執行

助理 指令
Claude Code claude -p "/jsc-persona:persona-chat lumi"
Codex codex exec '$persona-chat lumi'
Antigravity agy -p "/jsc-persona:persona-chat lumi"
OpenCode opencode run "用 lumi 這個人格跟我聊聊"

設計取捨(讀之前先知道)

  • 記憶是被策展的,不是全存:逐字稿進 journal/,但只有經過語意分析、有顯著度的內容才進短期記憶, 再由 persona-memory 決定什麼值得成為長期記憶。遺忘是功能
  • 事實與推測分離:推論走思維導圖(mindmap/threads/),驗證後才升格長期記憶。
  • 鎖的擁有者是 session 不是 process:CLI 跑完就結束,所以租約判定只看心跳。
  • guest 唯讀:受邀人格不能在別人的 session 裡改自己的長期記憶(避免兩個程序同時寫), 只能把見聞放進 memory/inbox/,等它自己被載入時消化。
  • hook 是強制、SKILL 是引導:SKILL.md 寫的規則模型可能忘記,hook 不會。

新增/修改 skill

  1. 複製一個現有 skill 目錄,改 SKILL.mdnamedescription(描述要寫清楚何時用、何時不用)。
  2. 需要新的狀態操作 → 加到 scripts/persona.mjs 的子指令,並在 scripts/selftest.mjs 補測試。
  3. 動到隔離規則 → 一定要在 selftest.mjs 的第 ③(隔離)/⑧(guest 與劇場模式)區加對應案例,跑到全綠。
  4. 把 skill 補進上方「Skills 目錄」區塊。
  5. bump .claude-plugin/plugin.json.codex-plugin/plugin.jsonplugin.json 三處 versioncommit 後 push。
S
Description
Persona 指令 for AI 助理
https://gitea.jsc.idv.tw/plugins/persona
Readme
7.2 MiB
Languages
JavaScript 98.3%
Python 1.7%