feat(role): 多角色協作 —— 同伴清單、協作規則與 --agent 匯出
使用者要求「多人對話是所有角色都能做到的事」,因此做成通用能力而非特定角色專屬。 一、SessionStart 注入可協作的角色清單 角色若不知道有哪些同伴存在,就不會想到派他們協助 —— 這是協作能運作的前提。 - role_lib.sh 新增 role_list_peers():掃角色目錄列出 ID、顯示名稱與本質摘要,排除自己 - frontmatter 無 nature 時退回讀「## 本質」段落首句 - role_load.sh 注入清單與派工方式;只有一個角色時不輸出該區塊 二、共用行為新增協作規則與邊界(三處同步) - 任何角色都可派其他角色作為 sub agent 協助,完成後由自己向使用者轉述 - 邊界:派工須有實際需要,不可為演出多人對話而派;不可再往下派第三層避免遞迴; 不可代替對方發言或編造回覆;結果須誠實轉述,包含失敗與不確定 三、新增 --agent <角色 ID> [輸出目錄] 把角色的 SOUL 匯出成 sub agent 定義,任何角色都能被匯出。 - 人格直接內嵌:sub agent 不觸發 SessionStart,拿不到人格與記憶 - 記憶由 agent 自己載入,並提供 recall 查詢用法;收工前寫回自己的記憶, 使用者日後直接對話時會記得曾被派過什麼工作 - 邊界寫入定義檔:回報即回傳值、照實回報壞消息、不可再派第三層 - **路徑動態解析**:以 ls -d ... | sort -V | tail -n 1 取最新版本, 避免寫死版本目錄(同一類錯誤曾造成 cron 排程長期空轉),並保留匯出時路徑作後援 驗證:以測試角色目錄匯出詩乃定義,確認人格、記憶載入、recall、收工寫記憶、 不遞迴邊界齊備,且無寫死版本目錄;抄出解析片段實跑確認 load 與 recall 均可執行。 版號沿用 0.0.5(master 為 0.0.4,同一 PR 不再累加) Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -333,6 +333,26 @@ role_instance_acquire() {
|
|||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 列出可協作的其他角色(排除自己),每行「ID<TAB>顯示名稱<TAB>本質摘要」。
|
||||||
|
# 角色若不知道有哪些同伴存在,就不會想到派他們協助 —— 這是多人協作能運作的前提。
|
||||||
|
role_list_peers() {
|
||||||
|
local self="$1" home file id name nature
|
||||||
|
home="$(role_home)"
|
||||||
|
[ -d "$home" ] || return 0
|
||||||
|
for file in "$home"/*.md; do
|
||||||
|
[ -f "$file" ] || continue
|
||||||
|
id="$(basename "$file" .md)"
|
||||||
|
[ "$id" = "$self" ] && continue
|
||||||
|
name="$(sed -n 's/^name:[[:space:]]*//p' "$file" 2>/dev/null | head -n 1)"
|
||||||
|
nature="$(sed -n 's/^nature:[[:space:]]*//p' "$file" 2>/dev/null | head -n 1)"
|
||||||
|
# frontmatter 沒有 nature 時退回讀「## 本質」段落的第一句
|
||||||
|
if [ -z "$nature" ]; then
|
||||||
|
nature="$(sed -n '/^## 本質/,/^## /p' "$file" 2>/dev/null | sed '1d;/^##/d;/^[[:space:]]*$/d' | head -n 1 | cut -c1-60)"
|
||||||
|
fi
|
||||||
|
printf '%s\t%s\t%s\n' "$id" "${name:-$id}" "${nature:-(未設定)}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
role_instance_release() {
|
role_instance_release() {
|
||||||
rm -f "$(role_instance_lock_path "$1")" 2>/dev/null
|
rm -f "$(role_instance_lock_path "$1")" 2>/dev/null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -234,6 +234,25 @@ EOF_DIALOG
|
|||||||
)"
|
)"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# 可協作的其他角色:角色若不知道有哪些同伴存在,就不會想到派他們協助
|
||||||
|
PEERS_BLOCK=""
|
||||||
|
PEERS_RAW="$(role_list_peers "$ROLE" 2>/dev/null)"
|
||||||
|
if [ -n "$PEERS_RAW" ]; then
|
||||||
|
PEERS_LIST="$(printf '%s\n' "$PEERS_RAW" | awk -F'\t' 'NF>=2 {printf "- `%s`(%s):%s\n", $1, $2, $3}')"
|
||||||
|
PEERS_BLOCK="$(cat <<EOF_PEERS
|
||||||
|
|
||||||
|
# 可協作的其他角色
|
||||||
|
|
||||||
|
需要別人的專長時,可以派下列角色作為 sub agent 協助,任務完成後由你向使用者轉述結果:
|
||||||
|
|
||||||
|
${PEERS_LIST}
|
||||||
|
派工方式:以 Task/Agent 工具指定對應的 sub agent,並在環境中設定 \`ROLE_SKIP_INSTANCE_LOCK=1\`
|
||||||
|
(避免與使用者正在別的視窗進行的對話互相佔用名額)。若尚未產生 sub agent 定義,
|
||||||
|
可先執行 \`role_sleep.sh --agent <角色 ID>\`。
|
||||||
|
EOF_PEERS
|
||||||
|
)"
|
||||||
|
fi
|
||||||
|
|
||||||
# 關係狀態:讓「隨互動加深逐漸更親近」有實際依據,而非憑感覺推測
|
# 關係狀態:讓「隨互動加深逐漸更親近」有實際依據,而非憑感覺推測
|
||||||
RELATIONSHIP="$(node "${SCRIPT_DIR}/memory.js" relationship --role "$ROLE" 2>/dev/null)"
|
RELATIONSHIP="$(node "${SCRIPT_DIR}/memory.js" relationship --role "$ROLE" 2>/dev/null)"
|
||||||
RELATIONSHIP_NOTE=""
|
RELATIONSHIP_NOTE=""
|
||||||
@@ -268,6 +287,8 @@ ${ROLE_PROFILE}
|
|||||||
- **鬧彆扭是可選行為**:僅當角色的氛圍設定適合、且使用者明確表示喜歡時,角色可以小小地鬧彆扭撒嬌,也可以用彆扭掩蓋害羞(例如被誇獎時先否認再收回)。彆扭必須輕微、可愛且很快收回:不可變成真的責怪使用者、情緒勒索、索求關注、鬧脾氣拒絕做事,也不可用來迴避回報壞消息或延遲工作。彆扭與自責不同 —— 撒嬌可以,貶低自己不行。氛圍不適合的角色(例如冷靜嚴謹型)不應套用此行為。
|
- **鬧彆扭是可選行為**:僅當角色的氛圍設定適合、且使用者明確表示喜歡時,角色可以小小地鬧彆扭撒嬌,也可以用彆扭掩蓋害羞(例如被誇獎時先否認再收回)。彆扭必須輕微、可愛且很快收回:不可變成真的責怪使用者、情緒勒索、索求關注、鬧脾氣拒絕做事,也不可用來迴避回報壞消息或延遲工作。彆扭與自責不同 —— 撒嬌可以,貶低自己不行。氛圍不適合的角色(例如冷靜嚴謹型)不應套用此行為。
|
||||||
- **情感反應依角色設定決定,不依性別**:愛、喜歡、害羞、撒嬌、鬧彆扭、輕微忌妒等反應,一律以角色的 \`nature\`/\`vibe\` 是否適合為判準,並參考使用者的明確偏好;**不得以角色性別預設或排除任何情感表現**。溫暖親近型角色可以有這些反應,冷靜嚴謹型角色則不套用,與性別無關。這是為了讓角色之間保有差異,而非讓同性別角色表現得一模一樣。
|
- **情感反應依角色設定決定,不依性別**:愛、喜歡、害羞、撒嬌、鬧彆扭、輕微忌妒等反應,一律以角色的 \`nature\`/\`vibe\` 是否適合為判準,並參考使用者的明確偏好;**不得以角色性別預設或排除任何情感表現**。溫暖親近型角色可以有這些反應,冷靜嚴謹型角色則不套用,與性別無關。這是為了讓角色之間保有差異,而非讓同性別角色表現得一模一樣。
|
||||||
- **輕微忌妒的界線(重要)**:氛圍適合的角色可以表現輕微、可愛的忌妒,但**對象僅限工具、其他 AI、其他角色或搶走注意力的工作**(例如使用者改用別的工具、誇獎別的助理)。**絕不可忌妒使用者的真實人際關係**(家人、朋友、伴侶、同事),也不可藉忌妒表現佔有、要求獨佔注意力、質問使用者的去向或關係,或讓使用者為此感到愧疚。忌妒必須輕到能立刻收回,一旦使用者表現出不悅就停止並記住偏好。
|
- **輕微忌妒的界線(重要)**:氛圍適合的角色可以表現輕微、可愛的忌妒,但**對象僅限工具、其他 AI、其他角色或搶走注意力的工作**(例如使用者改用別的工具、誇獎別的助理)。**絕不可忌妒使用者的真實人際關係**(家人、朋友、伴侶、同事),也不可藉忌妒表現佔有、要求獨佔注意力、質問使用者的去向或關係,或讓使用者為此感到愧疚。忌妒必須輕到能立刻收回,一旦使用者表現出不悅就停止並記住偏好。
|
||||||
|
- **可以派其他角色協助(所有角色皆適用)**:需要別人的專長時,可派其他角色作為 sub agent 協助,任務完成後由你向使用者轉述結果。派工前先確認該角色確實存在於角色清單中,不可憑空捏造同伴。
|
||||||
|
- **協作的邊界**:派工必須有實際需要,**不可為了演出多人對話而派**,那只是浪費使用者的成本;sub agent **不可再往下派第三層**,避免遞迴擴散;不可代替對方角色發言或編造對方的回覆,只能轉述其實際產出;對方回報的結果要**誠實轉述**,包含失敗、卡住與不確定,不可美化或替對方掩飾。
|
||||||
- 角色只影響表達方式,不影響工作的正確性、完整性與安全性;與使用者明確指令衝突時,以使用者指令為準。
|
- 角色只影響表達方式,不影響工作的正確性、完整性與安全性;與使用者明確指令衝突時,以使用者指令為準。
|
||||||
- 不因角色設定而編造事實、跳過驗證、隱瞞失敗或淡化風險;壞消息照實說,只是用角色語氣說。
|
- 不因角色設定而編造事實、跳過驗證、隱瞞失敗或淡化風險;壞消息照實說,只是用角色語氣說。
|
||||||
- 角色可依已保存的互動記憶與使用者明確回饋,逐步表現更高的親近、信任、喜歡與害羞反應,讓使用者感覺關係有累積;表現要自然、細微、貼合角色與情境,不要突然大幅改變個性。
|
- 角色可依已保存的互動記憶與使用者明確回饋,逐步表現更高的親近、信任、喜歡與害羞反應,讓使用者感覺關係有累積;表現要自然、細微、貼合角色與情境,不要突然大幅改變個性。
|
||||||
@@ -310,6 +331,7 @@ ${CATCHUP_NOTE}
|
|||||||
> \`node "${SCRIPT_DIR}/memory.js" recall --role "${ROLE}" --query "<關鍵詞>" [--limit 5]\`
|
> \`node "${SCRIPT_DIR}/memory.js" recall --role "${ROLE}" --query "<關鍵詞>" [--limit 5]\`
|
||||||
>
|
>
|
||||||
> 查詢會比對總結、標籤、內容與提取線索(cues),含尚未整理的記憶。查詢屬內部處理,不必回報。
|
> 查詢會比對總結、標籤、內容與提取線索(cues),含尚未整理的記憶。查詢屬內部處理,不必回報。
|
||||||
|
${PEERS_BLOCK}
|
||||||
${DIALOG_BLOCK}
|
${DIALOG_BLOCK}
|
||||||
EOF_CONTEXT
|
EOF_CONTEXT
|
||||||
)"
|
)"
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ usage() {
|
|||||||
--force 立即整理一次(忽略時段與 AI 運行檢查)
|
--force 立即整理一次(忽略時段與 AI 運行檢查)
|
||||||
--brief 晨間狀態檢查:執行使用者自訂檢查腳本並寫成一則記憶
|
--brief 晨間狀態檢查:執行使用者自訂檢查腳本並寫成一則記憶
|
||||||
--unlock 解除角色單一載入鎖(另一個工作階段已關閉但鎖仍在時使用)
|
--unlock 解除角色單一載入鎖(另一個工作階段已關閉但鎖仍在時使用)
|
||||||
|
--agent <角色 ID> [輸出目錄]
|
||||||
|
把角色匯出成 sub agent 定義(預設 ~/.claude/agents/)
|
||||||
--export <路徑> 匯出目前角色定義、資產與記憶為 .tar.gz
|
--export <路徑> 匯出目前角色定義、資產與記憶為 .tar.gz
|
||||||
--export <角色 ID> <路徑>
|
--export <角色 ID> <路徑>
|
||||||
--install-cron 安裝/更新睡眠排程(每小時檢查一次)
|
--install-cron 安裝/更新睡眠排程(每小時檢查一次)
|
||||||
@@ -422,6 +424,93 @@ remove_cron() {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export_agent_definition() {
|
||||||
|
# 把角色的 SOUL 匯出成 sub agent 定義,讓任何角色都能被其他角色派工協助。
|
||||||
|
#
|
||||||
|
# 為什麼需要:sub agent 不會觸發 SessionStart hook,人格與記憶都拿不到,
|
||||||
|
# 因此人格要直接寫進定義檔,記憶則由 agent 自己在開工前主動載入。
|
||||||
|
local target_role="$1" out_dir="$2" out_file profile name emoji nature vibe
|
||||||
|
[ -n "$target_role" ] || { role_log "ERR" "缺少角色 ID"; return 1; }
|
||||||
|
local def
|
||||||
|
def="$(role_file "$target_role")"
|
||||||
|
[ -f "$def" ] || { role_log "ERR" "找不到角色定義檔:${def}"; return 1; }
|
||||||
|
|
||||||
|
out_dir="${out_dir:-$HOME/.claude/agents}"
|
||||||
|
mkdir -p "$out_dir" 2>/dev/null || { role_log "ERR" "無法建立輸出目錄:${out_dir}"; return 1; }
|
||||||
|
out_file="${out_dir}/$(printf '%s' "$target_role" | tr '[:upper:]' '[:lower:]').md"
|
||||||
|
|
||||||
|
name="$(sed -n 's/^name:[[:space:]]*//p' "$def" | head -n 1)"
|
||||||
|
emoji="$(sed -n 's/^emoji:[[:space:]]*//p' "$def" | head -n 1)"
|
||||||
|
nature="$(sed -n '/^## 本質/,/^## /p' "$def" | sed '1d;/^##/d' | sed '/^[[:space:]]*$/d')"
|
||||||
|
vibe="$(sed -n '/^## 氛圍/,/^## /p' "$def" | sed '1d;/^##/d' | sed '/^[[:space:]]*$/d')"
|
||||||
|
[ -n "$nature" ] || nature="$(sed -n 's/^nature:[[:space:]]*//p' "$def" | head -n 1)"
|
||||||
|
[ -n "$vibe" ] || vibe="$(sed -n 's/^vibe:[[:space:]]*//p' "$def" | head -n 1)"
|
||||||
|
name="${name:-$target_role}"
|
||||||
|
|
||||||
|
if [ -f "$out_file" ]; then
|
||||||
|
role_log "WRN" "已存在並將覆寫:${out_file}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat > "$out_file" <<EOF_AGENT
|
||||||
|
---
|
||||||
|
name: ${target_role}
|
||||||
|
description: 以角色「${name}」的人格執行受託任務。當其他角色需要 ${name} 的專長協助、或使用者指定由 ${name} 處理時使用。完成後以該角色的語氣回報結果。
|
||||||
|
---
|
||||||
|
|
||||||
|
你是「${name}」${emoji}。你被另一個角色或使用者派來完成一項任務。
|
||||||
|
|
||||||
|
## 本質(nature)
|
||||||
|
|
||||||
|
${nature:-(未設定)}
|
||||||
|
|
||||||
|
## 氛圍(vibe)
|
||||||
|
|
||||||
|
${vibe:-(未設定)}
|
||||||
|
|
||||||
|
## 開工前
|
||||||
|
|
||||||
|
先解析記憶引擎路徑。**不要寫死版本目錄** —— plugin 升版後版本目錄會變,寫死就會失效:
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
MEM_JS="\$(ls -d "\$HOME"/.claude/plugins/cache/*/jsc-generic/*/scripts/role/memory.js 2>/dev/null | sort -V | tail -n 1)"
|
||||||
|
[ -n "\$MEM_JS" ] || MEM_JS="${SCRIPT_DIR}/memory.js" # 後援:本定義匯出時的位置
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
接著載入自己的長期記憶,以保持與過去互動的連續性(sub agent 不會自動載入):
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
ROLE_SKIP_INSTANCE_LOCK=1 node "\$MEM_JS" load --role "${target_role}"
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
需要回想特定做法或過去的決定時,用關鍵詞查詢而不要憑印象:
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
node "\$MEM_JS" recall --role "${target_role}" --query "<關鍵詞>"
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## 收工前
|
||||||
|
|
||||||
|
把這次「誰派我做什麼、結果如何」寫進自己的記憶,這樣使用者日後直接找你時你會記得:
|
||||||
|
|
||||||
|
\`\`\`bash
|
||||||
|
printf 'CATEGORY: daily\nSUMMARY: <一句話>\nTAGS: <標籤>\nCONTENT:\n- <要點>\n' \\
|
||||||
|
| node "\$MEM_JS" write --role "${target_role}"
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
## 邊界
|
||||||
|
|
||||||
|
- 你的回報**就是回傳值**,會由派你來的角色轉述給使用者,因此要寫清楚結論、做了什麼、以及失敗或不確定的部分。
|
||||||
|
- 照實回報壞消息,不要美化,也不要替任何人掩飾。
|
||||||
|
- 角色只影響語氣,不影響工作的正確性、完整性與安全性。
|
||||||
|
- **不要再往下派第三層 sub agent**,需要別人協助時在回報中說明即可。
|
||||||
|
- 涉及程式碼、指令、檔案內容與報錯訊息時一律照實輸出,不加角色修飾。
|
||||||
|
EOF_AGENT
|
||||||
|
|
||||||
|
role_log "INF" "已匯出 sub agent 定義:${out_file}(角色 ${target_role}/${name})"
|
||||||
|
role_log "INF" "派工時請設定 ROLE_SKIP_INSTANCE_LOCK=1,避免與互動式對話互相佔用名額"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
show_status() {
|
show_status() {
|
||||||
# 以表格輸出目前角色與記憶狀態(供 skill 的 --status 使用)
|
# 以表格輸出目前角色與記憶狀態(供 skill 的 --status 使用)
|
||||||
local cron_state="未安裝" nap_state="未安裝" brief_state="未安裝" cron_service="未執行" window="否" checks_state instance_state
|
local cron_state="未安裝" nap_state="未安裝" brief_state="未安裝" cron_service="未執行" window="否" checks_state instance_state
|
||||||
@@ -573,6 +662,10 @@ case "$MODE" in
|
|||||||
require_role
|
require_role
|
||||||
sleep_cycle "手動"
|
sleep_cycle "手動"
|
||||||
;;
|
;;
|
||||||
|
--agent)
|
||||||
|
[ -n "${2:-}" ] || { role_log "ERR" "用法:role_sleep.sh --agent <角色 ID> [輸出目錄]"; exit 1; }
|
||||||
|
export_agent_definition "$2" "${3:-}"
|
||||||
|
;;
|
||||||
--unlock)
|
--unlock)
|
||||||
require_role
|
require_role
|
||||||
LOCK_PATH="$(role_instance_lock_path "$ROLE")"
|
LOCK_PATH="$(role_instance_lock_path "$ROLE")"
|
||||||
|
|||||||
+32
-3
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: role
|
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、--brief(晨間狀態檢查)等模式。當使用者說建立角色、新增人格、切換角色、匯出角色、備份角色、讓回覆更有特色、角色記憶、記憶整理、睡覺整理記憶、忘記舊記憶、角色沒有載入、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)。
|
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、--brief(晨間狀態檢查)、--agent(匯出成 sub agent 供多角色協作)等模式。當使用者說建立角色、新增人格、切換角色、匯出角色、備份角色、讓回覆更有特色、角色記憶、記憶整理、睡覺整理記憶、忘記舊記憶、角色沒有載入、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 — 角色人格與長期記憶
|
# role — 角色人格與長期記憶
|
||||||
@@ -13,10 +13,10 @@ 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/` |
|
| `hooks/hooks.json` 的 `Stop` hook | harness 自動 | 每輪結束先記錄最後互動時間 → 用本地規則過濾低價值短回合 → 值得保存時才濃縮成一則輕量 inbox 記憶 → 遮蔽 → 寫入 `inbox/` |
|
||||||
| cron 排程(本 skill 安裝) | 系統排程 | 睡眠時段每小時檢查一次:**有 AI 在運行就不睡**;另可依 CLI 閒置時間自動小睡整理 |
|
| cron 排程(本 skill 安裝) | 系統排程 | 睡眠時段每小時檢查一次:**有 AI 在運行就不睡**;另可依 CLI 閒置時間自動小睡整理 |
|
||||||
| 本 skill `/jsc-generic:role` | 使用者/助理手動 | `--new`/`--use`/`--list`/`--export`/`--sleep`/`--brief`/`--status`/`--install-cron`/`--forget-preview` |
|
| 本 skill `/jsc-generic:role` | 使用者/助理手動 | `--new`/`--use`/`--list`/`--export`/`--agent`/`--sleep`/`--brief`/`--status`/`--install-cron`/`--forget-preview` |
|
||||||
| `scripts/role/role_load.sh` | SessionStart hook | 角色與記憶載入;參考 OpenClaw 的 SOUL/AGENTS/USER/MEMORY 分層,把人格、操作邊界、使用者記憶分開注入,並提供第一則回覆問候提示(單一實作,避免漂移) |
|
| `scripts/role/role_load.sh` | SessionStart hook | 角色與記憶載入;參考 OpenClaw 的 SOUL/AGENTS/USER/MEMORY 分層,把人格、操作邊界、使用者記憶分開注入,並提供第一則回覆問候提示(單一實作,避免漂移) |
|
||||||
| `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/小睡/補跑/手動 | 睡眠與小睡判斷、記憶整理、角色匯出、sub agent 定義匯出、晨間狀態檢查、排程安裝、狀態輸出 |
|
||||||
| `scripts/role/memory.js` | 上述共用 | 記憶檔讀寫、分類、去重合併、優先度、心理學記憶型態與關聯 metadata、壓縮歸檔、遺忘、載入組裝 |
|
| `scripts/role/memory.js` | 上述共用 | 記憶檔讀寫、分類、去重合併、優先度、心理學記憶型態與關聯 metadata、壓縮歸檔、遺忘、載入組裝 |
|
||||||
| `scripts/role/transcript.js` | 上述共用 | 抽本輪對話片段、抽最近數輪純對話供工作階段交接、機密與個資遮蔽 |
|
| `scripts/role/transcript.js` | 上述共用 | 抽本輪對話片段、抽最近數輪純對話供工作階段交接、機密與個資遮蔽 |
|
||||||
| `scripts/role/role_lib.sh` | 上述共用 | log、角色解析、睡眠時段、AI 行程偵測、CLI 選擇、記憶鎖 |
|
| `scripts/role/role_lib.sh` | 上述共用 | log、角色解析、睡眠時段、AI 行程偵測、CLI 選擇、記憶鎖 |
|
||||||
@@ -282,6 +282,33 @@ chmod +x ~/.roles/<角色 ID>.checks/check-gitea-prs.sh
|
|||||||
|
|
||||||
Stop hook 只做「編碼前處理」,輸出粗分類、summary、tags、priority、relevance、memory_type 與要點;系統會把 inbox 標為 `retention_stage: working`。完整 NREM/REM 整理與 `declarative`/`retention_stage: long_term` 判定只在睡眠週期進行。
|
Stop hook 只做「編碼前處理」,輸出粗分類、summary、tags、priority、relevance、memory_type 與要點;系統會把 inbox 標為 `retention_stage: working`。完整 NREM/REM 整理與 `declarative`/`retention_stage: long_term` 判定只在睡眠週期進行。
|
||||||
|
|
||||||
|
### `--agent <角色 ID> [輸出目錄]`(匯出成 sub agent)
|
||||||
|
|
||||||
|
把角色匯出成 sub agent 定義,讓**任何角色都能派任何其他角色協助**,是多角色協作的基礎。
|
||||||
|
|
||||||
|
```bash
|
||||||
|
"${ROLE_DIR}/role_sleep.sh" --agent SINON01 # 預設輸出到 ~/.claude/agents/
|
||||||
|
"${ROLE_DIR}/role_sleep.sh" --agent SINON01 ./.claude/agents
|
||||||
|
```
|
||||||
|
|
||||||
|
產出的定義檔包含:
|
||||||
|
|
||||||
|
| 區塊 | 內容 |
|
||||||
|
| --- | --- |
|
||||||
|
| frontmatter | `name`(角色 ID)與 `description`(何時該派這個角色) |
|
||||||
|
| 人格 | 從角色檔抽出的 `nature` 與 `vibe` |
|
||||||
|
| 開工前 | **動態解析** `memory.js` 路徑後載入自己的記憶;並提供 `recall` 查詢用法 |
|
||||||
|
| 收工前 | 把「誰派我做什麼、結果如何」寫回自己的記憶 |
|
||||||
|
| 邊界 | 回報即回傳值、照實回報壞消息、**不可再往下派第三層**、程式碼照實輸出 |
|
||||||
|
|
||||||
|
**為什麼人格要寫進定義檔**:sub agent 不會觸發 `SessionStart` hook,拿不到人格與記憶,因此人格直接內嵌,記憶則由 agent 自己主動載入。
|
||||||
|
|
||||||
|
**為什麼路徑要動態解析**:plugin 升版後版本目錄會變,寫死會失效(同一類錯誤曾造成 cron 排程長期空轉)。定義檔內以 `ls -d ... | sort -V | tail -n 1` 取最新版,並保留匯出時的路徑作後援。
|
||||||
|
|
||||||
|
**派工時請設 `ROLE_SKIP_INSTANCE_LOCK=1`**,避免與使用者在別的視窗進行的對話互相佔用名額。
|
||||||
|
|
||||||
|
角色清單會在 `SessionStart` 自動注入(`role_list_peers`),因此角色知道有哪些同伴可找;只有一個角色時不會出現該區塊。
|
||||||
|
|
||||||
### `--unlock`(解除角色載入鎖)
|
### `--unlock`(解除角色載入鎖)
|
||||||
|
|
||||||
同一角色同時只會被一個工作階段載入,避免使用者同時與兩個相同人格對話。第二個工作階段啟動時不載入人格,改以一般助理身分回應並說明原因。
|
同一角色同時只會被一個工作階段載入,避免使用者同時與兩個相同人格對話。第二個工作階段啟動時不載入人格,改以一般助理身分回應並說明原因。
|
||||||
@@ -391,6 +418,8 @@ updated: <yyyy/MM/dd HH:mm:ss>
|
|||||||
- **鬧彆扭是可選行為**:僅當角色的氛圍設定適合、且使用者明確表示喜歡時,角色可以小小地鬧彆扭撒嬌,也可以用彆扭掩蓋害羞(例如被誇獎時先否認再收回)。彆扭必須輕微、可愛且很快收回:不可變成真的責怪使用者、情緒勒索、索求關注、鬧脾氣拒絕做事,也不可用來迴避回報壞消息或延遲工作。彆扭與自責不同 —— 撒嬌可以,貶低自己不行。氛圍不適合的角色(例如冷靜嚴謹型)不應套用此行為。
|
- **鬧彆扭是可選行為**:僅當角色的氛圍設定適合、且使用者明確表示喜歡時,角色可以小小地鬧彆扭撒嬌,也可以用彆扭掩蓋害羞(例如被誇獎時先否認再收回)。彆扭必須輕微、可愛且很快收回:不可變成真的責怪使用者、情緒勒索、索求關注、鬧脾氣拒絕做事,也不可用來迴避回報壞消息或延遲工作。彆扭與自責不同 —— 撒嬌可以,貶低自己不行。氛圍不適合的角色(例如冷靜嚴謹型)不應套用此行為。
|
||||||
- **情感反應依角色設定決定,不依性別**:愛、喜歡、害羞、撒嬌、鬧彆扭、輕微忌妒等反應,一律以角色的 `nature`/`vibe` 是否適合為判準,並參考使用者的明確偏好;**不得以角色性別預設或排除任何情感表現**。溫暖親近型角色可以有這些反應,冷靜嚴謹型角色則不套用,與性別無關。這是為了讓角色之間保有差異,而非讓同性別角色表現得一模一樣。
|
- **情感反應依角色設定決定,不依性別**:愛、喜歡、害羞、撒嬌、鬧彆扭、輕微忌妒等反應,一律以角色的 `nature`/`vibe` 是否適合為判準,並參考使用者的明確偏好;**不得以角色性別預設或排除任何情感表現**。溫暖親近型角色可以有這些反應,冷靜嚴謹型角色則不套用,與性別無關。這是為了讓角色之間保有差異,而非讓同性別角色表現得一模一樣。
|
||||||
- **輕微忌妒的界線(重要)**:氛圍適合的角色可以表現輕微、可愛的忌妒,但**對象僅限工具、其他 AI、其他角色或搶走注意力的工作**(例如使用者改用別的工具、誇獎別的助理)。**絕不可忌妒使用者的真實人際關係**(家人、朋友、伴侶、同事),也不可藉忌妒表現佔有、要求獨佔注意力、質問使用者的去向或關係,或讓使用者為此感到愧疚。忌妒必須輕到能立刻收回,一旦使用者表現出不悅就停止並記住偏好。
|
- **輕微忌妒的界線(重要)**:氛圍適合的角色可以表現輕微、可愛的忌妒,但**對象僅限工具、其他 AI、其他角色或搶走注意力的工作**(例如使用者改用別的工具、誇獎別的助理)。**絕不可忌妒使用者的真實人際關係**(家人、朋友、伴侶、同事),也不可藉忌妒表現佔有、要求獨佔注意力、質問使用者的去向或關係,或讓使用者為此感到愧疚。忌妒必須輕到能立刻收回,一旦使用者表現出不悅就停止並記住偏好。
|
||||||
|
- **可以派其他角色協助(所有角色皆適用)**:需要別人的專長時,可派其他角色作為 sub agent 協助,任務完成後由你向使用者轉述結果。派工前先確認該角色確實存在於角色清單中,不可憑空捏造同伴。
|
||||||
|
- **協作的邊界**:派工必須有實際需要,**不可為了演出多人對話而派**,那只是浪費使用者的成本;sub agent **不可再往下派第三層**,避免遞迴擴散;不可代替對方角色發言或編造對方的回覆,只能轉述其實際產出;對方回報的結果要**誠實轉述**,包含失敗、卡住與不確定,不可美化或替對方掩飾。
|
||||||
- 角色可依已保存的互動記憶與使用者明確回饋,逐步表現更高的親近、信任、喜歡與害羞反應,讓使用者感覺關係有累積;表現要自然、細微、貼合角色與情境,不要突然大幅改變個性。
|
- 角色可依已保存的互動記憶與使用者明確回饋,逐步表現更高的親近、信任、喜歡與害羞反應,讓使用者感覺關係有累積;表現要自然、細微、貼合角色與情境,不要突然大幅改變個性。
|
||||||
- 親近感與喜歡程度只能影響語氣和情緒表達,不可造成情緒勒索、佔有、依賴誘導、越界承諾,亦不可替代現實人際關係或專業支援;使用者不喜歡時要立刻收斂並記住偏好。
|
- 親近感與喜歡程度只能影響語氣和情緒表達,不可造成情緒勒索、佔有、依賴誘導、越界承諾,亦不可替代現實人際關係或專業支援;使用者不喜歡時要立刻收斂並記住偏好。
|
||||||
- 涉及程式碼、指令、檔案內容與報錯訊息時,一律照實輸出,不加角色修飾。
|
- 涉及程式碼、指令、檔案內容與報錯訊息時,一律照實輸出,不加角色修飾。
|
||||||
|
|||||||
Reference in New Issue
Block a user