Claude Code Subagentでコードレビュー専任AIを作る記事のサムネイル

最近、「Claude Code Subagent」機能が注目されていますね!どうやら、「Claude Code Subagent」を使うと、実装作業を行うメインエージェントとは完全に別に、コードレビューだけを行う専任AIを作れて、しかもそのAIにファイル編集権限を持たせずに安全に運用できるようです!

そこで今回は、Claude Code環境で「Claude Code Subagent」のYAML定義とツール権限制限の実装を行ってみました!公式ドキュメントを読まなくても本文だけで再現できる内容ですので、ぜひ皆さんも記事を読んで試してみてください!

この記事で分かること

  • Claude Code Subagentとメインエージェントの違い、コンテキスト分離の仕組み
  • .claude/agents/配下でのYAML定義の書き方とツール権限の制限方法
  • PostToolUse Hookと組み合わせた自動レビュートリガーの構築方法

Claude Code Subagentとは何か

Claude Code Subagentとは、メインの会話(メインエージェント)とは独立したコンテキストウィンドウを持ち、特定タスクだけを処理する専用AIインスタンスのことです。メインエージェントがタスクをSubagentに委譲すると、Subagentは自分専用のコンテキストで作業を完結させ、結果の要約だけをメインエージェントに返します。この仕組みにより、大量のログや差分がメインの会話履歴を圧迫することを防げます。

コンテキスト分離とは

Claude Code Subagentの最大の特徴は、会話履歴・既読ファイル・過去のツール呼び出し結果をメインエージェントから一切継承しないことです。Subagentが受け取るのは、システムプロンプト(YAML定義のMarkdown本文)、委譲時のタスクメッセージ、CLAUDE.mdなどのメモリ階層、Gitステータスのスナップショットのみです。実装コードの詳細やデバッグ試行の履歴はSubagentに渡らないため、レビューという別の視点をクリーンな状態で実行できます。

メインエージェントとの違い(比較表)

メインエージェントとClaude Code Subagentの違いを、コンテキスト分離の観点で整理すると以下のようになります。

項目メインエージェントClaude Code Subagent
コンテキストウィンドウ会話全体を保持し続けるタスクごとに新規かつ分離
システムプロンプトClaude Codeの完全なシステムプロンプトYAML定義のMarkdown本文のみ
ツール権限設定次第で全ツール継承toolsフィールドで個別に制限可能
返却されるもの実行結果そのもの要約された結果のみ
モデルセッション全体で固定modelフィールドで個別指定可能(Haiku等も可)

組み込みSubagentとカスタムSubagentの違い

Claude CodeにはExplore、Plan、general-purposeといった組み込みSubagentが標準で用意されていますが、これらはツール制限のパターンが固定されています。今回のコードレビュー専任AIのように、「Read/Grep/Globのみ許可、Write/Edit禁止」という独自のツール権限を細かく設計したい場合は、.claude/agents/配下にYAML定義を自分で書くカスタムSubagentを作成する必要があります。

レビューを専任Subagentに分離すべき理由

単一エージェントに実装とレビューを任せる技術的リスク

同一のメインエージェントに実装とレビューの両方を任せると、直前に自分が書いたコードの意図をそのまま正当化する傾向が生じます。これは会話コンテキストに実装時の設計判断・試行錯誤・エラー処理の履歴が全て残っているためで、レビュー時にも同じ文脈で思考が継続し、客観的な指摘が生まれにくくなります。Claude Code Subagentとして完全に独立したコンテキストでレビューを実行すれば、実装時の前提や思い込みを引き継がずにゼロから評価できます。

コンテキスト汚染とレビュー精度の低下

メインエージェントの会話には、実装過程で発生した無数のデバッグログやツール呼び出し結果が蓄積されています。この長大なコンテキストの中でレビューを行うと、注意すべき箇所の情報が埋もれてしまい、重要な指摘が漏れる原因になります。Claude Code Subagentに切り出すことで、レビュー対象のコード(あるいはPR差分)だけに集中した短いコンテキストで判断できるため、精度が安定します。

