📁GitHubにコード公開: tf_claudecode02
シリーズ記事一覧
- 第1回:Skills比較
- 第2回:サブエージェント活用
- 第3回:Skillsインストール&実践
- 第4回:CLAUDE.mdカスタムルール
- 第5回:カスタムサブエージェント自作
- 第6回:カスタムエージェント&Agent Teams
📑 目次
- この記事について
- この記事のゴール
- 前提知識:3つのエージェント機能
- 前提条件
- 前半 Step 1:カスタムエージェントを定義する
- 前半 Step 2:カスタムエージェントを呼び出す
- 後半 Step 3:Agent Teams でチームを編成する
- 後半 Step 4:チーム開発の結果を確認する
- 体験して分かったこと
- まとめ
1. この記事について
1-1. シリーズの位置づけ
本記事は「Terraform × Claude Code」シリーズの最終回(第6回)です。
| 記事 | サブタイトル | 状態 |
|---|---|---|
| 01 | Skills比較|4つの公開スキルを調べて分かった最適な組み合わせ | ✅実施済み |
| 02 | サブエージェント活用|並列調査で01記事の数値を裏付け検証してみた | ✅実施済み |
| 03 | Skillsインストール&実践|コード生成の品質がどう変わるか検証してみた | ✅実施済み |
| 04 | CLAUDE.mdカスタムルール|チーム独自のルールをAIに教えてみた | ✅実施済み |
| 05 | カスタムサブエージェント自作|AIにコードレビューさせたら意外な発見 | ✅実施済み |
| 06 | カスタムエージェント&Agent Teams|AI開発チームを編成してみた(本記事) | 📝本記事 |
1-2. なぜこの記事を書いたか?
05記事で、
2つのサブエージェント(ルール準拠チェッカーとベストプラクティス監査)を自作しました。
しかし、
毎回プロンプトを全文書く必要がありました。
「レビューするたびに同じプロンプトをコピペするのか?」
この疑問に答えるのが カスタムエージェント です。
プロンプトをファイルに保存して、一言で呼び出せるようにします。
さらにもう1つ、
05記事には残された課題がありました。
skills-auditor は多くの問題を見つけましたが、
修正は別作業 でした。
「レビューで見つけた問題を、チームで一気に直せないか?」
この課題に答えるのが Agent Teams です。
複数のエージェントを「チーム」として編成し、
依存関係を管理しながら並列開発させます。
1-3. 06記事の方針
| 項目 | 方針 |
|---|---|
| 前半 | カスタムエージェント(05のサブエージェントをファイル永続化) |
| 後半 | Agent Teams(マルチモジュール並列開発) |
| 対象コード | 04記事で生成されたコード(iac_04/)を iac_06/ として再構築 |
| 連続性 | 04で作って、05で問題を見つけて、06で直す |
1-4. 対象読者
- 05記事でサブエージェントの自作を学んだ方
- 毎回プロンプトを書くのが面倒だと感じている方
- 複数エージェントの協調作業に興味がある方
2. この記事のゴール
| # | ゴール |
|---|---|
| ① | カスタムエージェントの定義・呼び出しができる |
| ② | Agent Teams でチームを編成し、依存関係付きの並列開発ができる |
| ③ | サブエージェント・カスタムエージェント・Agent Teams の違いを理解できる |
3. 前提知識:3つのエージェント機能
3-1. 学習ステップの全体像
本シリーズでは、エージェント機能を4段階で学んできました。
Step 1: サブエージェント(組み込み型) ← 02記事 ✅
Step 2: カスタムサブエージェント(アドホック) ← 05記事 ✅
Step 3: カスタムエージェント(ファイル永続化) ← 本記事・前半
Step 4: Agent Teams(双方向チーム) ← 本記事・後半
3-2. 3つの仕組みの関係
| 比較 | サブエージェント | カスタムエージェント | Agent Teams |
|---|---|---|---|
| 定義場所 | Task の prompt に直接記述 |
.claude/agents/ のファイル |
TeamCreate で動的作成 |
| 呼び出し | 毎回プロンプト全文を書く | 一言で呼べる | チームメンバーとして自動起動 |
| 通信 | 一方通行(結果を返すのみ) | 一方通行(同じ) | 双方向(SendMessage) |
| 再利用 | コピペで共有 | Git で管理・チーム共有 | セッションごとに作成 |
| 依存管理 | なし | なし | タスク依存グラフ |
| 用途 | 調査・レビュー | 調査・レビュー(再利用可能) | 並列開発・チーム作業 |
ポイントは2つです。
-
サブエージェント → カスタムエージェント は 同じ仕組みの進化形 です。
毎回書いていたプロンプトをファイルに保存するだけです。 -
サブエージェント → Agent Teams は 別の仕組み です。
一方通行の「親子関係」ではなく、対等なメンバーが双方向に会話します。
4. 前提条件
4-1. 環境
| 項目 | バージョン |
|---|---|
| Claude Code | v2.1.50 |
| Claude モデル | Opus 4.6 |
| Skills | antonbabenko/terraform-skill |
| Terraform | >= 1.3.0 |
4-2. 04記事のコードが存在すること
04記事で
CLAUDE.md のルール A〜E に従って生成されたコードが iac_04/ にあること。
本記事では
iac_04/ のコードをレビュー(前半)し、
Agent Teams で iac_06/ として再構築(後半)します。
4-3. Agent Teams の有効化
Agent Teams は実験的機能です。
~/.claude/settings.json に以下を追加して有効化します。
{
"env": {
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
}
}
5. 前半 Step 1:カスタムエージェントを定義する
5-1. 目的
05記事で作った2つのサブエージェント(ルール準拠チェッカー、ベストプラクティス監査)を .claude/agents/ にファイル化します。
5-2. ファイル構成
iac_06/
├── .claude/
│ └── agents/
│ ├── rule-checker.md ← ルール準拠チェッカー
│ └── skills-auditor.md ← ベストプラクティス監査
├── CLAUDE.md
├── main.tf
└── ...
5-3. rule-checker.md の定義
---
name: rule-checker
description: CLAUDE.md ルール準拠チェッカー。Terraform コードが
チームルール A〜E を守っているか検証する。
tools:
- Read
- Glob
- Grep
- Bash
model: sonnet
---
あなたは Terraform コードレビュアーです。
以下のルール A〜E に対して、生成されたコードが準拠しているか
チェックしてください。
## チェック対象
カレントディレクトリ配下の全 `.tf` ファイルを対象にしてください。
`modules/` 配下も含めて再帰的に読んでください。
## チェックするルール
### A. 必須タグ
全てのリソースに以下の3つのタグが付与されているか?
- Project(var.project)
- Owner(var.owner)
- CostCenter(var.cost_center)
locals でマージする方式が使われているか?
(B〜E も同様に定義)
## 出力形式
各ルールについて以下の形式で報告してください:
- 判定: ✅ 準拠 / ⚠️ 一部不備 / ❌ 未準拠
- 根拠: 具体的なファイル名と行番号を示す
- 改善提案: 不備がある場合のみ
最後に総合スコア(5点満点)を付けてください。
5-4. ファイル構成のポイント
| 要素 | 説明 |
|---|---|
| YAML フロントマター |
name, description, tools, model を定義する |
| tools の制限 | Read, Glob, Grep, Bash のみ。 Edit や Write は不要(レビュー専用) |
| model: sonnet | レビューには高速な Sonnet で十分。 コスト削減にもなる |
| チェック対象を汎用化 | 05記事ではフルパスを指定していたが、「カレントディレクトリ配下」に変更。 どのプロジェクトでも使える |
5-5. 05記事(アドホック版)との違い
| 比較 | 05記事(アドホック) | 06記事(ファイル永続化) |
|---|---|---|
| 定義場所 | Task の prompt に直接記述 | .claude/agents/rule-checker.md |
| 再利用 | 毎回プロンプトを書く | ファイルがあれば何度でも呼び出し可能 |
| チェック対象 | フルパスでファイルを列挙 | 「カレントディレクトリ配下」で汎用的に |
| 共有 | コピペで共有 | Git にコミットしてチーム共有 |
6. 前半 Step 2:カスタムエージェントを呼び出す
6-1. エージェントの認識確認
Claude Code のセッション内で
/agents コマンドを実行すると、定義したカスタムエージェントが表示されます。
❯ /agents
Project agents (/home/ub/.../iac_06/.claude/agents)
rule-checker · sonnet
skills-auditor · sonnet
Built-in agents (always available)
Bash · inherit
Explore · haiku
general-purpose · inherit
Plan · inherit
...
Project agents として
rule-checker と skills-auditor が認識されています。
6-2. 呼び出し方
05記事では長いプロンプト全文を書いていましたが、カスタムエージェントなら一言です。
❯ rule-checker でこのプロジェクトのコードをレビューして
Claude は自動的に
rule-checker カスタムエージェントを Task ツールで起動します。
6-3. 実行結果
2つのカスタムエージェントを順番に実行しました。
| エージェント | 結果 | 所要時間 |
|---|---|---|
| rule-checker | 5/5 完全準拠 | 1m 58s |
| skills-auditor | 60/100(改善推奨) | 1m 45s |
rule-checker の結果:
| ルール | 判定 | 概要 |
|---|---|---|
| A. 必須タグ | ✅ 準拠 | locals.tf で common_tags を定義し、全リソースに merge() で付与済み |
| B. リソース命名規則 | ✅ 準拠 | 全 Name タグが {project}-{env}-{種別} 形式 |
| C. S3 バケットポリシー | ✅ 準拠 | var.allowed_role_arn のみ許可。 パブリックアクセスブロックも設定済み |
| D. SG description | ✅ 準拠 | SG 本体・ingress・egress 全て日本語 |
| E. コード品質チェック | ✅ 準拠 | terraform fmt / validate ともに成功 |
skills-auditor の主な指摘:
| # | 観点 | 問題 | 影響度 |
|---|---|---|---|
| 1 | バージョン制約 |
>= 1.0.0 → ~> 1.9 に変更推奨 |
高 |
| 2 | 変数バリデーション | env, CIDR, ARN に validation 未設定 | 高 |
| 3 | for_each vs count | サブネットで count 使用。 削除・再作成リスク |
高 |
| 4 | SSH ingress |
[0] のみ使用。for_each で全 CIDR を適用すべき |
中 |
6-4. 発見:同セッション内のクロスリファレンス
面白い発見がありました。
skills-auditor の結果報告の末尾に、こう書かれていました。
rule-checker では全ルール準拠 (5/5) でしたが、
skills-auditor の観点では、
バージョン制約・変数バリデーション・count vs for_each に改善余地があります。
05記事のアドホック版では、
2つのサブエージェントは互いの結果を知りませんでした(コンテキスト分離)。
しかし今回は
同セッション内で順番に実行 したため、
メインの Claude が rule-checker の結果を保持しており、
skills-auditor の結果報告にそれが反映されました。
これは カスタムエージェントのファイル永続化 とは直接関係なく、
呼び出し方の違い(並列 vs 順次)から生まれた挙動です。
記事の実験としては想定外でしたが、
「AI の文脈理解が自然に働く」一例として興味深い発見でした。
7. 後半 Step 3:Agent Teams でチームを編成する
7-1. 目的
skills-auditor が見つけた問題を、チームで一気に直します。
04記事では1つのセッションで
S3/EC2/VPC を統合的に生成しましたが、今回は3つのエージェントに分担させます。
7-2. チーム構成
| メンバー | 担当 | 依存関係 |
|---|---|---|
| team-lead | 全体統括・タスク割り当て・ルートモジュール統合 | — |
| vpc-builder | VPC/サブネット/NAT Gateway(count → for_each 移行) | なし |
| s3-builder | S3バケット/ポリシー(モジュール化) | なし |
| ec2-builder | EC2/セキュリティグループ(モジュール化) | vpc-builder 完了待ち |
ec2-builder は
VPC のサブネット ID とセキュリティグループが必要なため、vpc-builder の完了を待ちます。
7-3. プロンプト
以下のプロンプトを Claude Code に入力しました。
Terraform のマルチモジュール並列開発をしたい。
Agent Teams を使って以下のチームを作ってほしい:
1. vpc-builder: modules/vpc/ 配下の VPC/サブネット/NAT Gateway を構築
2. s3-builder: S3バケット/ポリシーを構築
3. ec2-builder: EC2/セキュリティグループを構築(VPCのサブネットIDとSGが必要)
CLAUDE.md のルール A〜E に従って、共有タスクリストで依存関係を管理してほしい。
7-4. Claude が行った動作
プロンプト1つで、以下が自動的に行われました。
7-5. 依存関係の自動管理
Agent Teams の最大の特徴は、タスクの依存関係を自動管理 することです。
実行中の画面:
4 tasks (0 done, 2 in progress, 2 open)
◼ VPC モジュール改善 (modules/vpc/) (@vpc-builder)
Writing modules/vpc/versions.tf…
◼ S3 モジュール作成 (modules/s3/) (@s3-builder)
Running Create S3 module directory…
◻ EC2 モジュール作成 (modules/ec2/) › blocked by #1
◻ ルートモジュール統合・更新 › blocked by #1, #2, #3
blocked by #1 の表示が依存関係です。
vpc-builder(タスク#1)が完了するまで、ec2-builder(タスク#3)は自動的に待機します。
7-6. SendMessage による双方向通信
vpc-builder と s3-builder が完了すると、
team-lead にメッセージが届きました。
@s3-builder❯ S3 module complete with interface details
@vpc-builder❯ VPC module complete with outputs interface
team-lead はこの情報を受け取り、VPC の outputs インタフェース(vpc_id, private_subnet_ids)を ec2-builder に渡しました。
これがサブエージェントとの決定的な違いです。
サブエージェントは、
「結果を返して終わり」ですが、
Agent Teams は、
「完了報告 → 依存解除 → 次のメンバー起動 → インタフェース情報の受け渡し」
という連鎖ワークフローが動きます。
8. 後半 Step 4:チーム開発の結果を確認する
全4タスクが完了しました。
#1 vpc-builder と #2 s3-builder は並列で同時に動き、
#3 ec2-builder は、
#1 の完了を待ってから起動しました。
8-1. 最終タスクグラフ
[#1 vpc-builder] [#2 s3-builder]
✅ completed ✅ completed
│ │
▼ │
[#3 ec2-builder] │
✅ completed │
│ │
▼ ▼
[#4 ルートモジュール統合]
✅ completed (team-lead)
全4タスクが完了し、
チームは自動的にシャットダウンされました。
所要時間は約18分51秒でした。
8-2. 生成されたファイル構成
iac_06/
├── main.tf # module "vpc" / "s3" / "ec2" の呼び出しのみ
├── variables.tf # validation 付き変数定義
├── outputs.tf # 各 module の output を参照
├── locals.tf # common_tags(変更なし)
├── provider.tf # ~> 1.9 / ~> 6.0 にバージョン制約改善
├── modules/
│ ├── vpc/ # vpc-builder が改善
│ │ ├── main.tf # count → for_each 完全移行
│ │ ├── variables.tf # map(string) + validation
│ │ ├── outputs.tf # map 形式の outputs
│ │ └── versions.tf # 新規追加
│ ├── s3/ # s3-builder が新規作成
│ │ ├── main.tf # S3 + ポリシー + 暗号化 + ライフサイクル
│ │ ├── variables.tf # validation 付き(ARN 形式チェック等)
│ │ ├── outputs.tf # bucket_id, bucket_arn, bucket_name
│ │ └── versions.tf # 新規追加
│ └── ec2/ # ec2-builder が新規作成
│ ├── main.tf # SG + EC2(SSH ingress を for_each 化)
│ ├── variables.tf # validation 付き
│ ├── outputs.tf # instance_id, private_ip, security_group_id
│ └── versions.tf # 新規追加
8-3. Before → After の比較
04-05記事で発見された skills-auditor の指摘が、
Agent Teams によってすべて解消されました。
| 項目 | Before(04記事時点) | After(Agent Teams 後) |
|---|---|---|
| サブネット管理 |
count(index ズレリスク) |
for_each(AZ をキーに安全な削除) |
| SSH ingress |
count + [0](先頭 CIDR のみ) |
for_each = toset(...)(全 CIDR 適用) |
| 変数バリデーション | なし | env, CIDR, ARN, volume_size に validation |
| バージョン制約 |
>= 1.0.0 / >= 5.0.0(上限なし) |
~> 1.9 / ~> 6.0(メジャー固定) |
| モジュール分割 | S3/EC2 が root main.tf に混在 | 3モジュール独立 |
| versions.tf | なし | 各モジュールに追加 |
| terraform fmt / validate | OK | OK |
8-4. コード例:for_each への移行
Before(04記事・count 版)— modules/vpc/main.tf:
resource "aws_subnet" "public" {
count = length(var.azs)
vpc_id = aws_vpc.this.id
cidr_block = var.public_subnet_cidrs[count.index]
availability_zone = var.azs[count.index]
}
After(Agent Teams・for_each 版)— modules/vpc/main.tf:
resource "aws_subnet" "public" {
for_each = var.public_subnet_cidrs # map(string): AZ → CIDR
vpc_id = aws_vpc.this.id
cidr_block = each.value
availability_zone = each.key
}
count では、
要素の順序変更でリソースが再作成されますが、
for_each ではキー(AZ 名)で管理するため安全です。
8-5. コード例:変数バリデーション
Before(04記事・バリデーションなし)— variables.tf:
variable "env" {
description = "環境名"
type = string
}
After(Agent Teams・バリデーション付き)— variables.tf:
variable "env" {
description = "環境名 (dev, stg, prod)"
type = string
validation {
condition = contains(["dev", "stg", "prod"], var.env)
error_message = "env は dev, stg, prod のいずれかを指定してください。"
}
}
8-6. コード例:SSH ingress の for_each 化
Before(04記事・先頭 CIDR のみ)— main.tf:
resource "aws_vpc_security_group_ingress_rule" "ssh" {
security_group_id = aws_security_group.web.id
description = "管理者からのSSHアクセス"
ip_protocol = "tcp"
from_port = 22
to_port = 22
cidr_ipv4 = var.allowed_ssh_cidr_blocks[0]
}
After(Agent Teams・全 CIDR 適用)— main.tf:
resource "aws_vpc_security_group_ingress_rule" "ssh" {
for_each = toset(var.allowed_ssh_cidr_blocks)
security_group_id = aws_security_group.this.id
description = "管理者からのSSHアクセス"
ip_protocol = "tcp"
from_port = 22
to_port = 22
cidr_ipv4 = each.value
}
9. 体験して分かったこと
9-1. カスタムエージェントについて
-
「一言で呼べる」が最大のメリット:
05記事では長いプロンプトを毎回書いていた。
カスタムエージェントならrule-checker でレビューしての一言で済む。 -
Git でチーム共有できる:
.claude/agents/をリポジトリに含めれば、チーム全員が同じレビュアーを使える。
「レビュー観点のばらつき」を仕組みで解消できる。 -
チェック対象を汎用化すべき:
05記事ではフルパスを指定していたが、
「カレントディレクトリ配下」にすることでどのプロジェクトでも使える。
9-2. Agent Teams について
-
依存関係の自動管理が強力:
ec2-builder は vpc-builder 完了まで自動的にブロックされ、完了後に自動起動した。
人間が「VPC ができたから次は EC2」と指示する必要がない -
SendMessage で情報が受け渡される:
vpc-builder が完了すると
outputs インタフェース情報が team-lead に届き、それが ec2-builder に渡された。
サブエージェントでは不可能だった連携パターン -
team-lead も作業者:
team-lead はタスクの割り当てだけでなく、
自らタスク#4(ルートモジュール統合)を実行した。
「管理者」と「作業者」の境界がない。 -
ライフサイクル管理が完結:
作成 → 作業 → 完了報告 → シャットダウン → クリーンアップまで自動で行われた
9-3. シリーズ全体がつながった
06記事の最大の発見は、04-05で見つけた問題が06で解消された ことです。
04記事: CLAUDE.md でルール定義 → コード生成(ルール準拠 ✅)
05記事: skills-auditor で問題発見 (Skills 1/7 ❌)
06記事前半: カスタムエージェントで再確認 (60/100 ⚠️)
06記事後半: Agent Teams で再構築 → 問題がすべて解消 ✅
skills-auditor が指摘した
「count vs for_each」「変数バリデーション」「バージョン制約」は、
Agent Teams のメンバーが
各モジュールを再構築する過程で自然に修正されました。
10. まとめ
10-1. この記事で分かったこと
| ゴール | 結果 |
|---|---|
| ①カスタムエージェントの定義・呼び出し |
.claude/agents/ にファイル化。/agents で一覧表示、一言で呼び出し可能 |
| ②Agent Teams でチーム編成 | 4メンバーのチームを作成。 依存関係付きの並列開発が成功(約19分で完了) |
| ③3つの仕組みの違い | サブエージェント→カスタムエージェント=進化形。 Agent Teams=別の仕組み(双方向通信) |
10-2. シリーズを通して学んだこと
6記事を通して、以下の知識が積み上がりました。
| 記事 | 学んだこと | 積み上がった知識 |
|---|---|---|
| 01 | Skills の比較と選び方 | 「何を使うか」 |
| 02 | サブエージェントの基本 | 「道具の使い方」 |
| 03 | Skills の効果検証 | 「汎用ルールの威力」 |
| 04 | CLAUDE.md のカスタムルール | 「チーム固有ルールの威力」 |
| 05 | サブエージェントでレビュー + 意外な発見 | 「自動レビュー」+「2つの仕組みの関係」 |
| 06 | カスタムエージェント&Agent Teams | 「再利用可能なレビュー」+「チーム開発」 |
10-3. シリーズ全体の学び
6回の連載を通じて見えてきた、
Claude Code で Terraform を書くための実践パターンです。
| パターン | 使いどころ |
|---|---|
| Skills | コード生成の品質を底上げする(汎用ルール) |
| CLAUDE.md | チーム独自のルールを教える(プロジェクト固有) |
| カスタムエージェント | レビュー観点をファイル化して再利用・共有する |
| Agent Teams | 複数モジュールの並列開発、依存関係のある大規模作業 |
これらは排他的ではなく、組み合わせて使う ものです。
本記事の実験では、
Skills + CLAUDE.md + カスタムエージェント + Agent Teams の
すべてを併用しました。
10-4. 最後に
01記事で「Skills とは何か」を調べるところから始まり、
06記事で「AI チームを編成して並列開発する」ところまで来ました。
Claude Code は
「AI にコードを書かせるツール」ではなく、
「AI とチームを組むためのプラットフォーム」 です。
Skills でルールを共有し、
CLAUDE.md でプロジェクトの文脈を伝え、
カスタムエージェントでレビューを標準化し、Agent Teams で分業する。
これは人間のチーム開発と同じ構造です。
本シリーズが、Claude Code × Terraform の実践の一助になれば幸いです。