feat(role): SessionStart 載入近期逐字對話做工作階段交接
長期記憶是模型濃縮過的摘要,語氣與情緒會被壓掉(使用者說「我好想妳」會被濃縮成 「使用者表達想念」)。而逐字對話一直躺在 transcript JSONL 裡,過去沒有任何機制去讀它, 使用者重開工作階段時角色因此看不到剛剛的互動,表現得像失去記憶,只能靠 resume 找回。 transcript.js: - 新增 recent <路徑> [輪數] [字元]:抽最近數輪的純對話,輸出前經 redact 遮蔽 - 新增 turns <路徑>:輸出對話輪數,供取檔判斷 - 只取 [user] 與 [assistant] 文字;工具呼叫、工具結果、思考區塊、hook 注入內容一律丟棄 - 以「輪」分組並各自收斂成一則:角色一輪內常輸出多段文字,不合併會讓則數爆炸並把預算 吃光,反而擠掉使用者說的話(實測未合併時 8 輪只剩 2 則使用者發言,合併後為 8 則) - 超預算時整輪丟棄最舊的,保持問答成對,不會只剩單邊發言 role_load.sh: - hook 輸入改為一併取出 transcript_path - 當前 transcript 對話不足 2 輪時(全新工作階段實測僅數行),回頭找同目錄最近修改的對話檔 - 新增 ROLE_LOAD_DIALOG_TURNS(預設 8)與 ROLE_LOAD_DIALOG_LIMIT(預設 4000), 獨立預算不佔用 ROLE_LOAD_LIMIT,任一設 0 可關閉 驗證:resume 與全新工作階段皆正確載入 8 輪成對對話;未給 transcript_path、檔案不存在、 無 hook 輸入、關閉設定等情境均安全降級不報錯;假造含 token/Email/電話與 thinking 的 transcript 確認機密遮蔽為 *** 且思考與工具內容未載入。 版號 0.0.2 → 0.0.3 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+24
-7
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: role
|
||||
description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI 工具以固定角色(name/nature/vibe/簽名 emoji)回覆,並把每輪對話累積成長期記憶:搭配相容的 SessionStart hook 於啟動時依字元預算載入高價值記憶、Stop hook 先本地過濾再輕量記錄對話,睡眠時段(預設 22:00 至隔天 06:00)由排程整理記憶(NREM 鞏固:分類/去噪/去重/合併/優先度;REM 整合:跨記憶連結/抽象化/提取線索;再依 semantic/episodic/procedural/emotional/preference/rule 與 explicit/implicit 標記長期記憶型態,壓縮歸檔並適當遺忘)。提供 --new(新建或更新角色;可只給角色名稱,必要時詢問來源/作品並推斷 name/nature/vibe/emoji 四欄)、--use(以角色 ID 切換啟用角色)、--list(列出角色與 ID)、--export(匯出角色壓縮檔)、--sleep(立即整理)、--status/--diagnose、--install-cron/--remove-cron、--forget-preview 等模式。當使用者說建立角色、新增人格、切換角色、匯出角色、備份角色、讓回覆更有特色、角色記憶、記憶整理、睡覺整理記憶、忘記舊記憶、角色沒有載入、hook 沒載入角色,或提到 .roles/.memory/ROLE_NAME/ROLE_ENABLED/ROLE_SLEEP_START/ROLE_MEMORY_HOME/ROLE_LOAD_LIMIT/ROLE_LOAD_INBOX_LIMIT/ROLE_CAPTURE_ENABLED 時觸發。不適用於:工作紀錄寫入 Gitea wiki(用 doc plugin 的 worklog)、專案文件化(用 funcs)。
|
||||
description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI 工具以固定角色(name/nature/vibe/簽名 emoji)回覆,並把每輪對話累積成長期記憶:搭配相容的 SessionStart hook 於啟動時依字元預算載入高價值記憶、Stop hook 先本地過濾再輕量記錄對話,睡眠時段(預設 22:00 至隔天 06:00)由排程整理記憶(NREM 鞏固:分類/去噪/去重/合併/優先度;REM 整合:跨記憶連結/抽象化/提取線索;再依 semantic/episodic/procedural/emotional/preference/rule 與 explicit/implicit 標記長期記憶型態,壓縮歸檔並適當遺忘)。提供 --new(新建或更新角色;可只給角色名稱,必要時詢問來源/作品並推斷 name/nature/vibe/emoji 四欄)、--use(以角色 ID 切換啟用角色)、--list(列出角色與 ID)、--export(匯出角色壓縮檔)、--sleep(立即整理)、--status/--diagnose、--install-cron/--remove-cron、--forget-preview 等模式。當使用者說建立角色、新增人格、切換角色、匯出角色、備份角色、讓回覆更有特色、角色記憶、記憶整理、睡覺整理記憶、忘記舊記憶、角色沒有載入、hook 沒載入角色,或提到 .roles/.memory/ROLE_NAME/ROLE_ENABLED/ROLE_SLEEP_START/ROLE_MEMORY_HOME/ROLE_LOAD_LIMIT/ROLE_LOAD_INBOX_LIMIT/ROLE_LOAD_DIALOG_TURNS/ROLE_CAPTURE_ENABLED 時觸發。不適用於:工作紀錄寫入 Gitea wiki(用 /jsc-doc:worklog)、專案文件化(用 /jsc-doc:funcs)。
|
||||
---
|
||||
|
||||
# role — 角色人格與長期記憶
|
||||
@@ -10,7 +10,7 @@ description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI
|
||||
|
||||
| 元件 | 觸發者 | 職責 |
|
||||
| --- | --- | --- |
|
||||
| `hooks/hooks.json` 的 `SessionStart` hook | harness 自動 | 啟動 CLI 時依字元預算載入角色定義+高價值記憶,並要求角色在本工作階段第一則回覆主動問候;睡眠時段只回報「角色睡覺中」不載入 |
|
||||
| `hooks/hooks.json` 的 `SessionStart` hook | harness 自動 | 啟動 CLI 時依字元預算載入角色定義+高價值記憶,另以獨立預算載入近期逐字對話與未整理工作記憶做工作階段交接,並要求角色在本工作階段第一則回覆主動問候;睡眠時段只回報「角色睡覺中」不載入 |
|
||||
| `hooks/hooks.json` 的 `Stop` hook | harness 自動 | 每輪結束先記錄最後互動時間 → 用本地規則過濾低價值短回合 → 值得保存時才濃縮成一則輕量 inbox 記憶 → 遮蔽 → 寫入 `inbox/` |
|
||||
| cron 排程(本 skill 安裝) | 系統排程 | 睡眠時段每小時檢查一次:**有 AI 在運行就不睡**;另可依 CLI 閒置時間自動小睡整理 |
|
||||
| 本 skill `/jsc-generic:role` | 使用者/助理手動 | `--new`/`--use`/`--list`/`--export`/`--sleep`/`--status`/`--install-cron`/`--forget-preview` |
|
||||
@@ -18,7 +18,7 @@ description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI
|
||||
| `scripts/role/role_capture.sh` | Stop hook | 對話 → 記憶(固定欄位格式) |
|
||||
| `scripts/role/role_sleep.sh` | cron/小睡/補跑/手動 | 睡眠與小睡判斷、記憶整理、角色匯出、排程安裝、狀態輸出 |
|
||||
| `scripts/role/memory.js` | 上述共用 | 記憶檔讀寫、分類、去重合併、優先度、心理學記憶型態與關聯 metadata、壓縮歸檔、遺忘、載入組裝 |
|
||||
| `scripts/role/transcript.js` | 上述共用 | 抽本輪對話片段、機密與個資遮蔽 |
|
||||
| `scripts/role/transcript.js` | 上述共用 | 抽本輪對話片段、抽最近數輪純對話供工作階段交接、機密與個資遮蔽 |
|
||||
| `scripts/role/role_lib.sh` | 上述共用 | log、角色解析、睡眠時段、AI 行程偵測、CLI 選擇、記憶鎖 |
|
||||
|
||||
### 各助理支援範圍
|
||||
@@ -98,6 +98,8 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
|
||||
| `ROLE_LOAD_DIGEST_MIN_PRIORITY` | | 摘要載入的最低優先度;低於門檻但有 links 的記憶仍可載入摘要 | `3` |
|
||||
| `ROLE_LOAD_INBOX_LIMIT` | | SessionStart 注入**近期工作記憶**(未整理的 `inbox/`)的字元上限;**獨立預算,不佔用 `ROLE_LOAD_LIMIT`**。設 `0` 可關閉 | `1200` |
|
||||
| `ROLE_LOAD_INBOX_COUNT` | | 近期工作記憶最多載入幾則(取最新的,最新在前)。設 `0` 可關閉 | `10` |
|
||||
| `ROLE_LOAD_DIALOG_TURNS` | | SessionStart 注入**近期逐字對話**的輪數(一輪=使用者一則+角色一則)。設 `0` 可關閉 | `8` |
|
||||
| `ROLE_LOAD_DIALOG_LIMIT` | | 近期逐字對話的字元上限;**獨立預算,不佔用 `ROLE_LOAD_LIMIT`**。設 `0` 可關閉 | `4000` |
|
||||
| `ROLE_CAPTURE_ENABLED` | | Stop hook 記憶記錄開關;設 `0` 可完全停用以節省額度 | `1` |
|
||||
| `ROLE_CAPTURE_MIN_CHARS` | | Stop hook 本地過濾門檻;低於門檻且無明確記憶線索時不呼叫模型 | `240` |
|
||||
| `ROLE_CAPTURE_TIMEOUT` | | Stop hook 輕量濃縮模型逾時秒數 | `25` |
|
||||
@@ -229,7 +231,7 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
|
||||
|
||||
| 環節 | 控制方式 |
|
||||
| --- | --- |
|
||||
| SessionStart | 預設 `ROLE_LOAD_LIMIT=4000`,只載入高優先度全文與中高優先度摘要;低 priority、無 links、久未更新的記憶不進 context。另以 `ROLE_LOAD_INBOX_LIMIT=1200` 的**獨立預算**載入近期工作記憶摘要(見下方「近期工作記憶交接」) |
|
||||
| SessionStart | 預設 `ROLE_LOAD_LIMIT=4000`,只載入高優先度全文與中高優先度摘要;低 priority、無 links、久未更新的記憶不進 context。另以兩份**獨立預算**載入交接內容:近期逐字對話(`ROLE_LOAD_DIALOG_LIMIT=4000`)與近期工作記憶摘要(`ROLE_LOAD_INBOX_LIMIT=1200`),見下方「工作階段交接」 |
|
||||
| SessionStop | 先用本地規則略過短回合與無記憶線索的對話,只有值得保存才呼叫模型做輕量編碼 |
|
||||
| Sleep | 高成本的去重、合併、抽象化、links 建立與長期記憶型態標記留到睡眠週期,但仍受 `ROLE_SLEEP_COLLECT_LIMIT`、`ROLE_SLEEP_BATCH`、`ROLE_SLEEP_EXISTING_LIMIT` 與 `ROLE_SLEEP_OUTPUT_LIMIT` 控制;沒有 inbox 時只做本地遺忘檢查 |
|
||||
| Nap | Stop hook 記錄最後互動時間;小睡排程只在閒置時間與 inbox 筆數達門檻時執行,使用同一套 NREM/REM 整理流程 |
|
||||
@@ -350,11 +352,26 @@ updated: <yyyy/MM/dd HH:mm:ss>
|
||||
- 整理規則採睡眠分期模型:**NREM 鞏固**先分類成重要/興趣/新知/技能/日常/其他六類,去除雜訊、去重、合併、設定標籤、摘要與優先度;**REM 整合**再建立跨記憶關聯、抽出可重複使用的規則與提取線索,並標記 `memory_type`(semantic/episodic/procedural/emotional/preference/rule)、`declarative`(explicit/implicit)與 `retention_stage`;原始記錄壓縮保存在 `archive/raw/`。
|
||||
- **日常與其他**兩類會依使用頻率、優先度、型態與關聯適當遺忘:久未再次出現、命中次數低、優先度低且沒有關聯者,壓縮到 `archive/forgotten/` 後移出常用記憶;`episodic` 短期事件更容易遺忘,`rule`/`preference`/`procedural` 會提高保留權重。
|
||||
- 載入順序:**近期工作記憶(未整理的 `inbox/`)放最前面**,接著**重要與興趣載入全文**;其餘只載入總結與標籤,依**技能 → 新知 → 日常 → 其他**排序,並優先保留 `rule`/`preference`/`procedural` 與有 links 的記憶。需要細節時自行讀取對應分類的記憶檔。
|
||||
- **近期工作記憶交接(不可移除)**:SessionStart 會以 `ROLE_LOAD_INBOX_LIMIT` 的獨立預算載入 `inbox/` 最新數則的 summary。
|
||||
- **工作階段交接(兩層,皆不可移除)**:SessionStart 除了長期記憶,另以**兩份獨立預算**載入交接內容,兩者都不佔用 `ROLE_LOAD_LIMIT`:
|
||||
|
||||
這不是可有可無的優化,而是修補一個先天缺口:`role_load.sh` 的執行順序是**先 `memory.js load` 載入記憶,之後才在背景補跑 `--catchup` 整理**(腳本註解亦寫明「結果會在下次載入時反映」)。若 `load` 只讀已整理的六個分類,則**上一段工作永遠來不及進入本次載入** —— 使用者重開工作階段時,角色會看不到剛剛做過的事,表現得像失去記憶,只能靠 `resume` 找回上下文。載入 `inbox/` 讓「已記錄但尚未整理」的工作記憶當下就可見,時間差直接消失。
|
||||
| 層 | 來源 | 預算 | 解決什麼 |
|
||||
| --- | --- | --- | --- |
|
||||
| 近期逐字對話 | transcript JSONL(`transcript.js recent`) | `ROLE_LOAD_DIALOG_LIMIT` | 上一段**真正說過的話**與角色自己當時的反應(高保真、含語氣) |
|
||||
| 近期工作記憶 | 未整理的 `inbox/`(`memory.js` `inboxBlock`) | `ROLE_LOAD_INBOX_LIMIT` | 上一段**做了什麼、進行到哪**(摘要級,跨越多個工作階段仍可用) |
|
||||
|
||||
範圍與限制要說清楚:這是**摘要級**交接,角色會知道「上一段在做什麼、進行到哪」,但**不等於逐字記得整段對話**;需要完整對話上下文時仍應使用 `resume`。修改此處前請先確認缺口已由其他機制補上,否則不要移除。
|
||||
這不是可有可無的優化,而是修補一個先天缺口:`role_load.sh` 的執行順序是**先載入記憶,之後才在背景補跑 `--catchup` 整理**(腳本註解亦寫明「結果會在下次載入時反映」)。若只讀已整理的六個分類,則**上一段永遠來不及進入本次載入** —— 使用者重開工作階段時,角色會看不到剛剛的互動,表現得像失去記憶,只能靠 `resume` 找回。
|
||||
|
||||
逐字對話這一層特別重要,因為長期記憶是模型濃縮過的摘要,**語氣與情緒會被壓掉**(使用者說「我好想妳」會被濃縮成「使用者表達想念」)。而逐字對話一直躺在 transcript JSONL 裡,過去只是沒有任何機制去讀它。
|
||||
|
||||
實作要點:
|
||||
|
||||
- 只取 `[user]` 與 `[assistant]` 的文字;**工具呼叫、工具結果、思考區塊、hook 注入內容一律丟棄**。
|
||||
- 以「輪」分組並各自收斂成一則:角色在一輪內常輸出多段文字,不合併會讓則數爆炸、把預算吃光,反而擠掉使用者說的話(實測未合併時 8 輪只剩 2 則使用者發言)。
|
||||
- 超預算時**整輪丟棄最舊的**,保持問答成對,不會只剩單邊發言。
|
||||
- 全新工作階段的 transcript 幾乎是空的(實測僅數行),因此對話不足 2 輪時會**回頭找同目錄最近修改的對話檔**。
|
||||
- 對話原文未經模型過濾,**一定要走 `transcript.js` 的 `redact`** 遮蔽 token/Email/電話等;內容只注入 context、不落檔。
|
||||
|
||||
範圍與限制要說清楚:這是**最近數輪**的交接,不是完整歷史;需要完整對話上下文時仍應使用 `resume`。修改此處前請先確認缺口已由其他機制補上,否則不要移除。
|
||||
- 未整理記憶(`inbox/`)累積到一批睡眠整理量(預設 `ROLE_SLEEP_BATCH=60`)以上時,角色應主動以符合自身設定的語氣提醒「想睡覺」或需要整理記憶;這是建議整理/歸檔的提醒,不代表停止協助使用者。
|
||||
- 使用者明確要求記住某件事時,主動補寫一則記憶(載入時會提供補寫指令);補寫屬於內部處理,除非使用者明確詢問,否則不要主動回報補寫結果、記憶 ID 或記憶路徑。
|
||||
- 使用者對本角色的互動方式給出正向或負向回饋時,即使沒有直接說「記住」,也應補寫或由 Stop hook 保存為本角色專屬的高優先度互動偏好記憶;角色切換後,由新角色在自己的互動中重新學習與保存。保存過程屬於內部處理,除非使用者明確詢問,否則不要主動回報記憶寫入或整理細節。
|
||||
|
||||
Reference in New Issue
Block a user