新しい機能を実装しようと意気込んで要件定義を始めた矢先、AI agent が**「その機能、もう実装されていますよ」**と教えてくれたことがあります。
具体的には、ある判定ロジックを Phase 1 で新規実装するつもりだったところ、relation_analyzer.py:71 にほぼ同等の定義がすでに存在していました。実装に着手していたら、確実に重複コードを生むところでした。
本記事は、この経験から「要件定義の前に、AI でコードベース全体を透視する『フェーズ0サーチ』を必須化する」という運用にした記録です。地味ですが、大規模・並行開発のコードベースでは効きます。
事の発端:「新機能」のつもりが既存だった
ある関連度の判定機能を追加しようとしていました。仕様はこうです。
エンティティのペア(A と B)について、過去データから関連度を計算し、閾値を超えたら「関連あり」と判定する。
要件定義を書き始める前に、念のため Claude Code に「この機能、既存コードに似たものはある?」と聞きました。返ってきた答えがこれです。
1relation_analyzer.py:71 に、エンティティA-B の関連度定義が2すでに存在します。Phase 1 で実装予定のロジックと重複する可能性が3あります。スコープに含まれるか確認したほうがよいです。実際に :71 を見に行くと、まさに同じペアの関連度がハードコードで定義されていました。私が「これから作る」と思っていたものの一部は、すでに誰か(あるいは過去の自分)が作っていたのです。
もしこれを知らずに実装していたら、
- 同じ判定が2箇所に存在し、片方を直してももう片方が残る(DRY 違反)
- どちらが「正」なのか後から誰にも分からなくなる
- 数時間〜数日の重複工数
——という典型的な事故になっていました。
なぜ「新機能 = 未実装」と思い込むのか
この思い込みには、いくつか構造的な理由があります。
理由1:自分が書いていないコードは「ない」と感じる
大規模なコードベースでは、自分が直接書いたコードはごく一部です。残りは他人や過去の自分が書いたもの。人間の記憶は「自分が触った範囲」に強くバイアスがかかるので、触っていない領域の機能は存在ごと忘れます。
理由2:並行開発で「いつの間にか」増えている
複数の作業を並行で進めていると、別ブランチ・別 PR で似た機能が追加されていることがあります。マージのタイミングによっては、自分が要件定義した時点ではまだ見えていなかったものが、実装する頃には main に入っている、ということも起きます。
理由3:要件定義は「あるべき姿」から書くので「現状」を見ない
要件定義は本質的に「これから何を作るか」を describe する作業です。視線が未来を向いているので、「現状すでに何があるか」を確認するステップが構造的に抜け落ちます。
対策:要件定義の前に「フェーズ0サーチ」を挟む
そこで、要件定義(フェーズ1)の前に、フェーズ0として「先行サーチ」を必須化しました。やることは1つだけです。
これから作ろうとしている機能のキーワードで、コードベース全体を AI に透視させ、「すでに存在するもの・近いもの」を列挙させる。
AI agent はこの作業に向いています。全文検索の速さと意味的な近さの判定を両立できるからです。grep だけだと「キーワードが一致する箇所」しか出ませんが、agent は「名前は違うが同じことをしている関数」も拾ってくれます。
フェーズ0サーチの依頼テンプレート
1## フェーズ0: 先行サーチ(実装前の重複確認)2
3これから「{機能の説明}」を実装する。要件定義に入る前に、4既存コードベースに同等・類似の実装がないか透視せよ。5
6確認してほしいこと:71. 同じ処理をする関数・クラス・定義が既にないか8 (名前が違っても意味的に同じものを含む)92. 部分的に重複する箇所はないか10 (一部のロジックだけ既存を流用できる等)113. 過去に同じ機能を実装して廃止/コメントアウトした痕跡はないか12
13出力:14- 「完全に重複」「部分的に重複」「関連するが別物」に分類15- それぞれ file:line で根拠を示す1 collapsed line
16- 重複ゼロなら「新規実装が妥当」と明言このテンプレートで依頼すると、agent は単なるキーワード検索を超えて、意味ベースの重複チェックをしてくれます。
結果をどう使うか:3つの分岐
フェーズ0サーチの結果は、3つに分岐します。
| 結果 | 判断 | 次のアクション |
|---|---|---|
| 完全に重複が存在 | 実装不要 | 既存を再利用 or 拡張。要件定義は「既存の改修」に切り替え |
| 部分的に重複 | 一部流用 | 重複部分を共通化し、差分だけ新規実装するよう要件を調整 |
| 重複なし(新規) | 新規実装 | 当初の予定通り要件定義へ。ただし重複ゼロを確認したという事実が要件に記録される |
重要なのは、「重複なし」の場合でも価値があることです。「探したけど無かった」という事実が記録されることで、後から「なぜ新規実装したのか」が説明できます。フェーズ0サーチは、重複を見つけたときだけでなく、新規実装の正当性を担保する役割も果たします。
AI ならではの「意味的透視」が効く
このフェーズ0サーチが AI 時代に特に効く理由は、grep では拾えない重複を拾えるからです。
たとえば、これから「2つの値の関連度を計算する」機能を作るとして、既存コードに compute_correlation という関数があれば grep correlation で見つかります。しかし、
def measure_affinity(a, b)(名前が違う)def get_relation_score(x, y)(語彙が違う)- ある関数の内部で、たまたま同じ計算をしている一部分
——これらは単純なキーワード検索では漏れます。AI agent は**「やっていることの意味」**で照合できるので、こうした命名のゆらぎを越えて重複を発見できます。今回の relation_analyzer.py:71 も、私が想定していたキーワードとは少し違う名前で定義されていました。
注意:agent の「無い」は鵜呑みにしない
ただし、ここで1つ落とし穴があります。フェーズ0サーチで agent が**「重複は見つかりませんでした」**と報告したとき、それを鵜呑みにすると逆方向の事故になります。
AI agent は「ある」を見つけるのは得意ですが、「ない」を証明するのは構造的に苦手です。「網羅的に探したが無かった」という報告は、最も信頼度が低い種類の出力です。
そこで、フェーズ0サーチでも「重複なし」という結論だけは裏取りします。
- agent が「見た」と言うディレクトリ範囲が妥当か確認する
- 自分でも代表的なキーワードで
grepを1〜2本打つ - 命名規約から推測される別名でも検索する
「重複あり」は1件見つかれば確定ですが、「重複なし」は本質的に悪魔の証明です。新規実装に踏み切る前に、この一段の懐疑を挟みます。
まとめ:実装の前に「現状」を透視する
AI 駆動開発で機能を量産していると、コードベースは想像以上の速さで育ちます。自分が書いていない機能、過去の自分が書いて忘れた機能が、あちこちに溜まっていきます。
そんな中で「新機能 = 未実装」という暗黙の仮定は危険です。だから、
- 要件定義(フェーズ1)の前に、フェーズ0サーチを挟む
- AI に「これから作るもの」のキーワードでコードベースを意味的に透視させる
- 結果を「完全重複 / 部分重複 / 重複なし」に分類して次の判断を決める
- ただし「重複なし」だけは悪魔の証明として自分でも裏取りする
「探したけど無かった」という事実は、新規実装の正当性を担保します。「探したらあった」という事実は、数時間〜数日の重複工数を着手前に節約します。設計の前に現状を透視する——たった1ステップですが、コードベースが大きくなるほど効いてくる習慣です。