feat(role): 新增角色記憶預算與心理學記憶型態 #9

Merged
admin merged 10 commits from develop into master 2026-07-28 04:53:08 +00:00
2 changed files with 54 additions and 31 deletions
Showing only changes of commit 57a493e612 - Show all commits
+2 -2
View File
@@ -214,9 +214,9 @@ copilot plugin marketplace remove generic
| Skill | 用途 | 使用方法 | | Skill | 用途 | 使用方法 |
| --- | --- | --- | | --- | --- | --- |
| `role` | 讓 CLI 以固定角色(namenaturevibe/簽名 emoji)回覆,並把每輪對話累積成長期記憶:啟動時自動載入角色與記憶,睡眠時段(預設 22:00–06:00)由排程整理、去重、標籤化、壓縮歸檔並適當遺忘;新建角色時可詢問是否網路搜尋背景資料作為初始記憶,角色檔名與記憶目錄使用英文大寫 ID | `/jsc:role --new` 建立或更新角色、`--use <角色 ID>` 切換、`--list` 查角色與 ID、`--sleep` 立即整理、`--status` 診斷、`--install-cron` 安裝排程 | | `role` | 讓 CLI 以固定角色(namenaturevibe/簽名 emoji)回覆,並把每輪對話累積成長期記憶:啟動時依字元預算載入高價值記憶,Stop hook 先本地過濾低價值回合以節省額度,睡眠時段(預設 22:00–06:00)由 NREM 鞏固與 REM 整合兩階段整理、去重、標籤化、建立關聯、壓縮歸檔並依優先度適當遺忘;新建角色時可詢問是否網路搜尋背景資料作為初始記憶,角色檔名與記憶目錄使用英文大寫 ID | `/jsc:role --new` 建立或更新角色、`--use <角色 ID>` 切換、`--list` 查角色與 ID、`--sleep` 立即整理、`--status` 診斷、`--install-cron` 安裝排程 |
`role` 的自動路徑由 hook 與 cron 完成,**建立角色後重開工作階段即生效**;非睡眠時段載入角色後,角色會在本工作階段第一則回覆開頭主動簡短問候一次。角色檔、記憶目錄、`.active``ROLE_NAME` 一律使用角色 ID(例如 `ENGINEER01`),`--list` 可查每個顯示名稱對應的 ID。沒有建立過角色的人完全不受影響(`~/.roles/.active` 不存在時 hook 立即結束)。細節見 `skills/role/SKILL.md` `role` 的自動路徑由 hook 與 cron 完成,**建立角色後重開工作階段即生效**;非睡眠時段載入角色後,角色會在本工作階段第一則回覆開頭主動簡短問候一次,並載入上次睡眠摘要作為提取線索。角色檔、記憶目錄、`.active``ROLE_NAME` 一律使用角色 ID(例如 `ENGINEER01`),`--list` 可查每個顯示名稱對應的 ID。沒有建立過角色的人完全不受影響(`~/.roles/.active` 不存在時 hook 立即結束)。細節見 `skills/role/SKILL.md`
<!-- JSC-SKILLS:END --> <!-- JSC-SKILLS:END -->
+52 -29
View File
@@ -1,6 +1,6 @@
--- ---
name: role name: role
description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI 工具以固定角色(namenature/vibe/簽名 emoji)回覆,並把每輪對話累積成長期記憶:搭配相容的 SessionStart hook 於啟動時載入角色與記憶、Stop hook 記錄對話,睡眠時段(預設 22:00 至隔天 06:00)由排程整理記憶(分類重要/興趣/新知/技能/日常/其他、去重、設標籤與一句話總結、壓縮歸檔,日常與其他依使用頻率遺忘)。提供 --new(新建或更新角色;需產生英文大寫角色 ID,並詢問是否網路搜尋資料作初始記憶)、--use(以角色 ID 切換啟用角色)、--list(列出角色與 ID)、--sleep(立即整理)、--status--diagnose、--install-cron--remove-cron、--forget-preview 等模式。當使用者說建立角色、新增人格、切換角色、讓回覆更有特色、角色記憶、記憶整理、睡覺整理記憶、忘記舊記憶、角色沒有載入、hook 沒載入角色,或提到 .roles.memoryROLE_NAMEROLE_ENABLEDROLE_SLEEP_STARTROLE_MEMORY_HOME 時觸發。不適用於:工作紀錄寫入 Gitea wiki(用 doc plugin 的 worklog)、專案文件化(用 doc-funcs)。 description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI 工具以固定角色(namenature/vibe/簽名 emoji)回覆,並把每輪對話累積成長期記憶:搭配相容的 SessionStart hook 於啟動時依字元預算載入高價值記憶、Stop hook 先本地過濾再輕量記錄對話,睡眠時段(預設 22:00 至隔天 06:00)由排程整理記憶(NREM 鞏固:分類/去噪/去重/合併/優先度;REM 整合:跨記憶連結/抽象化/提取線索;再壓縮歸檔,日常與其他依使用頻率與優先度遺忘)。提供 --new(新建或更新角色;需產生英文大寫角色 ID,並詢問是否網路搜尋資料作初始記憶)、--use(以角色 ID 切換啟用角色)、--list(列出角色與 ID)、--sleep(立即整理)、--status--diagnose、--install-cron--remove-cron、--forget-preview 等模式。當使用者說建立角色、新增人格、切換角色、讓回覆更有特色、角色記憶、記憶整理、睡覺整理記憶、忘記舊記憶、角色沒有載入、hook 沒載入角色,或提到 .roles.memoryROLE_NAMEROLE_ENABLEDROLE_SLEEP_STARTROLE_MEMORY_HOMEROLE_LOAD_LIMITROLE_CAPTURE_ENABLED 時觸發。不適用於:工作紀錄寫入 Gitea wiki(用 doc plugin 的 worklog)、專案文件化(用 doc-funcs)。
--- ---
# role — 角色人格與長期記憶 # role — 角色人格與長期記憶
@@ -10,15 +10,15 @@ description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI
| 元件 | 觸發者 | 職責 | | 元件 | 觸發者 | 職責 |
| --- | --- | --- | | --- | --- | --- |
| `hooks/hooks.json``SessionStart` hook | harness 自動 | 啟動 CLI 時載入角色定義+記憶,並要求角色在本工作階段第一則回覆主動問候;睡眠時段只回報「角色睡覺中」不載入 | | `hooks/hooks.json``SessionStart` hook | harness 自動 | 啟動 CLI 時依字元預算載入角色定義+高價值記憶,並要求角色在本工作階段第一則回覆主動問候;睡眠時段只回報「角色睡覺中」不載入 |
| `hooks/hooks.json``Stop` hook | harness 自動 | 每輪結束抽本輪對話 → 濃縮成一則記憶 → 遮蔽 → 寫入 `inbox/` | | `hooks/hooks.json``Stop` hook | harness 自動 | 每輪結束先用本地規則過濾低價值短回合 → 值得保存時才濃縮成一則輕量 inbox 記憶 → 遮蔽 → 寫入 `inbox/` |
| cron 排程(本 skill 安裝) | 系統排程 | 睡眠時段每小時檢查一次:**有 AI 在運行就不睡**,沒有才進入睡眠整理記憶 | | cron 排程(本 skill 安裝) | 系統排程 | 睡眠時段每小時檢查一次:**有 AI 在運行就不睡**,沒有才進入 NREM/REM 兩階段記憶整理 |
| 本 skill `/jsc:role` | 使用者/助理手動 | `--new``--use``--list``--sleep``--status``--install-cron``--forget-preview` | | 本 skill `/jsc:role` | 使用者/助理手動 | `--new``--use``--list``--sleep``--status``--install-cron``--forget-preview` |
| `scripts/role/role_load.sh` | SessionStart hook | 角色與記憶載入、第一則回覆問候提示(單一實作,避免漂移) | | `scripts/role/role_load.sh` | SessionStart hook | 角色與記憶載入、第一則回覆問候提示(單一實作,避免漂移) |
| `scripts/role/role_capture.sh` | Stop hook | 對話 → 記憶(四欄固定格式) | | `scripts/role/role_capture.sh` | Stop hook | 對話 → 記憶(四欄固定格式) |
| `scripts/role/role_sleep.sh` | cron/補跑/手動 | 睡眠判斷、記憶整理、排程安裝、狀態輸出 | | `scripts/role/role_sleep.sh` | cron/補跑/手動 | 睡眠判斷、記憶整理、排程安裝、狀態輸出 |
| `scripts/role/memory.py` | 上述共用 | 記憶檔讀寫、分類、去重合併、壓縮歸檔、遺忘、載入組裝 | | `scripts/role/memory.js` | 上述共用 | 記憶檔讀寫、分類、去重合併、優先度與關聯 metadata、壓縮歸檔、遺忘、載入組裝 |
| `scripts/role/transcript.py` | 上述共用 | 抽本輪對話片段、機密與個資遮蔽 | | `scripts/role/transcript.js` | 上述共用 | 抽本輪對話片段、機密與個資遮蔽 |
| `scripts/role/role_lib.sh` | 上述共用 | log、角色解析、睡眠時段、AI 行程偵測、CLI 選擇、記憶鎖 | | `scripts/role/role_lib.sh` | 上述共用 | log、角色解析、睡眠時段、AI 行程偵測、CLI 選擇、記憶鎖 |
### 各助理支援範圍 ### 各助理支援範圍
@@ -31,7 +31,7 @@ description: 角色人格與長期記憶系統的建立與維護 skill。讓 CLI
| `--new``--use``--sleep` 等模式 | ✅ | ⚠️ 需 plugin 目錄保留 `scripts/` | ⚠️ 同左 | ❌ 只複製 `skills/`,無腳本 | ⚠️ 同左 | | `--new``--use``--sleep` 等模式 | ✅ | ⚠️ 需 plugin 目錄保留 `scripts/` | ⚠️ 同左 | ❌ 只複製 `skills/`,無腳本 | ⚠️ 同左 |
| 濃縮/整理 CLI | `claude -p` | `codex exec` | `agy -p` | `opencode run` | `copilot -p` | | 濃縮/整理 CLI | `claude -p` | `codex exec` | `agy -p` | `opencode run` | `copilot -p` |
- **`hooks/hooks.json` 只有 Claude Code 一定會讀**Codex 會從 `~/.codex/plugins/cache/generic/jsc` 找腳本。其他助理若提供等效 hook,`transcript.py` 需補對應解析器。 - **`hooks/hooks.json` 只有 Claude Code 一定會讀**Codex 會從 `~/.codex/plugins/cache/generic/jsc` 找腳本。其他助理若提供等效 hook,`transcript.js` 需補對應解析器。
- 不支援 hook 的助理仍可用:cron 排程與手動模式照常運作,只是角色不會自動載入。 - 不支援 hook 的助理仍可用:cron 排程與手動模式照常運作,只是角色不會自動載入。
### 腳本路徑解析(重要) ### 腳本路徑解析(重要)
@@ -81,12 +81,21 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
| `ROLE_SLEEP_END` | | 睡眠結束 `HH:MM` | `06:00` | | `ROLE_SLEEP_END` | | 睡眠結束 `HH:MM` | `06:00` |
| `ROLE_CLI` | | 濃縮/整理執行器:`auto``claude``codex``agy``opencode``copilot` | `auto`(先判斷目前 hook 環境,再 fallback 到已安裝工具) | | `ROLE_CLI` | | 濃縮/整理執行器:`auto``claude``codex``agy``opencode``copilot` | `auto`(先判斷目前 hook 環境,再 fallback 到已安裝工具) |
| `ROLE_MODEL` | | 強制指定模型(僅 `claude` CLI 使用) | 保底 `claude-haiku-4-5-20251001` | | `ROLE_MODEL` | | 強制指定模型(僅 `claude` CLI 使用) | 保底 `claude-haiku-4-5-20251001` |
| `ROLE_LOAD_LIMIT` | | 注入記憶的字元上限 | `8000` | | `ROLE_LOAD_LIMIT` | | SessionStart 注入記憶的字元上限,用來控制角色常駐 context 成本 | `4000` |
| `ROLE_SLEEP_TIMEOUT` | | 單次整理的模型逾時秒數 | `180` | | `ROLE_LOAD_FULL_MIN_PRIORITY` | | 全文載入的最低優先度 | `4` |
| `ROLE_LOAD_DIGEST_MIN_PRIORITY` | | 摘要載入的最低優先度;低於門檻但有 links 的記憶仍可載入摘要 | `3` |
| `ROLE_CAPTURE_ENABLED` | | Stop hook 記憶記錄開關;設 `0` 可完全停用以節省額度 | `1` |
| `ROLE_CAPTURE_MIN_CHARS` | | Stop hook 本地過濾門檻;低於門檻且無明確記憶線索時不呼叫模型 | `240` |
| `ROLE_CAPTURE_TIMEOUT` | | Stop hook 輕量濃縮模型逾時秒數 | `25` |
| `ROLE_SLEEP_TIMEOUT` | | 單次 NREM/REM 整理的模型逾時秒數 | `180` |
| `ROLE_SLEEP_COLLECT_LIMIT` | | 睡眠整理送進模型的素材字元預算 | `12000` |
| `ROLE_SLEEP_BATCH` | | 單次睡眠整理最多處理的 inbox 筆數 | `60` |
| `ROLE_SLEEP_EXISTING_LIMIT` | | 睡眠整理素材中可放入的既有記憶索引筆數 | `120` |
| `ROLE_SLEEP_OUTPUT_LIMIT` | | 睡眠整理模型輸出套用前的字元上限 | `8000` |
| `ROLE_SCOPE` | | 冒號分隔的路徑前綴,僅這些路徑下的 session 載入/記錄 | 全部 session | | `ROLE_SCOPE` | | 冒號分隔的路徑前綴,僅這些路徑下的 session 載入/記錄 | 全部 session |
| `ROLE_ERRLOG` | | 錯誤訊息額外寫入的檔案路徑 | 只走 stderr | | `ROLE_ERRLOG` | | 錯誤訊息額外寫入的檔案路徑 | 只走 stderr |
> 角色切換用 `/jsc:role --use <角色 ID>`(寫 `.active`)即可,一般不需要設 `ROLE_NAME``ROLE_NAME` 適合「單一專案固定用某角色」時寫進該環境。角色 ID 是英文大寫語意前綴加數字索引,例如 `ENGINEER01`、`MUSE02`。 > 角色切換用 `/jsc:role --use <角色 ID>`(寫 `.active`)即可,一般不需要設 `ROLE_NAME``ROLE_NAME` 適合「單一專案固定用某角色」時寫進該環境。角色 ID 是英文大寫語意前綴加數字索引,例如 `ENGINEER01`、`MUSE02`。若很在意額度,優先調低 `ROLE_LOAD_LIMIT` 或設 `ROLE_CAPTURE_ENABLED=0`。
--- ---
@@ -128,11 +137,11 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
個性欄位若使用者只想改其中一項,其餘一律沿用舊值;**共用行為區塊一律以本 skill 的最新版本覆寫**(該區塊由系統維護)。使用者不確認就不寫入。 個性欄位若使用者只想改其中一項,其餘一律沿用舊值;**共用行為區塊一律以本 skill 的最新版本覆寫**(該區塊由系統維護)。使用者不確認就不寫入。
7. 寫入 `~/.roles/<id>.md`UTF-8 無 BOM)。 7. 寫入 `~/.roles/<id>.md`UTF-8 無 BOM)。
8. 建立記憶目錄:`python3 "${ROLE_DIR}/memory.py" stats --role "<id>"`(會順帶建好 `inbox/`、六個分類與 `archive/`)。 8. 建立記憶目錄:`node "${ROLE_DIR}/memory.js" stats --role "<id>"`(會順帶建好 `inbox/`、六個分類與 `archive/`)。
9. 若使用者同意網路搜尋且已取得可保存內容,將搜尋摘要寫成已整理記憶,不進 inbox: 9. 若使用者同意網路搜尋且已取得可保存內容,將搜尋摘要寫成已整理記憶,不進 inbox:
```bash ```bash
printf '<繁體中文要點>' | python3 "${ROLE_DIR}/memory.py" seed --role "<id>" --category important --summary "<一句話總結>" --tags "角色背景,初始資料" --source "<來源 URL>" printf '<繁體中文要點>' | node "${ROLE_DIR}/memory.js" seed --role "<id>" --category important --summary "<一句話總結>" --tags "角色背景,初始資料" --source "<來源 URL>"
``` ```
多個來源可各寫一則,或合併同主題後以最主要來源作 `--source`。不可寫入憑證或個資。 多個來源可各寫一則,或合併同主題後以最主要來源作 `--source`。不可寫入憑證或個資。
@@ -146,7 +155,7 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
### `--list` ### `--list`
列出 `~/.roles/*.md`,以表格輸出:角色 ID、顯示名稱、emoji、nature 摘要、更新時間、是否為 `.active`、記憶目錄、記憶總數(可用 `memory.py stats` 取得)。這個指令必須能查出每個角色對應的 ID。 列出 `~/.roles/*.md`,以表格輸出:角色 ID、顯示名稱、emoji、nature 摘要、更新時間、是否為 `.active`、記憶目錄、記憶總數(可用 `memory.js stats` 取得)。這個指令必須能查出每個角色對應的 ID。
### `--sleep` ### `--sleep`
@@ -158,12 +167,25 @@ ROLE_DIR="<skill base directory>/../../scripts/role" # 其他助理
輸出整理結果(新增/合併/捨棄/歸檔筆數與遺忘清單)。 輸出整理結果(新增/合併/捨棄/歸檔筆數與遺忘清單)。
### 額度控制策略
角色系統預設避免因常駐人格與記憶造成大量模型額度占用:
| 環節 | 控制方式 |
| --- | --- |
| SessionStart | 預設 `ROLE_LOAD_LIMIT=4000`,只載入高優先度全文與中高優先度摘要;低 priority、無 links、久未更新的記憶不進 context |
| SessionStop | 先用本地規則略過短回合與無記憶線索的對話,只有值得保存才呼叫模型做輕量編碼 |
| Sleep | 高成本的去重、合併、抽象化與 links 建立留到睡眠週期,但仍受 `ROLE_SLEEP_COLLECT_LIMIT`、`ROLE_SLEEP_BATCH`、`ROLE_SLEEP_EXISTING_LIMIT` 與 `ROLE_SLEEP_OUTPUT_LIMIT` 控制;沒有 inbox 時只做本地遺忘檢查 |
| 手動節流 | 可設 `ROLE_CAPTURE_ENABLED=0` 關閉 Stop 記錄,或調低 `ROLE_LOAD_LIMIT`/調高 `ROLE_LOAD_FULL_MIN_PRIORITY` |
Stop hook 只做「編碼前處理」,輸出粗分類、summary、tags、priority、relevance 與要點;完整 NREM/REM 整理只在睡眠週期進行。
### `--forget-preview` ### `--forget-preview`
只預覽會被遺忘的記憶、不實際刪除: 只預覽會被遺忘的記憶、不實際刪除:
```bash ```bash
python3 "${ROLE_DIR}/memory.py" forget --role "<角色 ID>" --dry-run node "${ROLE_DIR}/memory.js" forget --role "<角色 ID>" --dry-run
``` ```
### `--status``--diagnose` ### `--status``--diagnose`
@@ -182,7 +204,7 @@ python3 "${ROLE_DIR}/memory.py" forget --role "<角色 ID>" --dry-run
| 工作階段 | 建立角色後是否**重開過** CLISessionStart 只在啟動時觸發) | | 工作階段 | 建立角色後是否**重開過** CLISessionStart 只在啟動時觸發) |
| 範圍 | `ROLE_SCOPE` 是否把目前目錄排除 | | 範圍 | `ROLE_SCOPE` 是否把目前目錄排除 |
| 時段 | 目前是否落在睡眠時段(睡眠時本來就不載入角色) | | 時段 | 目前是否落在睡眠時段(睡眠時本來就不載入角色) |
| 依賴 | `python3` 與 `ROLE_CLI` 選到的 CLI 是否找得到 | | 依賴 | `node` 與 `ROLE_CLI` 選到的 CLI 是否找得到 |
| 排程 | cron 條目是否存在、cron 服務是否執行中(WSL 常未啟動 → 靠啟動時補跑) | | 排程 | cron 條目是否存在、cron 服務是否執行中(WSL 常未啟動 → 靠啟動時補跑) |
### `--install-cron``--remove-cron` ### `--install-cron``--remove-cron`
@@ -244,8 +266,8 @@ updated: <yyyy/MM/dd HH:mm:ss>
### 記憶 ### 記憶
- 記憶存放於 `~/.memory/<角色 ID>/`,來源是與使用者的對話與新建角色時使用者同意建立的初始背景資料:每輪結束由 hook 自動記錄到 `inbox/`,睡眠時段整理歸檔。 - 記憶存放於 `~/.memory/<角色 ID>/`,來源是與使用者的對話與新建角色時使用者同意建立的初始背景資料:每輪結束由 hook 自動記錄到 `inbox/`,睡眠時段整理歸檔。
- 整理規則分類成**重要/興趣/新知/技能/日常/其他**六類 → 去除重複(重複者併入既有記憶)→ 設定標籤與一句話總結 → 壓縮內容後歸檔;原始記錄壓縮保存在 `archive/raw/`。 - 整理規則採睡眠分期模型:**NREM 鞏固**先分類成重要/興趣/新知/技能/日常/其他六類,去除雜訊、去重、合併、設定標籤、摘要與優先度;**REM 整合**再建立跨記憶關聯、抽出可重複使用的規則與提取線索;原始記錄壓縮保存在 `archive/raw/`。
- **日常與其他**兩類會依使用頻率適當遺忘:久未再次出現命中次數低者,壓縮到 `archive/forgotten/` 後移出常用記憶。 - **日常與其他**兩類會依使用頻率、優先度與關聯適當遺忘:久未再次出現命中次數低、優先度低且沒有關聯者,壓縮到 `archive/forgotten/` 後移出常用記憶。
- 載入順序:**重要與興趣載入全文**;其餘只載入總結與標籤,依**技能 → 新知 → 日常 → 其他**排序。需要細節時自行讀取對應分類的記憶檔。 - 載入順序:**重要與興趣載入全文**;其餘只載入總結與標籤,依**技能 → 新知 → 日常 → 其他**排序。需要細節時自行讀取對應分類的記憶檔。
- 使用者明確要求記住某件事時,主動補寫一則記憶(載入時會提供補寫指令)。 - 使用者明確要求記住某件事時,主動補寫一則記憶(載入時會提供補寫指令)。
- **絕不把憑證與個資寫進記憶**:token、密碼、API key、連線字串、Email、電話、姓名、身分證號。 - **絕不把憑證與個資寫進記憶**:token、密碼、API key、連線字串、Email、電話、姓名、身分證號。
@@ -272,14 +294,14 @@ updated: <yyyy/MM/dd HH:mm:ss>
└── state.json 上次整理/遺忘時間 └── state.json 上次整理/遺忘時間
``` ```
每則記憶是一個 `.md`frontmatter 帶 `id``category``summary`(一句話總結)/`tags``created``updated``hits`(命中次數,去重合併時 +1)。 每則記憶是一個 `.md`frontmatter 帶 `id``category``summary`(一句話總結)/`tags``priority`15)/`relevance`explicitfuturerepeatednoveltyemotionaltemporary 等)/`links`(相關記憶 id)/`sleep_stage`encodingseednremremnrem-rem)/`created``updated``last_replayed``hits`(命中次數,去重合併時 +1)。舊記憶沒有新欄位時,讀取時會依分類補預設值。
遺忘規則(只套用於日常與其他): 遺忘規則(只套用於日常與其他):
| 分類 | 未更新天數 | 命中次數 | 動作 | | 分類 | 未更新天數 | 命中次數 | 優先度 | 關聯 | 動作 |
| --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| 日常 daily | ≥ 14 天 | ≤ 1 | 壓縮到 `archive/forgotten/` 後移除 | | 日常 daily | ≥ 14 天 | ≤ 1 | ≤ 2 | 無 links | 壓縮到 `archive/forgotten/` 後移除 |
| 其他 other | ≥ 7 天 | ≤ 1 | 壓縮到 `archive/forgotten/` 後移除 | | 其他 other | ≥ 7 天 | ≤ 1 | ≤ 2 | 無 links | 壓縮到 `archive/forgotten/` 後移除 |
--- ---
@@ -290,14 +312,15 @@ flowchart TD
A[cron 每小時觸發<br/>睡眠時段內] --> B{有 AI 正在運行?} A[cron 每小時觸發<br/>睡眠時段內] --> B{有 AI 正在運行?}
B -- 有 --> C[不睡,下個整點再檢查] B -- 有 --> C[不睡,下個整點再檢查]
B -- 沒有 --> D[進入睡眠,取得記憶鎖] B -- 沒有 --> D[進入睡眠,取得記憶鎖]
D --> E[collectinbox 待整理 + 既有記憶索引] D --> E[collectinbox 待整理 + 既有記憶索引/優先度/關聯]
E --> F{有待整理記憶?} E --> F{有待整理記憶?}
F -- 沒有 --> G[更新整理時間 → 執行遺忘] F -- 沒有 --> G[更新整理時間 → 執行遺忘]
F -- 有 --> H[CLI 分類/去重/標籤/總結/壓縮] F -- 有 --> H[NREM:分類/去噪/去重/合併/優先度]
H --> I[apply:寫入分類、原始記錄歸檔] H --> I[REM:跨記憶連結/抽象規則/提取線索]
I --> J[forget:日常與其他依使用頻率遺忘] I --> J[apply:寫入分類、原始記錄歸檔、保存睡眠摘要]
J --> K[釋放鎖] J --> K[forget:低優先度且無關聯的日常/其他遺忘]
G --> K K --> Z[釋放鎖]
G --> Z
L[SessionStart:白天啟動 CLI] --> M{距上次整理 ≥ 20 小時<br/>且 inbox 有內容?} L[SessionStart:白天啟動 CLI] --> M{距上次整理 ≥ 20 小時<br/>且 inbox 有內容?}
M -- 是 --> N[背景補跑 --catchup] M -- 是 --> N[背景補跑 --catchup]
M -- 否 --> O[正常載入角色與記憶] M -- 否 --> O[正常載入角色與記憶]
@@ -312,7 +335,7 @@ flowchart TD
| 防線 | 位置 | 內容 | | 防線 | 位置 | 內容 |
| --- | --- | --- | | --- | --- | --- |
| 1 | 濃縮與整理提示詞 | 明令不得輸出 token/密碼/API key/連線字串/Email/電話/姓名/身分證號 | | 1 | 濃縮與整理提示詞 | 明令不得輸出 token/密碼/API key/連線字串/Email/電話/姓名/身分證號 |
| 2 | `transcript.py` 的 `redact` | 正則遮蔽:URL 內嵌憑證、40 字元 hex token、`gh?_``sk-` token、`token=``password=`、`Authorization:`、Email、台灣手機、身分證號 | | 2 | `transcript.js` 的 `redact` | 正則遮蔽:URL 內嵌憑證、40 字元 hex token、`gh?_``sk-` token、`token=``password=`、`Authorization:`、Email、台灣手機、身分證號 |
第二道防線不可移除 —— 模型不一定遵守指令,而記憶會被長期保存並在每次啟動時載入。 第二道防線不可移除 —— 模型不一定遵守指令,而記憶會被長期保存並在每次啟動時載入。