先日、ある開発の現場で、こんなことが起きました。
私と協力会社のエンジニアが、それぞれ別のブランチで5週間ほど作業していました。どちらもAIコーディングツールを使っています。いざ合流させようとしたところ、5つのファイルで29ヶ所が衝突し、マージできませんでした。
衝突の解消そのものは、半日で終わりました。AIを使えばこの作業は速い。問題は別のところにあります。最終的に、片方が数週間かけて詰めた実装を、まるごと1本捨てました。 動くのに、正しいのに、捨てるしかありませんでした。
先に結論を書きます。
編集どうしは合流できます。作り直しどうしは合流できません。
そしてAIが安くしたのは、編集ではなく作り直しのほうでした。
順に説明します。
起きたこと① 同じ問題を、2つのAIが別々に解いていた
開発していたのはモバイルアプリです。そのホーム画面には、細かい光や模様が常に動いている描画レイヤーがあります。ここが重く、端末が発熱するという課題がずっとありました。
私は自分のブランチで、この問題を「動かない部分を画像として一度だけ焼き付けて、毎フレームは画像を1枚貼るだけにする」という方法で解決しました。実機で発熱を測りながら詰めた実装です。
一方、本流のブランチでは、別のエンジニアとAIが、同じ問題を「描画そのものを計算式に置き換えて1回で描く」という方法で解決していました。
どちらも正しく、どちらも動きます。狙いも同じで、結果として得られる絵もほぼ同じです。それでも、片方しか採用できません。 この2つは同じ場所を占めていて、混ぜると動かないからです。
規模を書いておきます。私の側は22ファイル・約3,300行の追加。本流の側は同じ5つのファイルに45コミット・約1,300行の変更。このうち衝突していたのが29ヶ所でした。5週間ぶん、2人ぶんの作業が、同じ場所で正面からぶつかっていたことになります。
合流の作業は半日。捨てたのは数週間です。この非対称が、今回いちばん高くついたものでした。
なぜ「AIだから」起きるのか
ここが本題です。
ソースコードの変更には2種類あります。編集と作り直しです。
編集は、既にある構造の中で値を変えたり行を足したりする変更です。これは合流できます。2人が同じファイルの違う場所を編集していれば、機械が自動でくっつけてくれる。同じ行を触っていても、片方を選べば済みます。失われるのはその数行だけです。
作り直しは、構造そのものを別のものに置き換える変更です。これは合流できません。2つの構造を混ぜることはできないので、どちらかを丸ごと捨てることになります。
これはAIとは関係なく昔からそうでした。では何が変わったのか。
AI以前、1人のエンジニアが5週間で描画のしくみを丸ごと作り直すことは、そう起きませんでした。 コストが高すぎたからです。だから多くの変更は編集で、衝突は「編集の衝突」で済んでいた。「同じ行を触ったので片方を選ぶ」という、数行単位の話でした。
いま、その作り直しが安くなりました。AIに手伝わせれば、数週間で構造を入れ替えられます。安くなったので、人は以前より気軽に作り直しを選ぶようになります。そして作り直しは、合流できない種類の変更です。
つまりこういうことです。
AIは開発を速くしました。ただしその速さは、合流できる種類の変更ではなく、合流できない種類の変更のほうに効いています。
だから対策も、「マージを頑張る」ではありません。作り直しを2箇所で同時に走らせないことです。
起きたこと② AIの診断は正確で、処方だけが間違っていた
合流を試みた協力会社のエンジニアから、AIに調べさせた結果として報告がありました。分岐点が古いこと、衝突が29ヶ所であること。そして「このコマンドを順に実行すれば回避できます」という対処法が添えられていました。
診断は完全に正確でした。 こちらで検証したところ、分岐点も衝突の数も、1ヶ所の違いもなく一致していました。
ところが処方は間違っていました。 提示されたコマンドは衝突を回避しません。実際に流してみると、まったく同じ29ヶ所が同じように衝突します。解決する場所が変わるだけです。しかもそのコマンドには、レビュー中だった別の作業を巻き込んで壊す副作用がありました。
ここから引き出せるのは、AIの出力を検証コストで仕分けるという原則です。
検証が安いもの — 数、日付、差分、ファイル名。手元でコマンドを1回叩けば確かめられます。今回の「29ヶ所」がこれで、実際に正確でした。
検証が高いもの — 「こうすれば直ります」「この方法が最適です」。効くかどうかは、実行するまで分かりません。そして実行してから間違いだと分かると、その時点で何かが壊れています。
共同作業で事故になるのは、検証が高い出力を、検証しないまま相手に転送してしまうことです。「AIがこう言っています」は、受け取る側にとって断りにくい形をしています。安いものは共有していい。高いものは、自分で再現してから渡す。この線引きだけでも事故はかなり減ります。
起きたこと③ 検査を全部通ったのに、実機で壊れていた
29ヶ所を一つずつ判断して解消し、検証しました。型チェック エラー0、バンドル生成 成功、クラウドでの実機向けビルド 成功。ここまで通ったので大丈夫だろうと思いました。
しかし実機に入れて動かすと、カードの上端が水平に切れていました。
原因はこうです。合流前の本流には「拡大率は1.75倍」という設定値がありました。私のブランチでは、この拡大率の決め方そのものを作り直し、上限1.28倍という別の仕組みに置き換えています。
私は合流のとき、新しい仕組みを採用しました。ところが、古い設定値を参照している箇所を1ヶ所だけ残してしまいました。 結果、カードが本来より3割大きく描かれ、表示領域からはみ出して切れた——というわけです。
重要なのは、この矛盾がどの検査にも引っかからないことです。1.75も1.28も、数値として正しい。型としても正しい。コードとしても正しい。間違っているのは前提の組み合わせだけで、そこを見るしくみはどこにもありませんでした。
そして、これは作り直しの合流に必ずついてくる罠です。作り直しとは「前提の入れ替え」なので、入れ替え損ねた参照が必ずどこかに残ります。 新しく書かれたコードはレビューされますが、古い前提を参照したまま生き残った行は、誰の目にも留まりません。何も変わっていないように見えるからです。
月曜から変えられること
今回の反省から、実際に運用を変えたものを挙げます。どれも「AI以前には言う必要がなかった」ものです。
1. 止めるのは「作り直し」だけでいい
すべての変更を報告させると、報告が形骸化します。編集は自由でよく、構造を置き換える変更だけ、着手前に一言宣言する。「今週、描画のしくみを作り直します」の一言があれば、同じ場所で二重に走ることは避けられます。今回の件は、正直に言えば私自身が5週間ぶん本流を取り込まずに作り直していたことが直接の原因でした。相手の落ち度ではありません。
2. 作り直しの許可は「範囲」ではなく「前提」で出す
「この画面をお願いします」という範囲の指定では足りません。作り直しの中で、寸法の基準・単位・設定値の出どころといった前提が静かに置き換わります。あとで合流させる予定があるなら、どの前提の上で作るのかを先に決める。ここを握らずに出した指示が、今回いちばん高くつきました。
3. AIの出力は、検証コストで仕分けて扱う
数・日付・差分は信じてよい。「こうすれば直ります」は、自分の手元で再現してから採用する。相手に転送するときも同じです。
4. 合流のレビューは「消えなかった行」を見る
これが今回いちばん実用的な発見でした。合流後のレビューで見るべきなのは、新しく足された行ではありません。古い前提を参照したまま残ってしまった行です。 差分の上では何も起きていないように見えるので、意識して探さないと見つかりません。型チェックもAIも、ここは見てくれません。
そして、自動検査の通過を完了の根拠にしないこと。 型チェックが通った、ビルドが通った——どれも「壊れていないこと」の証明にはなりません。検収条件には実機での確認を必ず入れてください。
おわりに ——「合流の作法」を具体的に書く
今回の29ヶ所は、すべて解消して実機で動くところまで持っていきました。所要は半日です。コンフリクトの解消そのものは、AIで確実に簡単になりました。 5ファイル29ヶ所を、どちらの実装が何を意図しているか読み解きながら1つずつ判断する。以前なら数日がかりだった作業です。
問題は、簡単になったのが「解く」工程だけだったことです。どちらを残すかの判断は人間がやるしかなく、前提の食い違いは実機で初めて見つかり、そもそも29ヶ所も衝突させたのは人間の運用でした。
その運用のことを「合流の作法」と呼んでいますが、それだけでは何も言っていないので、具体的に書きます。今回の件から言えるのは3つです。
1. 作り直しは、始める前に宣言する
編集は宣言しなくていい。構造を置き換えるときだけ、一言。 「今週、描画のしくみを作り直します」で足ります。
2. 作り直しは溜めない
編集は溜めてかまいません。数週間ぶんの編集は、あとからでも合流できます。溜めてはいけないのは作り直しのほうで、これは日が経つほど「捨てる側」の損失が増えます。今回は5週間溜めて、数週間ぶんを捨てました。1週間で合流していれば、捨てるのは1週間ぶんで済んでいます。
3. 渡すときは「置き換えた前提」を書いて添える
これが今回いちばん高くついた欠落でした。実装を渡すとき、私が添えるべきだったのはこの2行です。
置き換えた前提
- 拡大率の決め方: 固定値 1.75 → 枠から計算(上限 1.28)
- 影響: 1.75 を参照している箇所はすべて要確認
この2行があれば、受け取る側は 1.75 を検索するだけで、残っていた1ヶ所を見つけられました。差分を3,300行読む必要も、実機に入れるまで気づかないということも、ありませんでした。
差分は「何が変わったか」しか語りません。「何を前提にしなくなったか」は、人間が書くしかないのです。そしてこれは、作り直しが安くなったいまだからこそ必要になった申し送りです。編集しかしていなかった頃は、前提が丸ごと入れ替わることがなかったので、書く必要がありませんでした。
AIを入れると、チームの弱いところが以前より速く、大きく現れます。今回それが出たのは、コードの書き方ではありませんでした。作り直しを宣言せず、溜め込み、前提の申し送りなしに渡した——その3つです。
もし1つだけ変えるなら、これです。「作り直します」と言ってから作り直し、「これを前提にしなくなりました」と書いて渡す。 今回の29ヶ所も、捨てた数週間も、実機で切れたカードも、この2つの習慣があれば起きていませんでした。
弊社では、こうした「AIを入れたあとに実際に起きること」を踏まえた開発・伴走を行っています。共同開発の進め方や、外部パートナーとの分担でお困りのことがあれば、お気軽にご相談ください。


