Quartet / Quintet

2026-09-04  ·  git · githubactions · 設計 · claudecode

並列開発を殺すのは、いつも共有ファイル

複数の作業を並列で走らせようとして、こうなったことはありませんか。

原因はたいてい共有ファイルです。 そして、これは分割の仕方で避けられます。

AI に並列で実装させる文脈で何度も踏んだので、パターンと対処を書きます。 人間のチームでも同じことが起きるので、AI に限った話ではありません。

犯人はだいたい決まっている

実際に衝突するファイルは、ほぼこの5種類でした。

共通点があります。「一覧」であること。 新機能を足すたびに1行増える構造は、 複数人(複数エージェント)が同時に触ると必ず同じ場所を編集します。

さらに悪いのは、ここでのコンフリクトは意味的には無害なことです。 Aさんが1行足し、Bさんが1行足しただけ。両方残せば正しい。 なのに Git は自動で解決できず、人間が止まります。

対処1: 共有ファイルだけを先に片付ける

一番効きます。共有ファイルを触る作業を1つだけ切り出して、先に通します。

Issue #10  ルート定義に3つのエントリを追加       Scope: src/routes/index.ts
Issue #11  設定画面の実装                      Scope: src/pages/settings/**   Depends on #10
Issue #12  請求画面の実装                      Scope: src/pages/billing/**    Depends on #10
Issue #13  通知画面の実装                      Scope: src/pages/notifications/**  Depends on #10

#10 は「まだ存在しない画面へのルートを先に足す」だけなので、数分で終わります。 その後 #11 #12 #13共有ファイルを一切触らないので、完全に並列で走ります。

順序が逆だと成立しません。#11 を実装しながらルートも足す形にすると、 3つが同じファイルを取り合います。

「まだ無い画面へのルートを足す」のは変か

一時的にビルドが壊れるのでは、と思うかもしれません。実際には、 プレースホルダのコンポーネントを置いておけば通ります。

// src/pages/settings/index.tsx  ← #11 が中身を実装する
export default function Settings() {
  return null;
}

空の箱を先に置く。 これだけで並列化できます。

対処2: 一覧を持たない構造にする

そもそも「一覧ファイル」を無くせるなら、そのほうが根本的です。

これ自体を1つの作業として切り出す価値があります。一度やれば、以後の並列化が ずっと楽になります。

ただし既存プロジェクトで急にやると影響範囲が広いので、 「衝突が3回起きたら構造を変える」くらいの基準を持っておくといいです。

対処3: 触れないものは、触れないと決めておく

AI に実装させる場合、これが効きます。担当範囲を明示し、 範囲外に出たら止めて報告させる。

- 担当している作業の Scope に書かれたパス以外を変更しない
- Scope 外の変更が必要になったら、実装を止めて報告する

黙って範囲を広げられると、分割が間違っていたという情報が消えます。 止まってくれれば、そこで分割を直せます。

実例です。ある作業で、実装者から報告が上がってきました。

tsc --noEmitnode:path の型を解決できません。devDependencies@types/node が無いためです。package.json は Scope 外なので変更していません。 別作業として切り出すか判断をお願いします。

これは土台の不足であって、その作業のせいではありません。 勝手に package.json を触られていたら、その PR に無関係な変更が混ざり、 レビューの基準がぼやけていました。別作業として切り出して、独立した PR で直しました。

対処4: マージは直列にする

分割が正しくても、マージまで並列にすると台無しです。

3つの PR を同時にマージすると、それぞれ単体ではテストが通るのに、 3つ入れた後で壊れることがあります。そしてどれが原因か切り分けられません。 結局3つとも調べ直すことになり、直列にマージするより遅くなります。

1件ずつマージすれば、main が進むたびに次の PR はその状態に対して判定されます。 壊れたら直前の1件が原因だと確定します。

実装は並列、マージは直列。 これが実務的な結論でした。

衝突は症状であって原因ではない

コンフリクトが繰り返し起きるとき、解消のやり方を改善しても意味がありません。 分割の仕方が間違っています。

コンフリクトの頻度は、分割の質を測る指標として使えます。

頻度 読み取れること
ほぼ起きない 分割が効いている
たまに起きる 想定外の依存がある。その回だけ解消すればよい
毎回起きる 共有ファイルを複数の作業が取り合っている。分割を見直す

毎回起きているのに、その場その場で解消して回ると、症状は消えますが原因は残り、 コストは増え続けます。

まとめ

この分割の考え方を、Claude Code のサブエージェント構成として明文化したものを MIT で公開しています。


Claude Code に設計・実装・レビューを別々の人格として分担させ、GitHub Issue と ブランチを軸に並列開発を回すための設定一式を MIT で公開しています。 コピーして ./setup.sh を叩けば動きます。技術スタックには依存しません。

https://github.com/quintetkit/quartet

このワークフローだけで実際にツールを 1 つ作りました。Issue の分割から PR、 レビュー、マージまで記録が全部残っています。うまくいかなかった箇所も消していません。

https://github.com/quintetkit/mdlinkcheck

UI 設計人格・レビュー基準・Issue 単位の並列実行スクリプト・実践ガイド 10 章を 足したものは製品ページにあります。

この運用そのものを配っています

4 人格版 Quartet は MIT で無料公開しています。UI 設計人格・レビュー基準・ Issue 単位の並列実行スクリプト・実践ガイド 10 章を足した Quintet は有料版です。

無料版を見る 製品ページ