Claude Code の fork() の使いどき — 並列エージェント設計の判断基準

「Claude Code でサブエージェントを並列で走らせたいけど、fork() と通常の fresh agent どちらを使えばいい?」——エージェント設計を自動化に組み込もうとすると、この判断で詰まります。
結論を先に言います。fork() を使うのは「親のコンテキストが必要で、かつ子の出力をコンテキストに戻したくないとき」 です。逆に言えば、文脈を引き継がせる必要がないなら fresh agent の方が正確です。
この記事の前提
masatoman.net の記事自動執筆設計(content-executor)を組む中で、エージェントの並列化設計に取り組んできました。複数の調査タスク・チェックタスクを並行で走らせるとき、fork() と fresh agent のどちらを選ぶかによって、コンテキストの状態・トークン消費・精度が変わることを確認しています。
スタック: Claude Code + Agent ツール(subagent_type: "fork")
読者のよくある詰まり
subagent_type: "fork"とsubagent_type: "general-purpose"の違いが分からない- fork() した子エージェントの出力を親コンテキストに戻さなくていい理由が分からない
- 並列で走らせると安くなるはずが、逆にコンテキストが肥大した
fork() の実際の動作
fork() で起動したエージェントは、親セッションのコンテキストをすべて引き継ぎます。 会話履歴・読み込んだファイル・ツール呼び出しの結果——これらがそのまま子エージェントに渡ります。
重要なのは キャッシュ共有 です。Claude API の Prompt Caching は、同じコンテキストプレフィックスを持つリクエストに対してキャッシュヒットが発生します。fork() は親と同じコンテキストから始まるため、キャッシュがそのまま効きます。コンテキストが重いセッション(大量のファイルを読んだ後など)でも、fork() の子エージェントは初回から低コストで動きます。
親セッション(コンテキスト 5万トークン)
└── fork() → 子は同じ 5万トークンのキャッシュを引き継ぐ
入力コスト = キャッシュヒット分(入力単価の約1/10)で処理される
一方、fresh agent(subagent_type が fork 以外) はコンテキストがゼロから始まります。タスクの背景・ファイルの内容・制約条件をすべてプロンプトに書いて渡す必要があります。コンテキストの再構築コストがかかる半面、過去の経緯を引き継がない「クリーンな判断」ができます。
fork() vs fresh agent の判断基準
| 条件 | fork() | fresh agent |
|---|---|---|
| 親のコンテキストが必要 | ✅ | ❌(プロンプトに書く) |
| 子の生ログを親コンテキストに入れたくない | ✅ | ✅ |
| 独立した視点・別モデルが必要 | ❌ | ✅ |
| 軽量な単発タスク | ❌(過剰) | ✅ |
| 並列研究・調査 | ✅ | ✅ |
| コンテキストを読んだ後の派生作業 | ✅ | △(要再ロード) |
fork() を選ぶ 3 条件:
- 親が今持っているコンテキストを子エージェントにも使わせたい
- 子の作業結果(ツール呼び出しの生ログなど)を親コンテキストに入れたくない
- 並列でいくつかの独立した問いを調べたい(同時に複数送れる)
fresh agent を選ぶ条件:
- 別モデルを使いたい(fork は親と同じモデル固定)
- コンテキストのない「第三者の目」が必要
- 親のコンテキストが重すぎて引き継ぎが逆効果なとき
実際に使ったパターン
content-executor で複数の記事チェックを並列で走らせるとき、fork() を使っています。各チェックタスクは「記事全文と判定ルールのコンテキスト」を必要としますが、チェック結果のログ(ツール呼び出し履歴)は親コンテキストに戻す必要がありません。
// 並列チェックを fork() で実行する設計例
Agent({ subagent_type: "fork", prompt: "誇張チェック: ...", run_in_background: true })
Agent({ subagent_type: "fork", prompt: "ターゲット適合チェック: ...", run_in_background: true })
Agent({ subagent_type: "fork", prompt: "CTA重複チェック: ...", run_in_background: true })
// 各チェックの完了を待ち、結果だけを受け取る
content-executor(本体)
├── fork(誇張チェック) ─┐
├── fork(ターゲット適合チェック) ─┤ 並列実行
└── fork(内部リンク存在チェック) ─┘
↓ 判定結果だけを受け取る(生ログは引き継がない)
これで親のコンテキストを汚さずに、並列チェックを低コストで実行できます。
今日やること
- 自分のルーティン設計で並列化したいタスクを 1 つ洗い出す
- そのタスクに「親コンテキストが必要か」を確認する → Yes なら fork()、No なら fresh agent
Agent({ subagent_type: "fork", run_in_background: true })で実装し、背景で走らせる