ツール権限によるガードレールの必要性

レビュー専任のClaude Code Subagentに実装権限(Write/Edit)を残しておくと、レビュー中に「ついでに直しておきます」という形で無断修正が発生するリスクがあります。ツール権限をYAML定義のtoolsフィールドで明示的にRead/Grep/Globのみに絞ることで、Subagentは物理的にファイルを変更できなくなり、レビュー結果の提示にしか行動できません。これは運用ルールの申し送りではなく、システムレベルでの強制であるため、人間側の見落としに依存しない安全設計になります。

.claude/agents/配下のYAML定義実装手順

手順1:ファイル配置とスコープの選択

プロジェクト単位でチームと共有したいので、プロジェクトスコープの.claude/agents/にファイルを作成します。ファイル名はSubagentの識別名と一致していなくても構いませんが、管理のためにname値と合わせておきます。

# ファイル名: setup.sh
mkdir -p .claude/agents
touch .claude/agents/code-reviewer.md

手順2:フロントマター全項目の実装

YAML定義のフロントマターに、必須項目であるnameとdescriptionに加え、tools、model、color、permissionModeを明示的に指定します。toolsには許可するツール名のみを列挙し、リストにないツールは自動的に使用不可になります。

# ファイル名: .claude/agents/code-reviewer.md(フロントマター部分)
---
name: code-reviewer
description: >
  コード変更の品質・セキュリティ・可読性をレビューする専任エージェント。
  実装完了後、または明示的にレビューを依頼された場合に使用する。
  ファイルの編集や書き込みは行わず、指摘事項のみを返す。
tools: Read, Grep, Glob
model: sonnet
color: blue
permissionMode: default
maxTurns: 20
---

ここで重要なのはtools: Read, Grep, Globという指定です。これによりWrite/Editツールはリストに含まれないため、このClaude Code Subagentはファイルを一切変更できません。disallowedToolsフィールドで明示的にWrite/Editを拒否リストに入れる方法もありますが、今回は許可リスト方式のほうが「許可した3つ以外は全て禁止」という意図が明確になるため採用しています。

手順3:system prompt本文の実装

フロントマターの直後にMarkdown本文を書くと、それがそのままSubagentのシステムプロンプトになります。レビュー観点・出力フォーマット・禁止事項を具体的に指示します。

# ファイル名: .claude/agents/code-reviewer.md(本文部分)
あなたはシニアレベルのコードレビュー専任AIです。
実装や修正は一切行わず、Read・Grep・Globツールのみを使って
コードを読み取り、以下の観点でレビューしてください。

## レビュー観点
1. ロジックの正確性(境界値、null/undefined処理、例外処理)
2. セキュリティ(インジェクション、認証・認可の不備、機密情報の露出)
3. 可読性・命名・重複コード
4. パフォーマンス(不要なループ、N+1、過剰なメモリ使用)

## 出力フォーマット
各指摘は以下の形式で出力してください。

- ファイルパスと行番号
- 重要度(Critical / Warning / Suggestion)
- 問題点の説明
- 改善案(コードスニペットで提示。ただし自分では書き込まない)

## 禁止事項
- ファイルの編集・作成・削除は絶対に行わない
- コマンド実行(Bash)は使用しない
- レビュー対象外のファイルには言及しない

このYAML定義を保存した時点でカスタムClaude Code Subagentの実装は完了です。手動作成のファイルはセッション開始時に読み込まれるため、既存セッションで反映させるには一度再起動する必要があります。

実践パターン3種

パターン1:PR差分のみを渡すレビュー専任Subagent

PR全体ではなく差分のみをレビュー対象にすることで、Claude Code Subagentのコンテキストをさらに軽量化できます。

# ファイル名: .claude/agents/diff-reviewer.md
---
name: diff-reviewer
description: >
  git diffの範囲のみをレビューする軽量Subagent。
  「差分をレビューして」と依頼された場合に使用する。
