買い物リストの小さなアプリがあり、追加したい機能が2つあります。項目のフィルターと、リストのCSVエクスポートです。ほとんど関係のない作業なので、2人で分担すれば1時間ではなく30分で両方できそうです。1人はフィルター、もう1人はエクスポートを担当し、変更が混ざらないよう各自の作業フォルダーも用意しました。ただし、リストの項目をそれぞれどう解釈するかは事前に話し合っていません。明らかだと思っていたのです。

30分後、両方の作業が終わりました。それぞれのチェックは成功し、統合でも競合はひとつも起きませんでした。ところが、全体のシナリオは動きません。画面ではフィルターが3行を表示するのに、エクスポートしたファイルでは列が空です。原因は単純でした。担当者の1人が作業のついでに、読みやすさを理由に completed フィールドを done に変更し、もう1人はそれを知りませんでした。

作業フォルダーを分けてもファイルが別々になるだけで、判断までは揃いません。このタスクを3段階で見ていきましょう。まず分担する価値があるかを判断し、次に変更範囲と共通ルールを決め、最後に統合した結果を確認します。最初に挙げたような問題が、最後の最後で発覚しないようにするためです。

依存関係を確認する

作業を分ける理由は、たいてい2つです。1つ目は別々の領域を独立して調査すること。たとえば、リストの表示方法とエクスポートの作られ方を同時に調べます。2つ目は、範囲と確認可能な成果がすでに分かっている作業を並行して進めることです。"ここで計画、ここで実行、ここで確認"のように分けるだけなら、3人は必要ありません。1つのセッションで順番に進められます。小さなタスクなら、まず担当者1人で始めるのが妥当です。

分担する理由があるなら、次は"Aの結果が分からない間に、Bの作業のどこまで進められるか"を考えます。BがAに完全に依存するなら、作業は順番に進めます。Bが独立した部分を先に準備できる場合もありますが、結果の統合はAを待つ必要があります。

同じ買い物リストの例で、3つの状況を見てみましょう。

作業内容同時に始められるか理由
現在のリストの絞り込み箇所と、エクスポートの生成箇所を探すはい異なる部分を読み、調査結果は互いに依存しない
原因がまだ分からない問題の最終修正を準備する原因を確認した後まず調査が必要。検証可能な別々の仮説なら並行して調べられる
フィルターとエクスポート機能を書く共通の項目形式を決めた後両方が同じフィールドを使うため、共通の判断がなければ結果が食い違う

3行目はよくある落とし穴です。フィルターは src/filter.js、エクスポートは src/export-csv.js にあるので、別々の作業に見えます。ファイルが違うのだから、と。けれど、どちらも同じ項目と completed フィールドを読みます。冒頭のシナリオで問題が起きたのもこのためです。ファイルが別々でも解決しませんでした。独立性を決めるのは動作と共通ルールであり、コードが何個のファイルにあるかではありません。

作業の分割案は、担当者を起動せずにエージェントへ頼めます。

タスクを複数の部分に分けてください。それぞれについて入力、成果、
依存関係、確認方法を示してください。今すぐ始められる部分に印を付けてください。
担当者はまだ起動しないでください。

起動前に回答を確認できます。未解決の依存関係がない部分は、並行して始める候補です。依存関係の欄が空なら、共通モデルや設定をエージェントが見落としていないかプロジェクトと照らし合わせましょう。

共通の成果までの時間を見積もる

速度向上は、作業そのものにかかった時間という1つの数字で測りがちです。見るべきなのは、共通の成果が受け入れられるまでの時間です。作業だけでなく、各担当者への依頼、各自によるプロジェクトの読み直し、待ち時間、2つの成果の確認と統合も含みます。

この例で仮に計算してみます。数値は計算用で、性能測定の結果ではありません。

項目担当者1人で順番に作業担当者2人で並行作業
分担の追加準備: 2つの依頼文と担当者間の調整0分5分
作業20 + 20分両方の作業に20分
成果の確認と統合10分15分
受け入れ可能な成果までの合計50分40分
項目の解釈違いで一方を15分かけてやり直した場合の合計50分55分

