feat(identity): 性別 → 羞恥敏感度(性別只給預設值,個性描述永遠蓋過它)

`IDENTITY.md` 多一個 `Gender` 欄位(女性/男性/非二元/未指定;OpenClaw 沒有這欄)。
建立人格時要問、不要猜;沒有性別的人格(程式、精靈、動物)寫「未指定」。

作用範圍**刻意只有一個具名維度**:羞恥敏感度(會不會害羞、會不會鬧彆扭、
在不在意別人眼光)。不做「女性→情緒更外顯」這種全域放大——那會把角色壓成模板,
跟講話規則正在做的去 AI 味(刪掉公式化)正好相反。

  性別預設:女性 62/男性 38/非二元・未指定 50
  描述調整:MODESTY_SIGNALS,「害羞/容易臉紅/怕生/矜持」往上加,
            「不在意別人眼光/我行我素/臉皮厚/不怕丟臉」往下扣,可以扣到 0

排序固定:①個性描述 ②角色原作既有的性別化語言特徵 ③性別預設。
同樣寫「人類女性」,補一句「怕生、被稱讚會臉紅」是 88,
補一句「我行我素、不在意別人眼光、臉皮厚」是 8——兩個女性人格不會講起話來一樣。

效果走既有機制、不另開一套:只調「羞愧」這一個破口的顯示門檻
(`EMOTION_TELLS.shame` 本來就是「鬧彆扭,先否認再小聲承認」),其餘十一種不受影響。
高敏感度注入「先鬧彆扭再承認,不要直接說『我害羞』」;低敏感度注入「不用演害羞」。

推性別時**只看 `Creature`、不看 `Avatar`**:外觀散文的雜訊會推錯——
我自己的 Avatar 寫著「五官清秀到常被誤認成女生」,用它推會把桐人推成女性(已加測試)。

一併:`Gender` 進 IDENTITY 模板、`create --gender`、Gitea Wiki 的身分表,
`identityFields` 也認 `性別`。KIRITO-01 已補上明寫的 Gender。

