MF Blogs 便利ツール
積み上がった技術的負債を小さく分解して返済していく抽象イメージ図

記事

Claude Codeで技術的負債を増やさないリファクタリング計画

Claude Codeは速い分だけ技術的負債も速く積まれます。負債の検出・優先順位付け(影響×変更頻度)・小分けリファクタ計画・特性化テストの安全網・負債台帳の記録までを、公式のExplore→Plan→Implementに沿って実務手順として整理します。

0:00 0:00

Claude Codeは実装が速い分、設計の歪み・重複・未テストコードも速く積み上がります。「動いたからマージ」を繰り返すと、半年後に誰も触れないモジュールが残ります。本記事は、AI開発で技術的負債を増やさないための検出・優先順位付け・返済計画の手順です。

結論:負債は「検出してから・小さく・テストで固定して」返す

Anthropic公式のBest Practicesは、修正の原則を「症状ではなく根本原因に対処せよ(address the root cause, don’t suppress the error)」とし、進め方を「Explore → Plan → Implement」で分離することを推奨しています(Best practices for Claude Code)。技術的負債の返済も同じです。

要点は4つです。

  1. 検出:負債を「感覚」ではなく検出可能な形にする(重複・未使用・未テスト・複雑度)
  2. 優先順位:影響度×変更頻度で並べ、触らない負債は意図的に放置する
  3. 小分け:1コミット=1意図でAPIを変えずに返す
  4. 記録:返した負債と放置した負債を台帳に残す

リファクタの安全な依頼文そのものは「Claude Codeで既存コードを壊さずリファクタリングする依頼文」、複数ファイルにまたがる変更の進め方は「Claude Codeで複数ファイルの変更を安全に進めるコツ」に任せ、本記事は「負債を増やさない/返す計画」に集中します。

なぜAI開発は負債が積みやすいのか

公式が挙げる失敗パターンが、そのまま負債の発生源になります。

  • trust-then-verify gap:それらしく動くが穴があるコードを検証せず受け入れる
  • 新規ファイルの量産:壊さないために分割し、重複と未使用が増える
  • 依存追加の暴走:1機能のPRに不要なライブラリが入る
  • 曖昧な依頼でスコープ外のリファクタが混入し、変更履歴が読めなくなる

速度が上がるほど、検収を飛ばしたときの負債蓄積も速くなります。人間が止めるべき場所は「AIに任せすぎないためのClaude Code運用ルール」に分けてあります。

ステップ1:負債を検出可能にする

「汚い」では着手できません。検出コマンドで対象を可視化し、plan modeのClaudeに棚卸しさせます(読み取りのみで安全です)。

claude --permission-mode plan

検出の入口になるコマンド例です(プロジェクトに合わせて読み替えます)。

git log --since='6 months ago' --name-only --pretty=format: | sort | uniq -c | sort -rn | head -20

これは「直近6か月で変更頻度が高いファイル」を出します。変更頻度が高く品質が低い箇所が、最優先の返済対象です。あわせて重複・未使用・型の緩さを機械的に拾います。

  • 重複コード:rgで同じシグネチャや定数の散らばりを探す
  • 未使用エクスポート:TypeScriptなら未使用エクスポート検出ツールで洗い出す
  • 未テスト:カバレッジの低いディレクトリを特定
  • 複雑度:極端に長い関数・深いネスト

Claudeへの依頼は「直して」ではなく「棚卸しして表にして」から始めます。検出と返済を同じターンで混ぜないのがコツです。

ステップ2:優先順位を付ける(影響度×変更頻度)

すべての負債を返す必要はありません。触らないコードの汚さは負債ではないという前提で並べます。

変更頻度\影響度影響大影響小
よく変わる最優先で返す計画的に返す
ほぼ変わらないテストだけ先に足す放置(記録のみ)

「よく変わる×影響大」だけを今回のスコープにし、残りは台帳に記録して見送ります。これを依頼文の制約に明示し、AIが勝手に全部直そうとするのを止めます。

ステップ3:小分けで返す(APIを変えない)

リファクタは挙動を変えない作業です。公式の「Explore → Plan → Implement → Commit」に乗せ、1コミット=1意図で進めます。

返済の順序は「特性化テストで現状の挙動を固定 → 内部を整理 → 公開APIは不変のまま」です。依頼文に入れる制約の最小セットはこうです。

## 目的
src/billing/の重複した税計算ロジックを1か所に統合する(負債返済)

## 制約
- 公開シグネチャ・外部から見た挙動を変えない(リファクタであり機能変更ではない)
- 新しい依存を追加しない
- 1コミット=1意図。統合・削除・呼び出し元修正は別コミット
- スコープはsrc/billing/のみ。それ以外は触らない

## 完了条件
- 既存テストが全て緑のまま
- 統合前の挙動を固定する特性化テストを先に追加し、それも緑
- 削除したコードが他から参照されていないことを確認した結果を報告

## 禁止事項
- 症状の握りつぶし(例外を握って握りつぶす等)で「直った」ことにしない
- 依頼スコープ外のリファクタやファイル新規作成

中間状態でテストスイート全体を壊さないこと、型定義→実装→呼び出し元→テストの順で進めることは、複数ファイル変更の基本です。受け入れ条件と禁止事項の書き分けは「Claude Codeの成功率を上げる制約条件と受け入れ条件の作り方」に詳しくあります。

ステップ4:返した負債と放置した負債を記録する

記録しない返済は再発します。負債台帳を残しますが、CLAUDE.mdに長文を書くと毎セッションのコンテキストを圧迫します。役割を分けます。

  • CLAUDE.md:再発を防ぐ短い禁止事項だけ(例:「src/legacy/は新規参照を増やさない」)
  • docs/tech-debt.md:負債台帳(場所・理由・影響度・対応方針・放置判断)
  • コミットメッセージ:1件1意図で「何を返したか」を残す

ドキュメントを増やしすぎない書き分けは「Claude Codeでドキュメントを増やしすぎないための書き方」にまとめています。台帳の最小フォーマット例です。

| 箇所 | 種類 | 影響度 | 変更頻度 | 方針 | 状態 |
| --- | --- | --- | --- | --- | --- |
| src/billing/tax | 重複 | 大 | 高 | 統合 | 返済済(PR #123) |
| src/legacy/report | 未テスト | 中 | 低 | テストのみ追加 | 保留 |

負債を増やさない予防ルール

返すより、増やさないほうが安いです。依頼ごとに次を効かせます。

  • 完了条件に「新規ファイル数とその理由を報告」を入れる
  • 依存追加は禁止事項にし、必要なら別PRで人間レビュー
  • 「症状の握りつぶし禁止・根本原因に対処」を依頼文に固定
  • 機能追加とリファクタを同じPRに混ぜない
  • マージ前に人間がgit diffを読む(検収ゲート)

チェックリスト

  • 負債を検出コマンドで可視化し、plan modeで棚卸しさせた
  • 影響度×変更頻度で優先順位を付け、放置する負債を決めた
  • 今回のスコープを「よく変わる×影響大」に絞って依頼文に明示した
  • 特性化テストで現状の挙動を固定してから内部を整理した
  • 公開APIを変えず、1コミット=1意図で進めた
  • 症状の握りつぶしを禁止事項に入れた
  • 返済済み/保留の負債をdocs/の台帳に記録した
  • 再発防止の短い禁止事項だけをCLAUDE.mdに追記した
  • 機能追加とリファクタを別PRに分け、人間が差分を検収した

次に読むおすすめ記事: