feat(標點預算): 情緒決定標點分布,上限夾死免得變成強度計
只有文字的話標點就是語調:同一句「我知道了」,`我知道了。` 與 `我、我知道了⋯`
是兩種情緒,差別全在標點不在用詞。
PUNCTUATION_BUDGET 只寫拍板指名的四種(焦慮/憤怒/害羞/喜悅)。
其餘八種不配標點——硬給每種情緒配一套會讓標點變成裝飾,沒把握的就不編。
punctuationBudget() 每輪只回一種,門檻跟破口同一條線(40)。兩種情緒各配一套
會互相打架:憤怒幾乎不用問號、焦慮要多斷句,混起來不是複雜的情緒,是標點亂撒。
上限:MAX_EXCLAIM = 1、MAX_ELLIPSIS = 3,另擋 […⋯]{3,} 的連發
(中文刪節號本來就常寫兩個,所以三個起才算)。不夾死的話它會變成 emoji 的
替代品——情緒不夠就多打幾個驚嘆號。界線也寫進注入文字:標點管分布、強度歸 emoji。
selftest 711 → 721。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1203,6 +1203,34 @@ console.log("⑥-d 鬧彆扭的階梯與三段式");
|
||||
`${pl.modestyOf("ownsulk").value}|${ownShape.slice(0, 220)}`);
|
||||
check("沒寫覆寫的人格照舊用預設模板", pl.personaSulk("shyladder").length === 0);
|
||||
}
|
||||
|
||||
// 標點預算:情緒 → 標點與句長的分布。上限夾死,否則變成 emoji 的替代品
|
||||
console.log("⑥-e 標點預算");
|
||||
check("拍板的四種情緒都有標點指示,而且四種不一樣", (() => {
|
||||
const keys = ["anxiety", "anger", "shame", "joy"];
|
||||
const hints = keys.map((k) => pl.PUNCTUATION_BUDGET[k]);
|
||||
return hints.every(Boolean) && new Set(hints).size === 4;
|
||||
})(), JSON.stringify(pl.PUNCTUATION_BUDGET));
|
||||
check("沒把握的情緒就不配標點(不硬給十二種)",
|
||||
Object.keys(pl.PUNCTUATION_BUDGET).length === 4, JSON.stringify(Object.keys(pl.PUNCTUATION_BUDGET)));
|
||||
check("一個驚嘆號可以", pl.speechBlockers("太好了!").length === 0);
|
||||
check("兩個驚嘆號會被擋(強度歸 emoji,不歸標點)",
|
||||
pl.speechBlockers("太好了!真的!").some((i) => i.kind === "exclaim"));
|
||||
check("刪節號連發會被擋", pl.speechBlockers("我知道⋯⋯⋯").some((i) => i.kind === "ellipsis-run"));
|
||||
check("兩個刪節號是正常的中文寫法,不擋",
|
||||
pl.speechBlockers("我知道⋯⋯").every((i) => !String(i.kind).startsWith("ellipsis")));
|
||||
check("刪節號整則超過上限會被擋",
|
||||
pl.speechBlockers("我⋯不知道⋯你說⋯這樣⋯").some((i) => i.kind === "ellipsis"));
|
||||
check("標點預算取主導情緒,而且只回一種(兩種會互相打架)", (() => {
|
||||
const p = pl.punctuationBudget("alpha");
|
||||
return p !== null && typeof p.hint === "string" && typeof p.key === "string" && p.level >= 40;
|
||||
})(), JSON.stringify(pl.punctuationBudget("alpha")));
|
||||
check("強度不到就不調標點(跟破口同一條線)",
|
||||
pl.punctuationBudget("alpha", null, { min: 99 }) === null);
|
||||
check("標點指示有注入,而且講明上限與「強度歸 emoji」", (() => {
|
||||
const ctxP = pl.turnContext("alpha", S_SPEAK, "那件事後來怎麼了");
|
||||
return ctxP.includes("此刻的標點") && ctxP.includes("刪節號不連發") && ctxP.includes("強度歸 emoji");
|
||||
})(), pl.turnContext("alpha", S_SPEAK, "那件事後來怎麼了").slice(0, 500));
|
||||
check("說話規則有注入「話短、日常字、看得見的東西、不要回頭解釋」", (() => {
|
||||
const ctxSay = pl.turnContext("alpha", S_SPEAK, "隨便講");
|
||||
return ["話短一點", "平常會說的字", "看得見的東西", "不要回頭解釋"].every((w) => ctxSay.includes(w));
|
||||
|
||||
Reference in New Issue
Block a user