共通の準備はどちらの進め方でも必要なので、計算には含めていません。10分の短縮は、1回のやり直しでなくなります。統合に時間がかかるほど、並行作業で節約すべき時間も増えます。

時間以外にも、忘れやすいコストが2つあります。担当者が増えるたびにプロジェクトを読み直すため、リソースを使います。また、戻ってきた詳しい報告は、全体の会話のスペースを占めます。より大きなコストは、あなた自身の注意力です。2つの成果を読み、互いに照らし合わせて判断する必要があります。届いた内容を読み切れないなら、速くなったのはあなたではありません。

規模が同程度で独立した2つの作業なら、追加コストが小さい場合にほぼ2倍の速度もあり得ます。ただし、担当者の人数だけで速くなるとは限りません。

重複か、相互確認か

重複作業は報告からは分かりません。2人の担当者が同じファイルを開いて、それぞれリストの項目構造を調べ、どちらも正直にコードを確認したと報告します。一方で、意図的に別の人の目で確認したい場合もあります。重要な前提を、最初の担当者の推論を見ていない人に確かめてもらうのです。偶然の重複と違い、相互確認では対象、理由、答えが食い違ったときの対応をあらかじめ決めておきます。最後の対応がなければ、ただ意見を集めるだけです。

逆の状況も考えてみましょう。2人に、リスト項目の completed が何を意味するか尋ねました。2人とも"購入済みの印"と答えました。別々の人から同じ答えが返り、裏付けが取れたように見えます。

実際には、2人とも1年前に書かれた README.md の同じ1行を読みました。コード上では、そのフィールドの意味はとっくに変わっています。一致したのは結論ではなく、情報源でした。

ここから、実務で役立つ習慣が2つ出てきます。

  • 回答の根拠を示してもらいます。ファイル、行、コードの一部など、自分で開いて確認できるものです。要約ではなく、実物を見せてもらいましょう。
  • 共通の前提は、全員が同意していても個別に実際の動作を確かめます。コードが何をし、シナリオで何が起こるかを確認します。

別々のセッションにしても、誤りが独立するとは限りません。同じ情報源を使えば、同じ見落としが起こります。回答が食い違ったら票数ではなく根拠を調べましょう。1人は最新のコードを見ていて、2人は古いメモを参照しているかもしれません。

コードで確認したフィールドの意味が、作業開始前に合意する共通モデルの基礎になります。ここまでの3つの確認を経ても分担に価値があるなら、担当範囲を決めましょう。

各担当範囲の責任者を決める

並行作業中のルールはシンプルです。1つの変更範囲に責任者は1人です。"このファイルを2人で触ってはいけない"ではなく、"この2つのタスクを進めている間は、この人がここを変更する"という約束です。プロジェクト固有の決まりではなく、期間を区切った合意です。

ルールの後半は前半より重要で、忘れられがちです。共通の成果にも責任者がいます。各部分を統合し、全体として完了したかを判断する人です。統合担当を決めなければ、最後に作業を終えた人が引き受けることになります。よりによって、その人は相手側の作業を最も把握していません。

開始前にプロジェクトを確認し、必要な部分がすでに何らかの形で分かれているかを見ます。分かれていなくても、並行作業のために大規模なリファクタリングを始める理由にはなりません。それ自体がその日の最大のタスクになり、分担するものがなくなってしまいます。

買い物リストの例では、次のように分担できます。

担当範囲変更担当者条件
src/filter.js, tests/filter.test.js担当者A合意した completed フィールドで項目を絞り込む
src/export-csv.js, tests/export-csv.test.js担当者B渡された項目を合意した形式でエクスポートする
src/item-model.js統合担当者共通の項目モデルは開始前に合意し、変更は依存する全員と相談する
src/app.js, tests/filter-export.test.js統合担当者両方を接続し、絞り込み後のリストがエクスポートされることを確認する
package.json, package-lock.json統合担当者担当者は作業中に依存関係を追加しない

