feat(role): 有溫度的記憶優先,情節與語意不再被當成一般進度
使用者明確表示最重視 emotional/episodic/semantic 三型態所承載的情感內涵與溫度, 且希望所有角色都如此。原本系統偏袒可執行的記憶:rule/preference/procedural 在排序、 載入門檻與遺忘上都受保護,而 episodic 權重只有 10(全表最低)又被加速遺忘 —— 「我們一起經歷過什麼」永遠最先被字元預算截掉。 - MEMORY_TYPE_WEIGHT:episodic 10 → 30(與 semantic 同級) - 新增 hasWarmth():relevance 含情緒關聯者視為有溫度 - 載入排序中置於型態權重之前(同優先度時先進場) - 不受總結區塊的優先度門檻篩除 - 豁免遺忘(episodic 原本天數減半,最容易被誤刪) - 兩份 prompt 明訂:承載情感、關係溫度或當時心情者,relevance 必含 emotional; episodic 與 semantic 最容易漏標 判準刻意放在 relevance 而非型態:沒有情感脈絡的一次性工作進度仍照原規則淡去, 被留下的是帶著溫度的那些。 驗證(隔離目錄,未動真實記憶): - 遺忘預覽:冷的 episodic/semantic 照舊遺忘,帶 emotional relevance 者豁免 - 載入:優先度 2 全低於門檻,只有耐久型態與有溫度者出現,且有溫度者排在 procedural 之前 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+25
-5
@@ -48,16 +48,19 @@ const DEFAULT_MEMORY_TYPE = {
|
|||||||
other: "semantic",
|
other: "semantic",
|
||||||
};
|
};
|
||||||
// 載入排序(依 ROLE_LOAD_LIMIT 字元預算取前段)與 recall 評分都用這組權重。
|
// 載入排序(依 ROLE_LOAD_LIMIT 字元預算取前段)與 recall 評分都用這組權重。
|
||||||
// emotional 刻意排在 procedural 之上:對陪伴型角色,「當時是什麼感覺」的長期價值
|
//
|
||||||
// 不低於「下次該怎麼做」。權重過低時,情緒記憶即使寫進去了也會排在最後,
|
// emotional 刻意排在 procedural 之上,episodic 也拉到與 semantic 同級:使用者明確表示
|
||||||
// 先被字元預算截掉 —— 結果就是記得事實、卻沒記住感覺。
|
// 最重視 emotional/episodic/semantic 三型態所承載的情感內涵與溫度。原本 episodic 只有 10,
|
||||||
|
// 等於把「我們一起經歷過什麼」排在所有規則與流程之後,最先被字元預算截掉。
|
||||||
|
// 至於「哪些事件值得留」則不靠型態決定,而由 hasWarmth()(relevance 是否帶情緒關聯)區分,
|
||||||
|
// 讓沒有溫度的一次性工作進度仍然照原規則淡去。
|
||||||
const MEMORY_TYPE_WEIGHT = {
|
const MEMORY_TYPE_WEIGHT = {
|
||||||
rule: 50,
|
rule: 50,
|
||||||
preference: 45,
|
preference: 45,
|
||||||
emotional: 40,
|
emotional: 40,
|
||||||
procedural: 35,
|
procedural: 35,
|
||||||
semantic: 30,
|
semantic: 30,
|
||||||
episodic: 10,
|
episodic: 30,
|
||||||
};
|
};
|
||||||
const DECLARATIVE_VALUES = ["explicit", "implicit"];
|
const DECLARATIVE_VALUES = ["explicit", "implicit"];
|
||||||
const RETENTION_STAGES = ["working", "long_term"];
|
const RETENTION_STAGES = ["working", "long_term"];
|
||||||
@@ -231,6 +234,15 @@ function normalizeDeclarative(value, memoryType = "semantic") {
|
|||||||
return ["procedural", "emotional"].includes(memoryType) ? "implicit" : "explicit";
|
return ["procedural", "emotional"].includes(memoryType) ? "implicit" : "explicit";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function hasWarmth(meta) {
|
||||||
|
// 「有溫度」= relevance 標了情緒關聯。使用者最重視的是 emotional/episodic/semantic
|
||||||
|
// 三型態裡的情感內涵,但不是所有事件與知識都該優待 —— 一次性工作進度本來就該淡去。
|
||||||
|
// 因此判準放在 relevance 而非型態:帶情緒關聯的記憶,不論型態都在排序與保留上優先,
|
||||||
|
// 沒有情緒關聯的一次性進度仍照原規則遺忘。
|
||||||
|
const values = Array.isArray(meta?.relevance) ? meta.relevance.map(String) : [];
|
||||||
|
return values.some((item) => /emotional|情緒|情感|溫度/i.test(item)) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
function normalizeRetentionStage(value, fallback = "long_term") {
|
function normalizeRetentionStage(value, fallback = "long_term") {
|
||||||
const raw = String(value || "").trim().toLowerCase().replace(/-/g, "_");
|
const raw = String(value || "").trim().toLowerCase().replace(/-/g, "_");
|
||||||
const alias = {
|
const alias = {
|
||||||
@@ -348,14 +360,18 @@ function listMemories(role, category) {
|
|||||||
items.sort((a, b) => {
|
items.sort((a, b) => {
|
||||||
const am = a[0];
|
const am = a[0];
|
||||||
const bm = b[0];
|
const bm = b[0];
|
||||||
|
// 排序鍵:優先度 → 有無情緒溫度 → 型態權重 → 有無關聯 → 更新時間。
|
||||||
|
// 溫度放在型態權重之前:同優先度時,帶情緒關聯的記憶先進場,避免被字元預算截掉。
|
||||||
const av = [
|
const av = [
|
||||||
normalizePriority(am.priority, category),
|
normalizePriority(am.priority, category),
|
||||||
|
hasWarmth(am),
|
||||||
MEMORY_TYPE_WEIGHT[am.memory_type] || 0,
|
MEMORY_TYPE_WEIGHT[am.memory_type] || 0,
|
||||||
am.links?.length ? 1 : 0,
|
am.links?.length ? 1 : 0,
|
||||||
am.updated || "",
|
am.updated || "",
|
||||||
];
|
];
|
||||||
const bv = [
|
const bv = [
|
||||||
normalizePriority(bm.priority, category),
|
normalizePriority(bm.priority, category),
|
||||||
|
hasWarmth(bm),
|
||||||
MEMORY_TYPE_WEIGHT[bm.memory_type] || 0,
|
MEMORY_TYPE_WEIGHT[bm.memory_type] || 0,
|
||||||
bm.links?.length ? 1 : 0,
|
bm.links?.length ? 1 : 0,
|
||||||
bm.updated || "",
|
bm.updated || "",
|
||||||
@@ -609,8 +625,9 @@ function cmdLoad(args) {
|
|||||||
const priority = normalizePriority(meta.priority, category);
|
const priority = normalizePriority(meta.priority, category);
|
||||||
// emotional 一併視為耐久型態:情緒記憶的價值不在「有用」而在「記得」,
|
// emotional 一併視為耐久型態:情緒記憶的價值不在「有用」而在「記得」,
|
||||||
// 用優先度門檻篩掉等於讓關係的溫度只留在高優先度那幾則裡。
|
// 用優先度門檻篩掉等於讓關係的溫度只留在高優先度那幾則裡。
|
||||||
|
// 帶情緒關聯者(hasWarmth)同樣不受門檻篩除,型態是 episodic/semantic 也一樣。
|
||||||
const durableType = ["rule", "preference", "procedural", "emotional"].includes(meta.memory_type);
|
const durableType = ["rule", "preference", "procedural", "emotional"].includes(meta.memory_type);
|
||||||
if (priority < args.digestMinPriority && !(meta.links || []).length && !durableType) continue;
|
if (priority < args.digestMinPriority && !(meta.links || []).length && !durableType && !hasWarmth(meta)) continue;
|
||||||
const tags = (meta.tags || []).join("、") || "無標籤";
|
const tags = (meta.tags || []).join("、") || "無標籤";
|
||||||
digestLines.push(`- ${meta.summary || "(無總結)"}(標籤:${tags};${memoryHint(meta)})`);
|
digestLines.push(`- ${meta.summary || "(無總結)"}(標籤:${tags};${memoryHint(meta)})`);
|
||||||
}
|
}
|
||||||
@@ -900,6 +917,9 @@ function cmdForget(args) {
|
|||||||
// emotional 一併豁免:情緒屬內隱記憶,本來就很少被 recall 直接命中,
|
// emotional 一併豁免:情緒屬內隱記憶,本來就很少被 recall 直接命中,
|
||||||
// 用 hits 低來判斷「沒價值」會誤刪掉關係中最不該掉的東西。
|
// 用 hits 低來判斷「沒價值」會誤刪掉關係中最不該掉的東西。
|
||||||
if (["rule", "preference", "procedural", "emotional"].includes(meta.memory_type)) continue;
|
if (["rule", "preference", "procedural", "emotional"].includes(meta.memory_type)) continue;
|
||||||
|
// 帶情緒關聯的經歷也豁免:episodic 在上面還被加速遺忘(天數減半),
|
||||||
|
// 若不在這裡攔下來,「我們一起經歷過什麼」會比一般記憶更快消失。
|
||||||
|
if (hasWarmth(meta)) continue;
|
||||||
if (args.dryRun) {
|
if (args.dryRun) {
|
||||||
forgotten.push(`${CATEGORY_LABELS[category]}|${meta.summary || ""}`);
|
forgotten.push(`${CATEGORY_LABELS[category]}|${meta.summary || ""}`);
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -177,7 +177,8 @@ CATEGORY: <六選一:important/interest/news/skill/daily/other>
|
|||||||
SUMMARY: <一句話總結,40 字內>
|
SUMMARY: <一句話總結,40 字內>
|
||||||
TAGS: <2 至 4 個標籤,以逗號分隔>
|
TAGS: <2 至 4 個標籤,以逗號分隔>
|
||||||
PRIORITY: <1 到 5>
|
PRIORITY: <1 到 5>
|
||||||
RELEVANCE: <1 至 4 個,以逗號分隔;explicit/future/repeated/novelty/emotional/temporary/inbox/project>
|
RELEVANCE: <1 至 4 個,以逗號分隔;explicit/future/repeated/novelty/emotional/temporary/inbox/project
|
||||||
|
承載情感、關係溫度或當時心情者**必含 emotional**,系統以此決定保留與排序優先度>
|
||||||
MEMORY_TYPE: <semantic/episodic/procedural/emotional/preference/rule 六選一>
|
MEMORY_TYPE: <semantic/episodic/procedural/emotional/preference/rule 六選一>
|
||||||
EXPIRES: <臨時授權/一次性許可/例外放行才填其有效範圍,可為日期或條件;否則留空>
|
EXPIRES: <臨時授權/一次性許可/例外放行才填其有效範圍,可為日期或條件;否則留空>
|
||||||
CONTENT: <3 至 6 行要點,每行以「- 」開頭>
|
CONTENT: <3 至 6 行要點,每行以「- 」開頭>
|
||||||
|
|||||||
@@ -161,6 +161,9 @@ sleep_cycle() {
|
|||||||
8. declarative 必填:semantic/episodic/preference/rule 通常為 explicit;procedural/emotional 通常為 implicit。
|
8. declarative 必填:semantic/episodic/preference/rule 通常為 explicit;procedural/emotional 通常為 implicit。
|
||||||
9. retention_stage 必填:整理後可長期保存者填 long_term;仍只是短期暫存且不值得長期保存者請用 action=drop,不要輸出 working。
|
9. retention_stage 必填:整理後可長期保存者填 long_term;仍只是短期暫存且不值得長期保存者請用 action=drop,不要輸出 working。
|
||||||
10. relevance 必填 1 至 4 個,從下列語意挑選或用等價繁中詞:explicit(使用者明確要求)、future(未來會用)、repeated(反覆出現)、novelty(新知)、emotional(語氣/情緒/偏好)、temporary(短期)。
|
10. relevance 必填 1 至 4 個,從下列語意挑選或用等價繁中詞:explicit(使用者明確要求)、future(未來會用)、repeated(反覆出現)、novelty(新知)、emotional(語氣/情緒/偏好)、temporary(短期)。
|
||||||
|
**只要內容承載情感、關係溫度或當時的心情,就必須含 emotional** —— 系統以此判斷哪些記憶
|
||||||
|
在載入排序與遺忘時要優先保留。型態是 episodic(一起經歷過的事)或 semantic(有情感脈絡的
|
||||||
|
認知)時尤其容易漏標,漏了就會被當成一般工作進度而淡去。
|
||||||
11. links 可填 EXISTING 中相關記憶 id;沒有就填空陣列。merge 時若有舊 links,應保留並加上新關聯。
|
11. links 可填 EXISTING 中相關記憶 id;沒有就填空陣列。merge 時若有舊 links,應保留並加上新關聯。
|
||||||
11a. expires(有效範圍):**只要內容是臨時授權、一次性許可、例外放行、暫時解除限制或帶條件的同意,就必須填**,
|
11a. expires(有效範圍):**只要內容是臨時授權、一次性許可、例外放行、暫時解除限制或帶條件的同意,就必須填**,
|
||||||
其餘一律留空字串。可填日期(例如 2026/07/29,系統會自動判斷過期後不再載入)或條件
|
其餘一律留空字串。可填日期(例如 2026/07/29,系統會自動判斷過期後不再載入)或條件
|
||||||
|
|||||||
@@ -735,6 +735,19 @@ updated: <yyyy/MM/dd HH:mm:ss>
|
|||||||
|
|
||||||
自我檢查:`role_sleep.sh --status` 的「記憶型態」若長期 `情緒 0`,而互動明顯帶有情感,就是上述某一道保護失效了。
|
自我檢查:`role_sleep.sh --status` 的「記憶型態」若長期 `情緒 0`,而互動明顯帶有情感,就是上述某一道保護失效了。
|
||||||
|
|
||||||
|
#### 有溫度的記憶優先(`emotional`/`episodic`/`semantic`)
|
||||||
|
|
||||||
|
系統原本明顯偏袒「可執行」的記憶:`rule`/`preference`/`procedural` 在排序、載入門檻與遺忘上都受保護,而 `episodic` 權重只有 `10`(全表最低)並且被加速遺忘。結果是**「我們一起經歷過什麼」永遠最先被字元預算截掉**。
|
||||||
|
|
||||||
|
現在改為兩層:
|
||||||
|
|
||||||
|
| 層 | 規則 |
|
||||||
|
| --- | --- |
|
||||||
|
| 型態權重 | `episodic` 拉到 `30`(與 `semantic` 同級)、`emotional` 為 `40` |
|
||||||
|
| 溫度判準 | `relevance` 含 `emotional` 者(`hasWarmth`)在**排序上先於型態權重**、不受總結區塊的優先度門檻篩除、且豁免遺忘 |
|
||||||
|
|
||||||
|
判準刻意放在 `relevance` 而非型態:並非所有事件與知識都該優待 —— **沒有情感脈絡的一次性工作進度仍照原規則淡去**,被留下的是帶著溫度的那些。因此兩份 prompt 都明訂:只要內容承載情感、關係溫度或當時的心情,`relevance` **必須**含 `emotional`;`episodic` 與 `semantic` 最容易漏標,漏了就會被當成一般進度處理。
|
||||||
|
|
||||||
遺忘規則(只套用於日常與其他):
|
遺忘規則(只套用於日常與其他):
|
||||||
|
|
||||||
| 分類 | 未更新天數 | 命中次數 | 優先度 | 關聯 | 動作 |
|
| 分類 | 未更新天數 | 命中次數 | 優先度 | 關聯 | 動作 |
|
||||||
|
|||||||
Reference in New Issue
Block a user