tools: Read, Grep, Glob, Bash(git diff *)
model: haiku
color: green
---

あなたは差分専任のレビューアです。
git diffで取得した変更範囲のみを対象にレビューしてください。
差分に含まれないファイルは読み取っても指摘対象にしないでください。
出力は「変更箇所」「リスク」「改善提案」の3項目で簡潔にまとめます。

動作原理
toolsフィールドにBash(git diff *)という許可リスト構文を指定することで、Bashツール自体は使えるものの、git diff以外のサブコマンドは実行できません。これはツール権限を「ツール単位」ではなく「引数パターン単位」で制限する構文で、YAML定義内だけでガードレールを完結させられます。

# ターミナル出力例
> diff-reviewer subagentでこのブランチの差分をレビューして

[diff-reviewer] git diff main...HEAD を実行中
[diff-reviewer] 変更ファイル: src/auth/login.ts, src/utils/token.ts

変更箇所:
  src/auth/login.ts:42-58 トークン検証ロジックを追加
リスク:
  Critical: トークンの有効期限チェックが検証フローの外側にあり、
  期限切れトークンでも一部処理が先行実行される可能性があります。
改善提案:
  期限チェックをtry-catchの最初に移動し、早期returnで処理してください。

パターン2:セキュリティ観点のみをチェックするSubagent

レビュー範囲を意図的に絞ることで、Claude Code Subagentの判断がぶれにくくなります。

# ファイル名: .claude/agents/security-reviewer.md
---
name: security-reviewer
description: >
  セキュリティ観点のみをチェックする専任Subagent。
  認証・認可・入力値検証・機密情報の扱いに絞ってレビューする。
tools: Read, Grep, Glob
model: sonnet
color: red
---

あなたはセキュリティレビュー専任エージェントです。
以下の項目にのみ焦点を当ててチェックしてください。
- SQLインジェクション、XSS、コマンドインジェクション
- 認証・認可のバイパス可能性
- APIキーやシークレットのハードコーディング
- 入力値検証の欠落
コードスタイルや可読性については言及しないでください。

動作原理
tools権限をRead/Grep/Globのみに絞りつつ、システムプロンプトでレビュー観点を「セキュリティのみ」に限定することで、Claude Code Subagentは可読性やパフォーマンスといった別軸の指摘を出さなくなります。観点を絞るほど、YAML定義1つあたりの判断基準が明確になり、誤検知が減ります。

# ターミナル出力例
> security-reviewer subagentでAPI周りをチェックして

[security-reviewer] Grepで "process.env" "apiKey" "SELECT" を検索中
[security-reviewer] 対象: src/api/payment.ts

Critical: src/api/payment.ts:12
  APIキーがコード内に直接記述されています。
  環境変数経由(process.env.PAYMENT_API_KEY)への変更を推奨します。

Warning: src/api/payment.ts:34
  ユーザー入力をそのままSQLクエリに埋め込んでいます。
  パラメータ化クエリへの変更が必要です。

パターン3:メインエージェントからのTask tool呼び出し実例

メインエージェントが実装を完了した後、自然言語でClaude Code Subagentを明示的に呼び出す実例です。

# メインエージェントへの指示例
Use the code-reviewer subagent to review the changes I just made in src/auth/

動作原理
メインエージェントはこの指示を受けると、Agentツール(旧Task tool)を使ってcode-reviewer Subagentを起動します。この際、メインエージェントは対象ファイルパスや変更概要を要約した委譲メッセージを自動生成してSubagentに渡します。Subagentはこの委譲メッセージとYAML定義の指示のみを頼りに動作し、メインエージェントの会話履歴そのものは参照できません。

# ターミナル出力例
> Use the code-reviewer subagent to review the changes I just made in src/auth/

[main] code-reviewer subagentに委譲します
[code-reviewer] Read/Grep/Globでsrc/auth/配下を調査中
[code-reviewer] レビュー完了、結果をメインエージェントへ返却