この表が決めるのは変更の責任者であり、アクセス権ではありません。共通ファイルは必要な人が全員読みます。

package.json の行は意地悪で加えたわけではありません。npm install は両方のファイルを一度に変更するため、並行して実行すると簡単に競合します。同じライブラリの異なるバージョンを使えば、ビルド時に予想外の問題も起きます。両方にライブラリが必要なら、何がなぜ必要かを伝えてもらいます。判断と変更は1人が1回だけ行います。

開始前に共通モデルを決める

ファイル単位の境界だけでは、共通ルールがないとうまくいきません。フィルターとエクスポートは同じ項目モデルを使います。以下はインターフェイスのスケッチで、実行できる例ではありません。関数の実装は省略しています。開始前に、項目の順序を保ち、元の配列は変更せず、CSVの真偽値はtrue/falseで出力することにも合意しました。CSVのエスケープ規則は変更しません。

// リストの1項目: この3つのフィールドは開始前に合意し、名前を変えない
const item = { id: 41, title: "oat milk", completed: false };

// filter.js は項目のセットを返し、フォーマットもエクスポートもしない
filterItems(items, mode);   // mode: "all", "active", "completed"

// export-csv.js は絞り込み済みのセットを受け取り、自分では絞り込まない
exportCsv(items);           // CSVの文字列を列 id,title,completed で返す

ここでの合意はファイル名ではなく、入力と出力に関するものです。"エクスポート機能には絞り込み済みのリストを渡す"は些細に聞こえますが、この1行で項目を選ぶ担当者が決まります。これがなければ、2人ともそれなりの理由で"絞り込みは自分の担当だ"と考えかねません。そうなると、ファイルにはすべての項目がそのまま出力されたり、二重に絞り込まれたものが出力されたりします。

開始前に、成果をどう受け入れるかも決めておきます。この例の共通シナリオでは、項目41と43は completed: true、項目42は false です。"completed"モードでは41と43を元の順で表示し、CSVには同じ2項目と id,title,completed のヘッダーを出し、最後の列にはtrueを入れます。両方の作業を通すことで、この記事の冒頭にあった問題をそのまま検出できます。

共通ルール自体の変更についても触れておきます。作業中に共通形式を変更する必要が分かったとしても、1ファイルの小さな変更ではありません。その形式に依存するすべてのタスクを見直す必要があります。すでに終えた作業が、以前の形式に基づいている可能性があるからです。

別々の作業フォルダー(git worktree)を使っても、合意の代わりにはなりません。変更を物理的に分けられるのは便利です。共通フォルダーでは、確認時に隣のタスクの未完了の変更が混ざり、どの担当者も単独では確認していない状態を検証してしまうことがあります。ただし、フォルダーは項目形式を決められません。また、ポート、ローカルのデータベース、その他の外部リソースは共通のままです。Git で追跡されていない .env は、新しいフォルダーにはデフォルトでまったく存在しません。たとえば .worktreeinclude を使ってコピーします。

各担当者に短い依頼を書く

依頼は長くなくてかまいません。通常は7項目で十分です。目標、開始するバージョン、自分が変更するファイル、共通ルール、検証可能な成果、返信に含める内容、他の担当範囲が必要になった場合の対応です。

目標: リストのフィルターで、すべての項目、未完了の項目だけ、または完了した項目だけを表示する。
開始する状態: 項目モデルについて合意した、mainブランチの最新コミット。
担当ファイル: src/filter.js と tests/filter.test.js。
共通ルール: completed フィールドは真偽値のままにし、フィールド名は変更しない。
フィルターは項目の配列を返し、エクスポートは行わない。
成果: フィルターのテストが成功する。3項目のセットで各モードが
期待どおりのリストを返す。
返信に含める内容: 実際に変更したファイルの一覧、テスト実行結果、
実行したバージョン、未解決の質問。
src/item-model.js または src/app.js の変更が必要になったら、作業を止め、
必要な変更と理由を説明して、返答を待つ。

