TwKit
正在载入
TwKit

給 AI 立規矩沒用,給它裝一個「執法者」才有用 分工先說清 CLAUDE.md 是告訴 Claude Code 該做什麼;子智能體、hooks 和斜槓命令… · @swordBluesy · TwKit

@swordBluesy

給 AI 立規矩沒用,給它裝一個「執法者」才有用 分工先說清 CLAUDE.md 是告訴 Claude Code 該做什麼;子智能體、hooks 和斜槓命令,是讓它真的照做的機制:帶著有限工具的專職審查員、用 shell 腳本強制執行的規則(而不是指望模型記得)、以及一個詞觸發的固定工作流。這篇給的是一套能直接抄的配置。 子智能體:一個文件一個專員 子智能體就是 .claude/agents/ 裡的一個 Markdown 文件,頭部 YAML 寫三樣:name;description——它決定 Claude 何時派活,想讓它被主動調用就寫「Use PROACTIVELY after…」這類措辭;可選的 tools 工具清單。每個子智能體在自己全新的上下文裡跑,不污染主對話,也看不到主對話——派活時要把確切的文件和目標交給它。 三條紀律:最小權限,審查員和安全審計員只給 Read, Grep, Glob,它不能編輯,就不可能「順手」改了你沒讓改的東西;一人一職,規劃、代碼審查、寫測試、調試、安全審計、寫文檔這六個角色覆蓋大多數團隊;輸出要立約,「按 MUST / SHOULD / NIT 分級、帶 path:line 報告」遠勝「幫我看看代碼」。個人用的放 ~/.claude/agents/,在會話裡用 /agents 管理。 Hooks:模型跳不過的規則 Hooks 住在 .claude/settings.json 的 "hooks" 裡。每個事件(PreToolUse、PostToolUse、Stop 等)配一個按工具名匹配的 matcher(如 Bash、Edit|Write)和一條命令;hook 從 stdin 拿到這次工具調用的 JSON。退出碼 2 就是攔截,並把你的 stderr 發回去給 Claude 看;退出 0 是放行;其他退出碼是非阻斷錯誤,只展示給你。 作者的四個標配: PreToolUse 匹配 Bash:攔 rm -rf、git push --force、git reset --hard、curl | sh、直推 main。 PreToolUse 匹配 Read|Edit|Write:拒碰 .env、*.pem 和鎖文件,但放行 .env.example。 PostToolUse 匹配 Edit|Write:對剛改的文件跑格式化,這裡永遠不要攔截。 Stop:代碼有改動就跑測試,失敗用退出碼 2 讓 Claude 繼續幹;記得檢查 stop_hook_active 防死循環。 再加兩條安全紀律:hooks 是用你本人的權限跑的,啟用前每條腳本都要讀過;腳本要進版本控制。同文件裡的 permissions.deny 再配一層,雙保險。 免費腳本:危險命令攔截器(可直接抄) #!/usr/bin/env bash # PreToolUse (matcher: Bash). Exit 2 = block; stderr is shown to Claude. cmd=$(jq -r '.tool_input.command // ""') deny=( 'rm -rf /' 'rm -rf ~' 'rm -rf \*' 'rm -rf \.' 'git push --force' 'git push -f' 'git reset --hard' 'git clean -fd' 'DROP DATABASE' 'DROP TABLE' 'TRUNCATE ' 'supabase db reset' 'prisma migrate reset' 'alembic downgrade base' 'chmod -R 777' 'mkfs' 'dd if=' ':(){' ) for p in "${deny[@]}"; do if printf '%s' "$cmd" | grep -qiF -- "${p//\\/}"; then echo "Blocked by .claude/hooks/block-dangerous-bash.sh: '$p' is destructive. Explain why it's needed and ask the human to run it." >&2 exit 2 fi done if printf '%s' "$cmd" | grep -qE '(curl|wget)[^|]*\|\s*(ba|z)?sh'; then echo "Blocked: piping a download into a shell. Download, inspect, then ask." >&2; exit 2 fi if printf '%s' "$cmd" | grep -qE 'git push[^&;|]*\b(main|master)\b'; then echo "Blocked: pushing to main/master. Push a branch and open a PR." >&2; exit 2 fi exit 0 看清它的設計:攔截時不光是拒絕,還把「為什麼攔、該怎麼辦」寫進 stderr 餵回給 Claude——讓模型自己向人類解釋並請求人工執行。下載管道直通 shell 的、直推主分支的,各有一條專門規則。 斜槓命令:把流水線封成一個詞 .claude/commands/ 裡每個文件就是一個 /文件名 命令;正文裡用 $ARGUMENTS 接你命令後面打的字,頭部可寫 description、argument-hint、allowed-tools。好的命令是會串子智能體的,比如 /feature = 規劃 → 實現 → 寫測試 → 跑測試 → 代碼審查 → 總結,一條龍。 S1哥觀點 這篇的核心洞察就一句:寫進提示詞的規矩是請求,寫進 hook 的規矩是法律。 模型會忘、會「理解偏差」、會在長上下文裡把你的禁令滑過去;shell 腳本不會——退出碼 2 擺在那裡,過不去就是過不去。把「不許直推 main」從 CLAUDE.md 的一句話,變成一道攔得住的閘,這才是把智能體放進生產環境的正確姿勢。 當然也有反方觀點:攔得太死,智能體動不動就停下來問人,效率優勢蕩然無存。我認為分寸在於只攔「不可逆」的那一類——刪庫、強推、格式化磁碟這一檔;格式、命名這種可逆的小事,讓它去。你的攔截清單裡第一條會寫什麼?評論區交換一下各自的黑名單。 原文連結:https://dev.to/eli_agentkit/claude-code-subagents-hooks-and-slash-commands-a-working-setup-34b5 原文:@eli_agentkit(由 S1哥 編譯)

曝光 32 · 评论 0 · 点赞 0 · 书签 0

查看原帖