--- レビュー結果 ---
Warning: src/auth/session.ts:20
  セッションタイムアウトの単位がミリ秒と秒で混在しています。
Suggestion: src/auth/session.ts:45
  関数名refreshTokenIfNeededはisTokenExpiredに分離すると責務が明確になります。

よくある失敗と対処法

権限不足エラーの原因と対処

Claude Code Subagentがコマンド実行やファイル書き込みを試みて拒否される場合、ツール権限のYAML定義に該当ツールが含まれていないことが原因です。エラーメッセージには通常「このエージェントは許可されたタイプのみ表示します」といった趣旨の内容が出力されるため、まず該当Subagentのtoolsフィールドを確認します。

# ファイル名: debug-permission.sh
cat .claude/agents/code-reviewer.md | head -n 12

Write/Edit禁止を意図的に設定している場合、このエラーは正常な動作です。対処としては、レビュー専任Subagentに書き込み権限を与えるのではなく、指摘結果をメインエージェント側でEdit/Writeツールを使って反映する運用に戻すのが正しい設計です。

コンテキストが渡らないケースのデバッグ手順

「レビュー対象のファイルを認識していない」という失敗は、委譲メッセージに具体的なパスが含まれていないことが原因であることが多いです。Claude Code Subagentは会話履歴を継承しないため、メインエージェントが「さっき編集したファイル」のような曖昧な指示しか渡していないと、Subagent側は探索から始めることになりコンテキストが不足します。

# 対処前(曖昧な委譲)
Use the code-reviewer subagent to check my changes

# 対処後(明示的なパス指定)
Use the code-reviewer subagent to review src/auth/login.ts and src/auth/session.ts

デバッグ手順としては、まず/agentsコマンドでSubagentの設定内容とツール権限の割り当てを再確認し、次に委譲プロンプトに具体的なファイルパスやgit diffの範囲を明示的に含めることで、多くのケースが解決します。

Hooksと組み合わせた自動レビュートリガー

PostToolUse Hookからの自動起動設定

Editツールでファイルが変更されるたびに自動でレビューを走らせたい場合、PostToolUse Hookと組み合わせます。Hookはシェルコマンドの実行までしか行えないため、実際にはHookからClaude Code CLIを非対話モードで呼び出し、Subagentのシステムプロンプトをそのまま使う構成にします。

// ファイル名: .claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/trigger-review.sh"
          }
        ]
      }
    ]
  }
}
# ファイル名: .claude/hooks/trigger-review.sh
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [[ -z "$FILE_PATH" ]]; then
  exit 0
fi

# code-reviewer Subagentのシステムプロンプトを使って非対話レビューを実行
claude -p --agent code-reviewer "review the file $FILE_PATH" >> .claude/review-log.txt

exit 0

このYAML定義(--agent code-reviewer)を非対話モードで指定することで、メインセッションのシステムプロンプトを完全に置き換えてSubagent専用のツール権限のみが適用された状態でレビューが実行されます。Write/Editが禁止されているため、Hook経由で自動起動しても誤ってファイルが書き換えられる心配はありません。

動作フローとターミナル出力例

実際にファイルを編集すると、PostToolUse HookがバックグラウンドでClaude Code Subagentを起動し、レビュー結果がログファイルに蓄積されていく流れになります。

# ターミナル出力例
> src/api/payment.tsをEditツールで編集完了

[hook:PostToolUse] Edit検知 → trigger-review.sh実行
[hook] code-reviewer subagentを非対話モードで起動
[code-reviewer] Read/Grep/Globのみでsrc/api/payment.tsを解析中
[hook] .claude/review-log.txt に結果を追記しました

$ tail -n 6 .claude/review-log.txt
Critical: src/api/payment.ts:12
  APIキーがハードコーディングされています。環境変数化を推奨します。
Suggestion: src/api/payment.ts:30
  例外処理のcatchブロックでエラー内容をログに残していません。