2人目への依頼も同じ形にします。別のファイル2つ、同じ項目形式、検証可能な成果、担当範囲を越える場合の同じ手順です。ここで全文を書く必要はありません。

次は返信についてです。実際に変更したファイルの一覧と、チェックの実際の出力を含めてもらいます。"他の人のファイルには触れていません"という文は簡単に書けますし、強く求めるほど返信に載りやすくなります。文言ではなく変更一覧を確認してください。依頼で決める境界は合意であって禁止ではありません。依頼文だけではエージェントによるファイル書き込みを防げず、アクセス権は別途設定します。

作業の一部をサブエージェントに任せる場合

Claude Codeのサブエージェントは独自のコンテキストウィンドウで動きます。通常のサブエージェントはあなたとの会話を見ず、Claudeが作成したタスクの説明に沿って作業します。forkは会話全体を引き継ぎます。そのため、共通ルールと判断基準は依頼に明記しておくとよいでしょう。戻ってくるのは要約です。読みやすい一方で、ファイルのどこが変わったかまでは分からず、メインの会話のコンテキストも使います。詳しくはサブエージェントのドキュメントを参照してください。

重複する範囲を再調整する

作業中に、別の担当範囲にぶつかることはあります。担当者Bは src/app.js を変更しなければエクスポート機能をどこにも接続できないと気づきます。エクスポートボタンが呼び出されないのです。

Bからのよい返答には、理由、必要な変更、依存関係が含まれます。src/app.js の接続はすでに統合担当者の範囲です。そこでBは自分のモジュールを仕上げ、接続を依頼できます。共通部分の変更なしでは自分の作業を続けられない場合は、依存する作業を一時停止します。

次の対応は2つです。統合担当者が自分の範囲として共通ファイルを変更するか、担当範囲を明示的にBへ移します。後者の場合は、前の担当者がそのファイルを変更中でないことを先に確認してください。作業を止めずに担当だけ移すと、分担で防ごうとしていた状況がそのまま起きます。

担当者に境界を迂回させるのは避けましょう。"app.jsには触らず、何とかしてください"と頼むと、たいていは自分のファイルに他の人のロジックを複製するか、後から誰も説明できない余分な層ができます。表の上ではルールを守っていますが、実際にはエクスポートの動作について2つ目の正解ができてしまいます。

ファイルだけでなく動作を統合する

統合前に責任者が把握すべきことは3つです。各部分がどのバージョンから始まったか、各担当者がどのバージョンで何を確認したか、実際に変更されたファイルは何か。依頼への返信に記録されているはずですが、ファイル一覧は実際の変更と照合します。

その後、各部分を統合し、開始前に合意した共通シナリオを実行します。妨げになるのは、大きく異なる2種類の問題です。

テキスト上の競合。各部分が同じ箇所を異なる方法で変更したり、ファイルを削除・改名したりして、Gitが自動で統合できません。競合を解消してから、統合後の動作を確認します。

意味上の互換性の問題。同じ行を2人で変更していないため、変更はきれいに統合され、競合も通知されません。ここで、最初の改名の問題が起きます。フィルターは done を読み、エクスポートは completed を読むため、空の結果になります。それでも各部分のチェックは成功します。それぞれが自分のデータで、自分の範囲だけを確認しているからです。

競合のない統合は互換性の証明ではない

競合なしで統合できても、動作の互換性が証明されたわけではありません。UIを使うか、関数をつなぐテストで共通シナリオを実行できます。個別のチェックでは代用できません。

2つの作業部分を1つに統合し、共通シナリオで確認する担当者A担当者B統合担当者共通シナリオフィルターとエクスポートを一緒に各部分を統合src/filter.jssrc/export-csv.js
各部分を1人の責任者が統合し、互換性は共通シナリオで確認する

