MF Blogs Tools
増えすぎたファイル群を表す抽象的なツリー図

Article

AI開発でファイルが増えすぎる問題を防ぐ設計ルール

Claude CodeなどのAIコーディングエージェントは小さなファイル・ヘルパー・util・型定義・READMEを次々に量産しがちです。ファイル分割の基準、統合判断、ドメイン単位の置き場、レビュー観点を整理し、ファイルスプロールを止める設計ルールをまとめます。

0:00 0:00

This article is not published in this language yet, so the Japanese version is shown instead.

Claude CodeのようなAIコーディングエージェントを使い続けると、リポジトリには気がつかないうちに細かいファイルが溜まっていきます。utils/formatDate.tshelpers/parseUserId.tstypes/UserResponseDto.ts、各機能ごとのREADME.md——どれも単体では正しく見えますが、半年後に「どこを直せばいいのかわからない」状態を生みます。この記事では、AI開発で起きやすい「ファイルスプロール」を防ぐための設計ルールを整理します。

なぜAIはファイルを増やしすぎるのか

ファイルが増えやすい原因は3つあります。

  1. 既存ファイルの全文を読まない: 該当箇所だけを変更するため、似た関数が既にあっても新しいファイルを作る
  2. 「分割しておけば安全」というデフォルト挙動: 新規ヘルパーやutilを別ファイルに切り出す傾向が強い
  3. 指示にない補助物まで作る: 同じディレクトリに README.mdindex.ts を勝手に追加する

これは個別のセッションでは「親切」に見えますが、リポジトリ全体では重複・命名揺れ・参照の枝分かれを生み続けます。

増えすぎの典型パターン

パターン1:1関数1ファイル化

src/utils/
  ├ formatDate.ts        // export function formatDate
  ├ formatDateShort.ts   // export function formatDateShort
  ├ parseDate.ts         // export function parseDate
  ├ getMonthName.ts      // 内部で formatDate を再実装

似た目的の関数が独立ファイルに散らばり、再実装まで起きます。

パターン2:型定義ファイルの量産

src/types/
  ├ UserDto.ts
  ├ UserResponseDto.ts
  ├ UserCreateRequestDto.ts
  ├ UserUpdateRequestDto.ts

DTOごとに別ファイル化されますが、参照されるドメインは同じです。

パターン3:ローカルREADMEの増殖

src/components/src/api/src/lib/の各階層に「このディレクトリは何か」を説明するREADME.mdが作られ、内容はコードと重複します。

パターン4:壊さないための新規ファイル

「既存コードを壊したくない」という配慮から、修正ではなく新規ファイルでの実装が選ばれます。userServiceV2.tsuserService.new.tsのような並走実装がその例です。

ファイル分割の基準を3つに固定する

ファイルを分けるかどうかの判断は、3つの基準に絞ると安定します。

基準分けてよい例分けないほうがよい例
ドメイン境界users/orders/ のように業務概念が違う同じドメインの関数を内部処理ごとに分ける
公開API境界パッケージ外に公開する関数1関数からしか呼ばれない内部ヘルパー
テスト境界独立したテストスイートがある親モジュールのテストでカバーされる

3つすべてを満たさない分割は「とりあえず分けただけ」の可能性が高く、統合候補です。

CLAUDE.mdに書くべきファイル設計ルール

ファイルスプロールはAIへの指示で大幅に防げます。CLAUDE.mdに共通ルールとして書く内容のテンプレートです。

## ファイル設計ルール

- 新規ファイルを作る前に、同じディレクトリに似た用途のファイルがないか必ず確認する
- 1関数だけのutilファイルは作らない。既存の `src/utils/index.ts` に追記する
- 型定義は機能単位で集約する。1型1ファイルにしない
- `README.md` は依頼されない限り作らない
- 既存ファイルの修正で済むなら、新規ファイルは作らない
- ファイルを200行超えそうなときだけ分割を検討する

CLAUDE.mdの書き方詳細は「CLAUDE.mdテンプレート完全版」を参照してください。

ドメイン単位で置き場所を決める

