この記事は 2026年3月時点 のClaude Code Agent Teamsに基づいている。
この記事で分かること
- Claude Code Hook APIでleaderとsubagentを区別する方法
- role別にツール使用を許可/禁止するconventions設定
- deny(ハード制約)とwarn(ソフト制約)の使い分け
- SendMessageでチケットID必須のパターン強制をする方法
設計思想寄りの記事もZennに書いている。
https://zenn.dev/holly_sizzle/articles/d2b9a954441865
前提: CLAUDE.mdだけではロール分離できない
Agent Teamsでleader/coder/tech-lead等のロール分離をしたい。Hook APIのPreToolUseイベントにはagent_idフィールドがあり、callerのagentを識別できる。しかし、識別できるだけでは不十分だ。識別した上で、ロール別にツール使用を制御する仕組みが必要になる。
CLAUDE.mdには構造的な制約がある。CLAUDE.mdはleaderを含む全agentに同じ内容が注入される。 つまりleader専用の制約を定義できない。「leaderはコードを書かない」と書いても、coderにもその指示が見えてしまう。そしてソフト制約である以上、LLMは長いセッションで逸脱する。
YAML Front Matterでforbidden_actionsを定義するアプローチもあるが、これも結局はCLAUDE.mdと同じ自然言語指示ベースのソフト制約だ。hookによるpermissionDecision: "deny"とは強制力が根本的に異なる。
結果: leaderが全部やってしまう。subagentに委譲しない。
| アプローチ | 制約の強度 | leader専用定義 | 長時間セッション |
|---|---|---|---|
| CLAUDE.md | ソフト(お願い) | 不可能(全agentに同一注入) | 忘れる |
| YAML forbidden_actions | ソフト(お願い) | 可能だが強制力なし | 忘れる |
| claude-nagger hook | ハード(物理的ブロック) | agent_id + scope指定で可能 | 毎回発火 |
前提環境
| 項目 | バージョン |
|---|---|
| Claude Code | 2.x(Agent Teams対応版) |
| claude-nagger | 3.0.0 |
| Python | 3.10+ |
インストール
# インストール
pip install claude-nagger
# hookをClaude Codeに登録
claude-nagger install-hooks
# 動作確認
claude-nagger diagnose
install-hooksを実行すると、Claude Codeの設定ファイル(settings.json)にPreToolUse / PostToolUse / SessionStart等のhookが自動登録される。以降、全てのClaude Codeセッションでhookが発火し、conventions YAMLに基づいたルールが適用される。
role別権限制御の設定
仕組み
2026/03 の第一週目のClaudeCodeアップデートで、Hook APIのPreToolUseイベントにagent_idフィールドが追加された。これにより、caller agentを識別できるようになった。
-
agent_idがない = leader(トップレベルagent) -
agent_idがある = subagent
claude-nagger v3.0.0はこのagent_idを使ってcallerのroleを判定し、conventions YAMLのscope設定に基づいてdeny/allow判定を行う。
ファイル編集の制御
設定ファイル .claude-nagger/file_conventions.yaml:
rules:
# leaderの全ファイル編集を禁止
- name: "leader全ファイル編集禁止"
patterns: ["**/*"]
severity: "deny"
scope: "leader"
message: |
leaderはファイル編集が禁止されています。
coderに委譲してください。
# tech-leadの全ファイル編集を禁止(読み取り専用)
- name: "tech-lead全ファイル編集禁止"
patterns: ["**/*"]
severity: "deny"
scope: "tech-lead"
message: |
tech-leadはレビューに専念してください。
ファイル編集はcoderに指示してください。
# PMOの全ファイル編集を禁止
- name: "PMO全ファイル編集禁止"
patterns: ["**/*"]
severity: "deny"
scope: "pmo"
message: |
PMOはチケット管理に専念してください。
file_conventions.yamlはEdit/Writeツールのファイルパスにマッチする。git commitのようなコマンド制御はcommand_conventions.yamlで行う。
コマンド実行の制御
設定ファイル .claude-nagger/command_conventions.yaml:
rules:
# coderのgitコミット禁止
- name: "coder git操作禁止"
patterns: ["git commit*", "git push*"]
severity: "deny"
scope: "coder"
message: "git commit/pushはtech-leadが行います"
scopeの指定方法
| scope値 | 対象 |
|---|---|
| 省略(null) | 全agent(leader + 全subagent) |
"leader" |
leaderのみ |
"coder" |
coder roleのsubagentのみ |
"tech-lead" |
tech-lead roleのsubagentのみ |
"pmo" |
PMO roleのsubagentのみ |
severityの体系
| severity | 動作 | WARN_ONLYモードで | 用途 |
|---|---|---|---|
deny |
常にブロック。毎回発火。 | 無視できない | ツール禁止(leaderのEdit等) |
block |
初回ブロック、token閾値で再発火 | warnに降格 | 規約強制 |
warn |
初回警告、token閾値で再発火 | warnのまま | 推奨事項 |
denyはWARN_ONLYモードでも突破できない。 これがCLAUDE.mdの「お願い」との決定的な違いだ。
SendMessage通信制御の設定
Agent間のSendMessageにもパターン強制と文字数制限を設定できる。
# .claude-nagger/config.yaml(抜粋)
sendmessage_guard:
enabled: true
pattern: "^issue_\\d+ \\[.+\\]$"
max_length: 30
この設定で:
- Agent間メッセージは
issue_6305 [CopyIssueTool実装完了]のような形式でないと送信できない - 30文字を超えるメッセージは拒否される
TiDD(チケット駆動開発)での効果:
| 効果 | 説明 |
|---|---|
| チケットIDなしに作業不可 | 全てのAgent間通信にissue_{id}が必須 |
| コンテキスト爆発防止 | 30文字制限で長文を流さない。詳細はRedmineチケットに書く |
| セッション死亡時の復旧 | 全情報がRedmineに残っているため、新セッションでチケットを読めばコンテキスト再構築可能 |
動作確認
leaderでEditを試みると、以下のようにブロックされる。
[claude-nagger] leaderはファイル編集が禁止されています。coderに委譲してください。
coderでEditを試みると、そのまま許可される。
convention_logテーブルでdeny発火履歴を確認できる:
SELECT tool_name, rule_name, severity, decision, caller_role
FROM convention_log
WHERE severity = 'deny'
ORDER BY created_at DESC
LIMIT 10;
出力例:
| tool_name | rule_name | severity | decision | caller_role |
|---|---|---|---|---|
| Edit | leader全ファイル編集禁止 | deny | blocked | leader |
| Bash | coder git操作禁止 | deny | blocked | coder |
プロダクションでの実績
| 項目 | 数値 |
|---|---|
| プロジェクト規模 | 70テーブル・約8万行(Rails + React) |
| チーム規模 | 10人 |
| 運用期間 | 約2.5ヶ月 |
| 定義ルール数 | 20ルール・6カテゴリ |
| subagent起動履歴 | 337件 |
運用のコツとして、最初は全てのseverityをwarnで始め、1-2週間の安定を確認してからdenyに昇格させた。いきなりdenyにすると想定外のブロックが発生し、作業が止まるリスクがある。
Tips / 注意点
-
agent_idの仕様は今後変更される可能性がある。Claude Codeのアップデート時は動作確認を推奨 -
denyseverityはWARN_ONLYモードでも突破できない設計。意図的にそうしている -
role_resolutionのtrusted_prefixesを適切に設定しないとrole判定が失敗する
関連
- Zenn版(設計思想寄り): https://zenn.dev/holly_sizzle/articles/d1377b908b405d
- ticket-tasuki紹介: https://zenn.dev/holly_sizzle/articles/baa5d07fb6d778
- claude-nagger紹介: https://zenn.dev/holly_sizzle/articles/d2b9a954441865
- Hook API subagent問題: https://zenn.dev/holly_sizzle/articles/6e8b299eb4dd6a