図では、下の矢印に注目してください。上半分が、一般に作業の分担と呼ばれるものです。別々のファイルで、2つの独立した部分を作ります。一方、完了したかどうかの判断は、その下にある両方の部分を通すシナリオで行います。この矢印の先まで確認できなければ、手元にあるのは個別の成果だけで、共通の成果はありません。プロジェクトのルールで全チェックの実行が必要なら、共通シナリオだけでは代わりになりません。

共通の判断を記録する

統合後、共通の成果の責任者が次の対応を選びます。たとえば次のとおりです。

  1. 共通の成果を受け入れる。シナリオが成功し、変更内容を説明でき、条件を満たしている。
  2. 具体的な部分を修正に戻す。何が何と合っていないかを明示します。"エクスポートが何となく変"ではなく、"モデルにもうないフィールドをエクスポートが読んでいる"と伝えます。
  3. 分担そのものを見直す。担当者を減らすか、作業を順番に進めます。

3つ目も普通の選択肢で、失敗ではありません。分担を見直す兆候はすぐに見えてきます。

  • 共通の項目形式が何度も変わり、そのたびに両方の作業をやり直している。
  • 担当者同士が待ち合っている。依存関係があったのに、明示されていなかったということです。
  • 成果が届くペースに、読む速度が追いつかない。

最後の兆候は、外から見ると成功のように見えるので厄介です。また、1回うまくいっただけで傾向が分かったとは言えません。エージェントの結果は実行ごとに変わるため、重要な結論は条件の近いタスクでもう一度確かめましょう。

部分的な成果も、問題のない結果です。フィルターは完成して確認済みでも、エクスポート機能は未完了かもしれません。その場合は、そのまま"2つのうち1つ"と記録します。全体のタスクは引き続き未完了です。半分が動くからといって完了扱いにはできません。丁寧に分担しても、その事実は変わりません。

理解度を確認する

2つの状況を考えます。まず自分で答えを出してから、確認してください。

原因がまだ分かっていない。
エクスポートで空のファイルができることがあり、すぐに2人へ修正を頼みたくなります。まず再現して調査しましょう。検証可能な別々の仮説が見つかったら、2人にそれぞれ調査を頼めます。ただし、根拠のない修正案が2つあっても問題は解決しません。それぞれを原因と結びつけ、元のシナリオで確認する必要があります。

ファイルは別々、でも数値は1つ。
フィルターは商品数を個数で数え、エクスポートは同じ数をパッケージ数で書き出します。両方のチェックは成功していますが、画面とファイルの数値が一致しません。コードのバグではありません。どちらの担当も自分の範囲を守っています。足りないのは単位の合意です。開始前に共通の項目モデルに記録し、src/item-model.js は統合担当者が変更してから、共通シナリオをもう一度実行します。

Claude Codeに任せられること

記事の冒頭で示したように、エージェントは分担案を作成し、あなたの項目をもとにまとまった依頼文を作れます。ほかにも便利な使い方が3つありますが、判断するのはあなたです。

  • 担当範囲のマップ案。プロジェクトを調べ、タスクの各部分で変更するファイルをパス付きで提案するよう頼みます。あくまで案です。各範囲の責任者はあなたが決めます。
  • 統合と共通シナリオの実行。エージェントが各部分を統合し、変更一覧をすべて示して、共通シナリオを実行します。その後、変更全体を自分で確認してください。
  • 判断が分かれる箇所。自信のある説明が2つあっても、判断が確定するわけではありません。根拠、ファイル、行を尋ねましょう。共通ファイルを誰が変更するかは、説得力のある答えをした人ではなく、事前に表で決めます。

結局、必要なのは1つの判断と2つの担当決めです。判断とは、分担する価値があるかどうかです。担当者を増やすなら、その人の作業に、準備・確認・統合の手間に見合う効果が必要です。担当決めとは、各変更範囲の責任者と共通の成果の責任者です。買い物リストの例で不足していたのは、まさにこの2つでした。completed フィールドへの合意も、フィルターとエクスポートをまとめて確認する人もいませんでした。ツールは機械的な作業を減らせますが、統合後の動作が本当に依頼どおりかどうかを判断するのは人です。