utils/helpers/という名前のディレクトリは、何でも入る箱になりがちです。代わりにドメイン名で割ります。

変更前(増えやすい)            変更後(境界が明確)
src/                            src/
  ├ utils/                       ├ domain/
  │  ├ formatDate.ts             │  ├ user/
  │  ├ parseUserId.ts            │  │  ├ user.ts
  │  ├ validateOrder.ts          │  │  └ user.test.ts
  │  └ generateInvoiceId.ts      │  ├ order/
  └ helpers/                     │  │  ├ order.ts
     ├ apiClient.ts              │  │  └ order.test.ts
     └ logger.ts                 │  └ invoice/
                                 │     └ invoice.ts
                                 └ shared/
                                    └ logger.ts

shared/は「ドメインに属さないが複数ドメインから使う」場合だけに限定し、ここに何でも置かないようにします。プロジェクト構成全体の整え方は「Claude Codeでプロジェクトを読ませる前に整理すべきファイル構成」で詳しく扱っています。

既存ファイルへの追記を依頼文で促す

新規ファイルではなく既存ファイルへの追記を促すために、依頼文に明示します。

依頼:ユーザー作成時に表示名を整形する処理を追加してください。

制約:
- 新規ファイルは作らないこと
- 整形処理は src/domain/user/user.ts 内に追加する
- 既存の formatDisplayName 関数があるか先に確認し、あれば再利用する
- 関数名は既存命名(camelCase、動詞+目的語)に従う

完了条件:
- npm test が通る
- src/ 以下の新規ファイル数が0であることを git status で確認する

「新規ファイル数が0」という検証可能な完了条件を入れることで、勝手な分割を抑制できます。完了条件の書き方は「Claude Codeの成功率を上げる制約条件と受け入れ条件の作り方」を参照してください。

統合判断のチェックリスト

レビュー時、以下のいずれかに該当するファイルは統合候補です。

  • 1関数しかexportしておらず、呼び出し元が1〜2箇所
  • 同じディレクトリに似た用途のファイルが3つ以上ある
  • ファイル名にHelperUtilCommonが入っているが、共通利用されていない
  • 型定義しかなく、対応する実装ファイルから1対1で参照されている
  • 中身が10行未満で、importとexportが大半
  • バージョン番号やnewv2がファイル名に入っている

統合候補が見つかったら、まとめてリファクタリングPRを作ります。リファクタの安全な進め方は「Claude Codeで既存コードを壊さずリファクタリングする依頼文」で扱っています。

レビューで見るべき3観点

PRレビュー時、AIが新規ファイルを追加した場合は次の3点を必ず確認します。

  1. 必要性: 既存ファイルへの追記で解決できなかったか
  2. 置き場所: ドメイン境界に沿っているか、utils/に何でも入れていないか
  3. 重複: 似た関数・型・ロジックが既存にないか

greprgでファイル名・関数名の類似を検索する習慣をつけると重複の発見が早くなります。

# 似た関数名を一覧する
rg "function format" --type ts

# importされていないファイルを検出する
npx ts-prune

ドキュメントファイルも増えすぎを防ぐ

AIはドキュメントファイル(README.mdNOTES.mdCHANGELOG.md)も気軽に作ります。次のルールで運用します。

  • プロジェクトルートのREADME.mdCLAUDE.mdNOTES.md以外は依頼ベースでのみ作る
  • ディレクトリごとのREADME.mdは作らない(コードコメントとCLAUDE.mdで代替)
  • 設計判断はdocs/adr/に集約し、各機能ディレクトリにメモを残さない

ファイルスプロール防止チェックリスト

  • CLAUDE.mdにファイル設計ルールを書いてあるか
  • utils/helpers/ではなくドメイン名でディレクトリを割っているか
  • 依頼文で「新規ファイルを作らない」と明示しているか
  • 完了条件に「新規ファイル数の検証」を入れているか
  • 1関数1ファイル化、1型1ファイル化を避ける運用になっているか
  • ローカルREADME.mdを依頼なしで作らないルールがあるか
  • レビュー時に既存ファイルでの代替可否を確認しているか

次に読むおすすめ記事: