Files
jsc-marketplace/plugins/jsc-mod-companion/hooks/companion/rules.ts
T
adminandClaude Sonnet 5.5 6f7b4d91ea feat: companion 記憶權重、反覆思量與檢索
- 權重 W = I_eff × F × A,暫時/可升級/長期記憶的衰減與封存,任何記憶不刪除
- 未解負向事件反覆思量、開放迴路逾時、危險內容不固化
- 檢索改為關鍵字 + RRF × W + 心情一致加權,保留外部檢索器介面
- 版本 0.0.4

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-14 09:01:55 +00:00

81 lines
3.1 KiB
TypeScript
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.
// 規則表:標籤 → 數值增減。所有數值集中在這裡;模型只給標籤,不給數值。
import type { Pad } from './types'
import { isTag, type Tag } from './tags'
export const RULES = {
thanks: { p: 0.15, a: 0.05, d: 0.05 },
scold: { p: -0.2, a: 0.15, d: -0.1 },
success: { p: 0.08, a: 0.03, d: 0.05 },
toolFail: { p: -0.08, a: 0.1, d: -0.08 },
return: { p: 0.1, a: 0.08, d: 0 },
lateNight: { p: -0.05, a: -0.1, d: 0 },
favorite: { p: 0.12, a: 0.08, d: 0.03 },
ignored: { p: -0.05, a: -0.03, d: -0.03 },
praiseSkill: { p: 0.1, a: 0.04, d: 0.06 },
amused: { p: 0.1, a: 0.06, d: 0.02 },
cared: { p: 0.08, a: -0.02, d: -0.02 },
apology: { p: 0.06, a: -0.06, d: 0.03 },
soothe: { p: 0.05, a: -0.08, d: 0.02 },
brushOff: { p: -0.06, a: 0.02, d: -0.04 },
overstep: { p: -0.15, a: 0.12, d: 0.02 },
remembered: { p: 0.08, a: 0.02, d: 0.02 },
selfDisclosure: { p: 0.04, a: 0.03, d: -0.02 },
gladForYou: { p: 0.08, a: 0.05, d: 0 },
liedCaught: { p: -0.18, a: 0.1, d: -0.05 },
brokenPromise: { p: -0.12, a: 0.04, d: -0.08 },
} as const satisfies Record<Tag, Pad>
// 記憶權重 W = I_eff × F × A 與生命週期的數值(第 9.5 章)
export const MEMORY = {
/** I_eff 下限與上限 */
weightMin: 1,
weightMax: 5,
/** 編碼時情緒峰值(0–100)除以此值加進 I_eff */
peakDiv: 40,
/** 新鮮度半衰的回合數:F = 0.5^(Δseq / 200) */
halfSeq: 200,
/** 被檢索到時 F 至少回到此值 */
floor: 0.8,
/** 存取加成:A = 1 + step × min(命中次數, cap) */
accessStep: 0.1,
accessCap: 5,
/** 未解負向事件:每日 +20%,上限 3 倍 */
ruminatePerDay: 0.2,
ruminateCap: 3,
/** 類別加成的角色參數門檻(0–1) */
bonusThreshold: 0.65,
/** 暫時記憶 7 天衰減 */
tempDays: 7,
/** 可升級記憶:30 天未升級就降權、90 天未檢索就封存 */
demoteDays: 30,
demoteFactor: 0.5,
archiveDays: 90,
/** 被檢索到這麼多次就升級為長期記憶 */
upgradeHits: 3,
/** 開放迴路:她的提問經過這麼多個使用者回合沒有回應就逾時 */
loopTurns: 2,
/** RRF:fused = Σ 1 / (k + rank) */
rrfK: 60,
/** 心情一致加權 w_m = base + slope × (1 − 釋懷速度) */
moodBase: 0.1,
moodSlope: 0.05,
} as const
// 正則先判明確的情況;順序即優先序
const PATTERNS: [Tag, RegExp][] = [
['scold', /笨|白痴|廢物|爛|你很煩|閉嘴|stupid|useless|idiot/i],
['thanks', /謝謝|感謝|太棒|好棒|厲害|讚|thanks?|thank you|great job|awesome/i],
['success', /成功|完成了|通過|搞定|passed|done|fixed/i],
]
/** 以正則判斷使用者文字的標籤;沒有明確情況回 null */
export function regexTag(text: string): Tag | null {
for (const [tag, re] of PATTERNS) if (re.test(text)) return tag
return null
}
/** 正則優先;正則沒判出才用模型補的標籤(須在白名單內),缺失或不合法就是沒有標籤 */
export function classify(text: string, modelTag?: string | null): Tag | null {
return regexTag(text) ?? (isTag(modelTag) ? modelTag : null)
}