こんにちは。ファインディ株式会社でテックリードマネージャーをやらせてもらっている戸田です。
ファインディでは要件定義から設計・タスク分解・Issue生成までをAIに任せるカスタムコマンドを開発しています。
今回は、そのコマンドで生成したIssueをAIエージェントに渡したときに、どう並列実装まで自動化しているかを紹介します。Git worktreeとClaude CodeのAgent Teamsを組み合わせることで、依存関係を考慮しながら複数のIssueを並列にPR作成まで進められます。
- Git worktreeとは
- 依存関係グラフで実行レイヤーを決定する
- Claude CodeのAgent Teams機能
- Team LeadとWorkerの役割分担
- IssueごとのWorktreeで並行実装を実現する
- merge-gateによるレイヤー間の同期
- Workerの実装フロー
- まとめ
Git worktreeとは
Git worktreeは、1つのGitリポジトリを複数のディレクトリで同時にチェックアウトできる機能です。
通常のブランチ切り替えと異なり、メインの作業ディレクトリはそのままに、別のディレクトリで別のブランチを並行して操作できます。
# worktreeの作成 git worktree add .worktrees/feature/add-auth -b feature/add-auth main # worktreeの一覧表示 git worktree list # worktreeの削除 git worktree remove .worktrees/feature/add-auth
エージェントごとに独立した作業ディレクトリを持てる点が、並列実装との相性が良い理由です。あるエージェントの変更が別のエージェントの作業ディレクトリに影響しません。
依存関係グラフで実行レイヤーを決定する
この仕組みを使うには、GitHubのIssueが次の構造になっている必要があります。
- 親IssueにGitHubのSub-issue機能でSub-issueが紐づいていること
- Sub-issue間の依存関係がGitHubのIssue依存関係機能(blocked_by)で設定されていること
具体的には次のような構造です。
#200 ユーザー認証機能の実装(親Issue) ├── #201 テーブル作成 │ ├── #202 サービス実装 │ │ └── #204 APIエンドポイント │ └── #203 テンプレート実装 └── #205 ドキュメント更新
並列実装で最初に解決しなければならない問題は「どのIssueを先に実装するか」です。Sub-issue間に依存関係がある場合、順序を間違えると後続の実装が破綻します。例えばテーブルが存在しない状態でサービス層を実装しようとしても、マイグレーションが走っていないためテストが通らず、PRを作るところまで辿り着けません。人間が実装するときも依存関係の順序は意識しますが、複数のエージェントが並列で動く場合は「誰がどの順番でどれを実装するか」を明示的に制御する仕組みが必要になります。
この依存関係をもとに、並列実行できるIssueのグループ(レイヤー)を計算します。
- Layer 0: 依存なし → 全て並列実行可能
- Layer N: Layer N-1 以前のIssueにのみ依存 → Layer N-1 完了後に並列実行
例えば5つのSub-issueがある場合、次のような実行計画になります。
依存関係グラフ:
#201 テーブル作成 ─┬→ #202 サービス実装 ─┬→ #204 APIエンドポイント
└→ #203 テンプレート ─┘
#205 ドキュメント更新(独立)
Layer 0(並列実行): #201, #205
Layer 1(並列実行): #202, #203 ← Layer 0 完了後
Layer 2: #204 ← Layer 1 完了後
この実行計画をユーザーに提示し、確認を得てから実装を開始します。循環依存が検出された場合はエラーを報告して中止します。
Claude CodeのAgent Teams機能
この仕組みはClaude CodeのAgent Teams機能を基盤として構築しています。
Agent Teamsは、複数のClaudeセッションがチームとして協調して動作するための機能です。Team Leadがタスクを作成して各Workerに割り当て、WorkerはSendMessageでTeam Leadに進捗を報告しながら並列で作業を進めます。なお、執筆時点では実験的な機能のため、利用するには設定での有効化が必要です。
Team LeadとWorkerの役割分担
実行はTeam LeadとWorkerというエージェントの役割分担で行います。
- Team Lead: 依存関係グラフの構築、タスクの作成と事前割り当て、Workerの起動・停止、レイヤー間の同期(merge-gate)を担当する。コードは実装しない
- Worker: 割り当てられたIssueのworktreeを作成し、実装・セルフレビュー・PR作成まで一貫して行う
Team Leadはオーケストレーターに徹し、Workerのworktreeに対してコマンドを実行したり、コードを直接編集したりしません。Workerからの報告を受動的に待つだけです。
IssueごとのWorktreeで並行実装を実現する
各WorkerはアサインされたIssueごとにworktreeを作成し、独立したディレクトリで実装を進めます。worktreeはリポジトリ内の.worktrees/exec-issues-{親Issue番号}/issue-{Issue番号}/以下に配置され、作業が完了したら削除されます。
git worktree add ".worktrees/exec-issues-200/issue-201" -b "issue-201/テーブル作成" main
複数のWorkerが同時に動いていても、それぞれが独立したworktreeを持つため互いの作業が干渉しません。あるWorkerがファイルを編集しても別のWorkerの作業ディレクトリには影響がなく、並行実装が安全に行えます。
tmuxやiTerm2を使っている場合、Workerの起動と同時にペインが追加されます。並行実装中のWorkerがそれぞれ別ペインで動いている様子をリアルタイムで確認できるため、全体の進行状況を把握しやすくなっています。
同一レイヤー内の並行IssueがどのファイルをPATCHするかは事前にわかりません。そのため、Workerのタスク情報に「同一レイヤーで並行実装中のIssue一覧」を含め、ファイル競合リスクをWorkerが意識できるようにしています。
merge-gateによるレイヤー間の同期
レイヤー間の依存関係を守るために、merge-gateという仕組みを新たに追加しました。
Layer 0のWorkerが全員PRを作成し終えたら、Team LeadはLayer 1のWorkerを起動する前にmerge-gateを処理します。merge-gateでは、Layer 0で作成された全PRのマージ状態をチェックし、未マージのPRをユーザーに通知して待機します。
全PRがマージされたことを確認してからdefaultブランチを最新に更新し、Layer 1のWorkerを起動します。この仕組みにより、後続レイヤーのWorkerは常に最新の状態をベースに実装を始められます。
タスクの依存関係で表現すると次のような構造です。
[impl] #201 ─┐
├→ [merge-gate] Layer 0 ─┐
[impl] #205 ─┘ ├→ [impl] #202
└→ [impl] #203
merge-gateタスクはTeam Lead専用で、Workerはclaimしません。
Workerの実装フロー
各Workerは割り当てられたタスクを順番に処理します。
- タスク詳細(Issue番号・タイトル・親Issueの文脈)を読み取る
- worktreeを作成して環境をセットアップする
- (PLAN_APPROVALが有効な場合)実装計画をTeam Leadに送信して承認を得る
- Issueの内容に従って実装する
- セルフレビューを実施し、修正提案をTeam Leadに送って承認後に適用する
- PRを作成してTeam Leadに結果を報告する
- worktreeを削除してクリーンアップする
全タスクを処理し終えたらTeam Leadに完了を報告して終了します。

まとめ
今回紹介した仕組みのポイントは次の3点です。
- Sub-issue間の依存関係をもとにレイヤー分けし、同一レイヤーのIssueを並列実行する
- merge-gateでレイヤー間のPRマージを確認してからdefaultブランチを更新し、後続レイヤーに進む
- IssueごとにWorkerとworktreeを対応させることで、並行実装の干渉を防ぐ
Sub-issueに依存関係を設定した親Issueを用意して指示するだけで、実装の順序管理からPR作成まで自動で進みます。複数の施策を同時に走らせることへの心理的なハードルが下がり、並行して進められる開発の幅が広がりました。
ファインディでは一緒に会社を盛り上げてくれるメンバーを募集中です。興味を持っていただいた方はこちらのページからご応募お願いします。