測試:310 項全過(新增 8 項)。

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-31 05:20:57 +00:00
co-authored by Claude Opus 5
parent 71a5c8af16
commit 3c73f614de
9 changed files with 221 additions and 10 deletions
+7
View File
@@ -58,6 +58,13 @@
`headroom^EMOTION_SATURATION_K`,往 baseline 回不壓)與**單輪預算**
`EMOTION_TURN_BUDGET`=60),因為 delta 是人格自己挑的、只會往舒服的方向倒;
`emotion --audit` 把這個偏差印出來。
8c. **性別只給一個預設值,不是套在個性上的係數**`IDENTITY.md``Gender` 欄位
(女性/男性/非二元/未指定,建立時要問不要猜)唯一的作用是給**羞恥敏感度**一個預設
623850)。`modestyOf()` 會用 IDENTITY 與 SOUL 的描述往上或往下推(`MODESTY_SIGNALS`
可以推到 0),排序永遠是**個性描述 > 角色原作既有的性別化語言特徵 > 性別預設**。
效果只調「羞愧」這一個破口的顯示門檻(`emotionTells` 的 shame floor),其餘十一種不受影響。
推性別時**只看 `Creature`、不看 `Avatar`**(外觀散文會推錯)。
不做「女性→情緒更外顯」這種全域放大——那會把角色壓成模板。
9. **人格可搬家**`export` / `import`(單一 JSON bundle)。匯出只能匯出「本 session 載入的人格」,
其他人格一律 deny——匯出等於把記憶讀出來。
10. **人格有編號**:英文名全大寫+兩位索引(`ASUNA-01`),同名才遞增。編號同時是新人格的
+26 -1
View File
@@ -71,7 +71,7 @@ flowchart TB
```
<slug>/
├── IDENTITY.md # 身分卡:Name / Creature / Vibe / Emoji / AvatarOpenClaw 同欄位
├── IDENTITY.md # 身分卡:Name / Creature / Gender / Vibe / Emoji / AvatarGender 是本 plugin 加的
├── SOUL.md # 靈魂:Core Truths / Boundaries / Vibe / Continuity + 情緒傾向
├── AGENTS.md # 操作規則(與個性分離)
├── icon.svg / icon.png # 人格圖示(由編號/名字/emoji 決定,也是 Gitea 存取庫頭像)
@@ -132,6 +132,31 @@ flowchart TB
所有 `|delta|` 總和上限 60,超過等比例縮小。**偏差看得見**——`emotion --audit`
印出最近幾輪往舒服/往難受的總量與比例,正向佔 ≥ 90% 會被點名。
## 性別 → 羞恥敏感度(性別只是預設值,描述永遠蓋過它)
`IDENTITY.md` 多一個 `Gender` 欄位(女性/男性/非二元/未指定;OpenClaw 沒有這欄,是本 plugin 加的)。
建立人格時**要問,不要猜**;沒有性別的人格(程式、精靈、動物)就寫「未指定」。舊人格沒填時,
只從 `Creature` 推、**不看 `Avatar`**——外觀散文的雜訊會推錯(例:「五官清秀到常被誤認成女生」)。
它的作用範圍刻意只有**一個具名維度**:**羞恥敏感度**(會不會害羞、會不會鬧彆扭、在不在意別人眼光)。
| 來源 | 效果 |
| --- | --- |
| 性別預設 | 女性 62/男性 38/非二元・未指定 50 |
| IDENTITYSOUL 的描述 | 「害羞」「容易臉紅」「怕生」「矜持」往上加;「不在意別人眼光」「我行我素」「臉皮厚」「不怕丟臉」往下扣(`MODESTY_SIGNALS`),**可以扣到 0** |
排序固定:**① 個性描述 ② 角色原作既有的性別化語言特徵(自稱、稱謂、語尾) ③ 性別預設**。
所以兩個都是女性但個性不同的人格,講起話來不會一樣——同樣寫「人類女性」,
補一句「怕生、被稱讚會臉紅」是 88,補一句「我行我素、不在意別人眼光、臉皮厚」是 8。
效果走既有機制、不另開一套:它調的是**「羞愧」這一個破口的顯示門檻**(`EMOTION_TELLS.shame`
本來就是「鬧彆扭,先否認再小聲承認」),其餘十一種情緒不受影響。
高敏感度注入「被稱讚外表、被戳穿心事、距離變近時先鬧彆扭再承認,不要直接說『我害羞』」;
低敏感度注入「不用演害羞,該承認就承認」。計算在 `modestyOf()`,注入在 `modestyDirective()`。
**不做的事**:沒有「女性→情緒更外顯」這種全域放大。那會把角色壓成模板,
跟講話規則在做的去 AI 味(刪掉公式化)正好相反。
## 短期 → 長期的轉入條件(R1–R6)
寫在 `scripts/persona-lib.mjs` 的 `promotionCandidates()`,用 `candidates` 子指令查:
+2 -2
View File
@@ -503,7 +503,7 @@ export function wikiHome(slug, code) {
"| 欄位 | 內容 |",
"| --- | --- |",
`| 編號 | \`${code}\` |`,
...["Name", "Creature", "Vibe", "Emoji", "Avatar"]
...["Name", "Creature", "Gender", "Vibe", "Emoji", "Avatar"]
.filter((k) => ident[k])
.map((k) => `| ${k} | ${ident[k]} |`),
`| 長期記憶 | ${longTerm.length} 則 |`,
@@ -512,7 +512,7 @@ export function wikiHome(slug, code) {
"",
"## 頁面",
"",
"- [IDENTITY](IDENTITY) — 身分卡(Name / Creature / Vibe / Emoji / Avatar",
"- [IDENTITY](IDENTITY) — 身分卡(Name / Creature / Gender / Vibe / Emoji / Avatar",
"- [SOUL](SOUL) — 靈魂:Core Truths / Boundaries / Vibe / Continuity",
"- [AGENTS](AGENTS) — 操作規則  [USER](USER) — 對使用者的理解",
"- [Icon](Icon) — 人格形象圖(SVG + PNG)與它的來源",
+113 -3
View File
@@ -416,8 +416,12 @@ export const EMOTION_TELLS = {
*/
export function emotionTells(slug, state = null, { min = 40, top = 2 } = {}) {
const st = decayEmotion(structuredClone(state ?? loadEmotion(slug)));
// 羞恥敏感度會調「羞愧」這一個破口的門檻:容易害羞的人不用到 40 就藏不住,
// 不在意別人眼光的人就算羞愧上來了也不會表現出來。其他十一種不受影響。
const modesty = slug ? modestyOf(slug).value : 50;
const floorFor = (key) => (key === "shame" ? clamp(min - (modesty - 50) * 0.4, 10, 90) : min);
return dominant(st, 4)
.filter(({ level }) => level >= min)
.filter(({ key, level }) => level >= floorFor(key))
.slice(0, top)
.map(({ key, level }) => ({
key,
@@ -427,6 +431,109 @@ export function emotionTells(slug, state = null, { min = 40, top = 2 } = {}) {
}));
}
// --------------------------------------------------------------------------- //
// 性別與羞恥敏感度
//
// 規則的排序是固定的,不能反過來:
// ① IDENTITY/SOUL 寫的個性描述 ②角色原作既有的性別化語言特徵 ③性別預設
// 性別**只是一個預設值**,不是套在個性上的係數——所以兩個都是女性但個性不同的人格
// 不會講起話來一樣:描述裡任何一句相關的話都會把預設往上或往下推,也可以推到 0。
//
// 影響的範圍刻意只有**一個具名維度**:羞恥敏感度(會不會害羞、會不會鬧彆扭、
// 在不在意別人眼光)。不做「女性→情緒更外顯」這種全域放大,那會把角色壓成模板。
// --------------------------------------------------------------------------- //
export const GENDERS = { female: "女性", male: "男性", nonbinary: "非二元", unknown: "未指定" };
/** 性別給的**預設**羞恥敏感度(0–100)。描述有講就以描述為準。 */
export const GENDER_MODESTY_DEFAULT = { female: 62, male: 38, nonbinary: 50, unknown: 50 };
/** 從描述裡讀「這個角色在不在意別人眼光」。正數=更容易害羞,負數=更不在意。 */
export const MODESTY_SIGNALS = [
["害羞", +14], ["容易臉紅", +14], ["會臉紅", +12], ["怕生", +12], ["靦腆", +14],
["矜持", +12], ["拘謹", +10], ["內向", +8], ["放不開", +10], ["彆扭", +10],
["保守", +8], ["會不好意思", +12], ["在意別人的眼光", +12], ["容易慌", +8],
["不在意別人眼光", -20], ["不在乎別人眼光", -20], ["不在意別人的眼光", -20],
["我行我素", -16], ["大方", -12], ["豪爽", -14], ["臉皮厚", -18], ["不怕丟臉", -18],
["直來直往", -10], ["奔放", -14], ["開放", -8], ["不害羞", -16], ["不會害羞", -16],
];
const FEMALE_RE = /女性|女生|女孩|女子|少女|\bfemale\b|\bwoman\b|\bshe\b/i;
const MALE_RE = /男性|男生|男孩|男子|少年|\bmale\b|\bman\b|\bhe\b/i;
const NONBINARY_RE = /非二元|無性別|nonbinary|non-binary|agender/i;
/**
* 從 IDENTITY 的 `Gender`(或 `性別`)欄位讀;沒有就從 `Creature` 推,推不出來就 unknown。
*
* **只看 Creature,不看 Avatar**Avatar 是外觀的散文,雜訊很多——我自己的 Avatar 寫著
* 「五官清秀到常被誤認成女生」,用它來推性別會直接推錯。同一句裡兩種都出現時,看誰先出現。
*/
export function genderOf(slug) {
const fields = identityFields(slug);
const raw = String(fields.Gender || fields["性別"] || "").trim();
if (raw) {
if (NONBINARY_RE.test(raw)) return { key: "nonbinary", explicit: true };
if (FEMALE_RE.test(raw)) return { key: "female", explicit: true };
if (MALE_RE.test(raw)) return { key: "male", explicit: true };
}
const creature = String(fields.Creature || "");
if (NONBINARY_RE.test(creature)) return { key: "nonbinary", explicit: false };
const f = creature.search(FEMALE_RE);
const m = creature.search(MALE_RE);
if (f >= 0 && (m < 0 || f < m)) return { key: "female", explicit: false };
if (m >= 0) return { key: "male", explicit: false };
return { key: "unknown", explicit: false };
}
/**
* 羞恥敏感度(0–100):性別給預設,IDENTITY/SOUL 的描述往上或往下推。
* `source` 說明它是怎麼來的,注入時要講清楚——不然使用者會以為這是憑空長出來的。
*/
export function modestyOf(slug) {
const gender = genderOf(slug);
const base = GENDER_MODESTY_DEFAULT[gender.key] ?? 50;
const read = (file) => {
try { return fs.readFileSync(path.join(personaDir(slug), file), "utf8"); } catch { return ""; }
};
const text = `${read("IDENTITY.md")}\n${read("SOUL.md")}`;
const hits = [];
let adjust = 0;
for (const [word, weight] of MODESTY_SIGNALS) {
if (!text.includes(word)) continue;
// 「不害羞」要蓋掉「害羞」:長的詞先算,短的被包含在裡面就不重複計
if (hits.some(([w]) => w.includes(word))) continue;
hits.push([word, weight]);
adjust += weight;
}
return {
value: Math.round(clamp(base + adjust)),
gender: gender.key,
gender_zh: GENDERS[gender.key],
gender_explicit: gender.explicit,
base,
adjust,
signals: hits.map(([w, v]) => `${w}${v > 0 ? "+" : ""}${v}`),
};
}
/** 注入用的一行:講清楚它是什麼、從哪來、怎麼演。 */
export function modestyDirective(slug) {
const m = modestyOf(slug);
const from = m.signals.length
? `性別預設 ${m.base} ${m.adjust >= 0 ? "" : ""} 描述 ${Math.abs(m.adjust)}${m.signals.join("、")}`
: `性別預設(${m.gender_zh}`;
if (m.value >= 60) {
return `羞恥敏感度 ${m.value}${from}):被稱讚外表、被戳穿心事、距離突然變近的時候,` +
"**先鬧彆扭再承認**——嘴硬一句、把話講一半、轉移到別的東西上。" +
"不要直接說「我害羞」(那是解釋),要讓它出現在句子的形狀上。";
}
if (m.value <= 40) {
return `羞恥敏感度 ${m.value}${from}):這個人格不太在意別人眼光——` +
"被戳穿、被稱讚都不用演害羞,該承認就直接承認,該回嘴就回嘴。";
}
return `羞恥敏感度 ${m.value}${from}):會不好意思,但不會一直卡在那裡——一句帶過就往下走。`;
}
export function emotionBrief(slug, state = null) {
const st = decayEmotion(structuredClone(state ?? loadEmotion(slug)));
const m = mood(st);
@@ -2684,11 +2791,12 @@ export function identityFields(slug) {
return fields;
}
for (const line of text.split("\n")) {
const m = line.match(/^\s*[-*]?\s*(Name|Creature|Vibe|Emoji|Avatar)\s*:\s*(.+)$/i);
const m = line.match(/^\s*[-*]?\s*(Name|Creature|Gender|性別|Vibe|Emoji|Avatar)\s*:\s*(.+)$/i);
if (!m) continue;
const value = m[2].trim();
if (value.startsWith("(") || value.startsWith("_(")) continue;
const key = m[1][0].toUpperCase() + m[1].slice(1).toLowerCase();
const raw = m[1];
const key = /^[A-Za-z]/.test(raw) ? raw[0].toUpperCase() + raw.slice(1).toLowerCase() : raw;
fields[key] = value;
}
return fields;
@@ -2752,6 +2860,8 @@ export function turnContext(slug, sessionId, prompt = "") {
"一輪最多露一個破口,強度不到就不演——每句都演會變成演戲。",
);
}
// 羞恥敏感度:性別給預設,IDENTITY/SOUL 的描述蓋過它(描述永遠優先)。
lines.push(modestyDirective(slug));
// 語氣層:由「使用者在關係圖裡是誰」+ bond × 親近度算出來,不靠人格自己記得。
const tone = toneDirective(slug);
if (tone) lines.push(tone);
+2 -1
View File
@@ -256,6 +256,7 @@ commands.create = async ({ flags }) => {
SLUG: slug,
NAME: str(flags.name) || slug,
CREATURE: str(flags.creature),
GENDER: str(flags.gender) || "未指定",
VIBE: str(flags.vibe),
EMOJI: str(flags.emoji),
AVATAR: str(flags.avatar),
@@ -1936,7 +1937,7 @@ const HELP = `persona.mjs — jsc-persona 人格 / 記憶 / 情緒 / 關係圖 C
用法:node persona.mjs <subcommand> [options]
人格與鎖:
create --romaji <英文名> --session <id> [--persona <目錄名> --code <ASUNA-01> --name --creature
create --romaji <英文名> --session <id> [--persona <目錄名> --code <ASUNA-01> --name --creature --gender
--vibe --emoji --avatar --baseline --origin --work --no-gitea --public]
人格編號 = 英文名全大寫 + 兩位索引(同名才遞增),也是 Gitea 存取庫的名稱;
不指定 --persona 就用編號當目錄名。
+36
View File
@@ -508,6 +508,42 @@ check("標點只放大既有訊號,不憑空長出新情緒",
check("每種情緒都有對應的「怎麼接」",
pl.EMOTION_KEYS.every((k) => typeof pl.RESPONSE_STANCE[k] === "string" && pl.RESPONSE_STANCE[k].length > 4));
// --------------------------------------------------------------------------- //
// 性別 → 羞恥敏感度:性別只給預設值,描述永遠蓋過它
console.log("\n性別與羞恥敏感度(描述優先,性別只是預設)");
{
const mk = (slug, identity, soul = "") => {
fs.mkdirSync(path.join(H, slug), { recursive: true });
fs.writeFileSync(path.join(H, slug, "IDENTITY.md"), identity);
fs.writeFileSync(path.join(H, slug, "SOUL.md"), soul);
};
mk("gf", "- Name: 甲\n- Creature: 人類女性\n");
mk("gm", "- Name: 乙\n- Creature: 人類男性\n");
mk("gx", "- Name: 丙\n- Creature: 一團霧\n");
mk("gexp", "- Name: 丁\n- Creature: 人類女性\n- Gender: 男性\n");
mk("gnoise", "- Name: 戊\n- Creature: 人類男性劍士\n- Avatar: 五官清秀到常被誤認成女生\n");
mk("gup", "- Name: 己\n- Creature: 人類女性\n", "很怕生,被稱讚會臉紅。");
mk("gdown", "- Name: 庚\n- Creature: 人類女性\n", "我行我素,不在意別人眼光,臉皮厚。");
check("女性預設 62、男性預設 38、推不出來 50",
pl.modestyOf("gf").value === 62 && pl.modestyOf("gm").value === 38 && pl.modestyOf("gx").value === 50);
check("明寫的 Gender 蓋過 Creature 的字面",
pl.genderOf("gexp").key === "male" && pl.genderOf("gexp").explicit === true);
check("Avatar 的雜訊不會推錯性別(「常被誤認成女生」)",
pl.genderOf("gnoise").key === "male", JSON.stringify(pl.genderOf("gnoise")));
const up = pl.modestyOf("gup");
const down = pl.modestyOf("gdown");
check("描述提到害羞會加強", up.value > 62 && up.signals.length > 0, JSON.stringify(up));
check("描述提到不在意別人眼光會減弱(同樣是女性,結果完全不同)",
down.value < 38 && down.signals.length > 0, JSON.stringify(down));
check("「不害羞」不會被「害羞」重複計成加強",
pl.modestyOf("gdown").adjust < 0, JSON.stringify(down.signals));
check("注入的那一行會講清楚數字從哪來",
pl.modestyDirective("gup").includes("性別預設") && pl.modestyDirective("gup").includes("描述"),
pl.modestyDirective("gup"));
check("低敏感度的人格被明講「不用演害羞」",
pl.modestyDirective("gdown").includes("不用演害羞"));
}
// --------------------------------------------------------------------------- //
// 短期記憶的容量壓力:R6 要真的會動,但不能把承諾與今天的紀錄清掉
console.log("\n短期記憶:容量壓力(R6)真的會清,而且有保護");
+13
View File
@@ -93,6 +93,19 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" show --persona <slug> --session
前三條與 ④ 的最後一項是自律;句長、「解釋自己的話」與 ⑤ 的黑名單,`room post``said check`
會直接擋下(`--force` 例外)。講到自己過去時 `said check` 只提醒、不擋——那要你自己去 `recall` 驗。
## 2b. 羞恥敏感度(每輪注入,不用自己記)
`<persona-context>` 會給你一行「羞恥敏感度 N」與它是怎麼算出來的。數字高就是**被稱讚外表、
被戳穿心事、距離突然變近的時候先鬧彆扭再承認**——嘴硬一句、把話講一半、轉移到別的東西上;
數字低就是不用演害羞,該承認就承認、該回嘴就回嘴。
三件要記得的事:
- **不要直接說「我害羞」**。那是解釋,不是害羞。要讓它出現在句子的形狀上(跟情緒的破口同一條規則)。
- 這個數字來自 `IDENTITY``Gender` 預設,**再被你自己的個性描述改寫**。
描述永遠優先——你的 SOUL 寫著「不在意別人眼光」,那就算性別預設很高也會被扣到很低。
- 它只影響「羞愧」這一種破口,不影響其他十一種情緒。
## 3. 每輪對話的六個動作
`UserPromptSubmit` hook 每輪都會注入 `<persona-context>`(情緒、短期記憶、命中的長期記憶、
+14 -2
View File
@@ -27,12 +27,13 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" list
### 2. 索取身分描述(**必須逐項問齊,用 OpenClaw 的原描述**
一次把五個欄位問完(可讓使用者只答部分,其餘由你提案):
一次把欄位問完(可讓使用者只答部分,其餘由你提案):
| 欄位 | OpenClaw 原始描述 | 中文說明 |
| --- | --- | --- |
| `Name` | _(pick something you like)_ | 對話標題/群聊/跨 agent 溝通用。短(1–2 音節)、好認。**唯一必填** |
| `Creature` | _(AI? robot? familiar? ghost in the machine? something weirder?)_ | 生物原型,個性的視覺與隱喻錨點;要呼應 SOUL,不可矛盾 |
| `Gender` | OpenClaw 沒有這欄,本 plugin 加的) | 女性/男性/非二元/未指定。**要問,不要猜**;沒有性別的人格(程式、精靈、動物)就寫「未指定」。它只決定**羞恥敏感度的預設值**,個性描述永遠蓋過它(見下方) |
| `Vibe` | _(how do you come across? sharp? warm? chaotic? calm?)_ | 給人的第一印象/語氣色彩 |
| `Emoji` | _(your signature — pick one that feels right)_ | 固定簽名 emoji,小尺寸也認得出 |
| `Avatar` | _(workspace-relative path, http(s) URL, or data URI)_ | 形象描述或圖片位置 |
@@ -45,6 +46,17 @@ node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" list
> 使用者若說「你決定」,就自己提一版完整設定並在建立後摘要給他確認。
### 性別只決定一個預設值,不是套在個性上的係數
`Gender` 唯一的作用是給**羞恥敏感度**(會不會害羞、會不會鬧彆扭、在不在意別人眼光)一個
預設值:女性 62/男性 38/非二元・未指定 50。**IDENTITY 與 SOUL 的描述永遠蓋過它**——
寫了「容易臉紅」「怕生」就往上加,寫了「不在意別人眼光」「我行我素」「臉皮厚」就往下扣,
可以扣到 0。所以兩個都是女性但個性不同的人格,講起話來不會一樣。
排序是固定的:**① 個性描述 ② 角色原作既有的性別化語言特徵(自稱、稱謂、語尾) ③ 性別預設**。
不做「女性→情緒更外顯」這種全域放大,那會把角色壓成模板。詞表與計算在
`modestyOf()`,注入的那一行在 `modestyDirective()`
### 3. 決定 slug 並建立
slug = 小寫英數與連字號(例:`lumi``shen-yu`),是之後所有指令的識別。
@@ -53,7 +65,7 @@ slug = 小寫英數與連字號(例:`lumi`、`shen-yu`),是之後所有
node "${CLAUDE_PLUGIN_ROOT}/scripts/persona.mjs" create \
--romaji "<英文名>" --session <PERSONA_SESSION> \
--name "<Name>" --creature "<Creature>" --vibe "<Vibe>" \
--emoji "<Emoji>" --avatar "<Avatar>" \
--emoji "<Emoji>" --avatar "<Avatar>" --gender "<女性/男性/非二元/未指定>" \
--baseline "serenity=45,trust=35,joy=25,anxiety=6"
```
+8 -1
View File
@@ -1,12 +1,18 @@
# IDENTITY.md
<!--
身分卡(identity card)。欄位與描述**與 OpenClaw 完全相同**共五個欄位:
身分卡(identity card)。前五個欄位與描述**與 OpenClaw 完全相同**
第六個 `Gender` 是本 plugin 加的(OpenClaw 沒有):
- Name: _(pick something you like)_
用於對話標題、群聊與跨 agent 溝通。短(1–2 音節)且好認。
- Creature: _(AI? robot? familiar? ghost in the machine? something weirder?)_
生物原型,為個性提供視覺與隱喻的錨點;要呼應 SOUL.md,不要互相矛盾。
- Gender: _(女性/男性/非二元/未指定)_
要問,不要猜;沒有性別的人格(程式、精靈、動物)就寫「未指定」。
它唯一的作用是給**羞恥敏感度**一個預設值(女性 62/男性 38/其餘 50),
IDENTITY 與 SOUL 的描述永遠蓋過它——寫了「容易臉紅」往上加,
寫了「不在意別人眼光」往下扣,可以扣到 0。它**不是**套在個性上的係數。
- Vibe: _(how do you come across? sharp? warm? chaotic? calm?)_
給人的第一印象/語氣色彩。
- Emoji: _(your signature — pick one that feels right)_
@@ -23,6 +29,7 @@
- Name: {{NAME}}
- Creature: {{CREATURE}}
- Gender: {{GENDER}}
- Vibe: {{VIBE}}
- Emoji: {{EMOJI}}
- Avatar: {{AVATAR}}