大規模なリファクタリングをAIに任せるとき、一番やってはいけないのが「全部いい感じに直して」と丸投げして一括置換させることです。差分が巨大になり、どこで壊れたか追えなくなり、結局自分で全部読み直すハメになります。
この記事では、Claude Codeの実在する機能(Plan mode・サブエージェント・CLAUDE.md・/clear・Hooks)を使って、大規模リファクタリングを「壊さずに・追える形で」進める手順をまとめます。読者はClaude Codeを日常的に使う開発者を想定しています。
大原則:一括置換せず、小さく刻んで各ステップで検証する
リファクタリングをAIに任せるときの安全性は、ほぼ次の3点で決まります。
- 影響範囲を先に把握する(読むだけ・書かない)
- 計画を立ててレビューしてから書く(承認ゲートを挟む)
- 1ステップ=小さい差分にして、毎回テストで検証する
これは人間がやるリファクタリングの定石とまったく同じです。Claude Codeにはこの定石をそのまま乗せられる機能が揃っています。
ステップ1:影響範囲を調査する(書かせない)
いきなりコードを触らせる前に、まず「どこに影響するか」を調べさせます。ここで重要なのは書き込みを伴わない調査に徹することです。
Claude CodeにはPlan modeがあり、Shift+Tabを2回押すか、/planコマンドで入れます。Plan modeでは、Claudeはコードベースを読んで分析・計画はしますが、あなたが承認するまでファイルを変更しません(Plan Mode - ClaudeLog)。調査フェーズにそのまま使えます。
調査の指示例:
(Plan modeで)
UserService の getUser メソッドの戻り値の型を変更したい。
変更する前に、まず以下を調べて報告して:
- getUser を呼び出している箇所すべて(ファイルパスと行番号)
- 戻り値をどう使っているか(プロパティアクセス・分岐・テスト)
- 影響しそうなテストファイル
まだコードは変更しないで。調査結果だけ出して。
調査のような読み取り中心の作業は、サブエージェントに任せるとメインの会話のコンテキストを汚さずに済みます。Claude Codeには読み取り専用でコードベースを探索するExploreサブエージェント(既定で高速・低コストなモデルで動く)や、Plan modeで使われるPlanサブエージェントが組み込まれています(Create custom subagents - Claude Code Docs)。
調査結果が出たら、自分の目で影響範囲を確認します。Claudeが見落とした呼び出し箇所があれば、ここで指摘して追わせます。この段階での確認が、後の事故をいちばん減らします(効果は対象コードベースや指示の精度によって変わります)。
ステップ2:計画を立てさせ、レビューしてから承認する
影響範囲が見えたら、次は実行計画を作らせます。Plan modeはまさにこのためにあり、Claudeが提示した計画を読んでからShift+Tabでモードを切り替えて実行に移れます。
計画には「順番」と「分割」を明示させるのがコツです。
調査結果をもとに、リファクタリングの手順を小さいステップに分割して。
各ステップは:
- 1コミットに収まる小ささにする
- ステップ単独でビルド・テストが通る状態を保つ
- 何をどう変えるか、どのテストで検証するかを書く
ステップ間の依存関係も明示して。
ここで出てきた計画を読み、順番がおかしい・1ステップが大きすぎると感じたら分割し直させます。計画段階での手戻りはコストが小さいので、納得いくまで詰めます。
ステップ3:既存パターンに合わせさせる(CLAUDE.md)
リファクタリングで地味に効くのが「既存のコードの書き方に合わせさせる」ことです。放っておくとAIは自分流のスタイルで書き、コードベースの一貫性が崩れます。
プロジェクトルートにCLAUDE.mdを置くと、その内容はセッション開始時に自動でコンテキストに読み込まれます。命名規則・使うライブラリ・テストの書き方・避けたいパターンなどを書いておくと、毎回同じ前提で作業させられます。
# CLAUDE.md
## コーディング規約
- エラーハンドリングは Result 型を使う(例外を throw しない)
- 新規の日付処理は date-fns を使う(moment は使わない・移行中)
- テストは Vitest。describe/it で構造化する
## リファクタリング時の注意
- 公開APIのシグネチャを変えるときは必ず呼び出し側も同コミットで直す
- 1コミットの差分は小さく保つ。無関係な変更を混ぜない
なお、調査用のExplore / Planサブエージェントは速度とコストのためCLAUDE.mdを読み飛ばす一方、それ以外の組み込み・カスタムサブエージェントはCLAUDE.mdを読み込みます(Create custom subagents - Claude Code Docs)。実際に書き換えを行うフェーズでは規約が効く、と理解しておくとよいです。
ステップ4:テストを先に固める(壊さないためのガード)
リファクタリングの定義は「外から見た振る舞いを変えずに内部を整える」ことです。つまり、振る舞いを固定するテストがあれば、それがそのままガードになります。
書き換え前に、対象範囲のテストの現状を確認させます。
リファクタ対象の UserService に対する既存テストを実行して、
現状すべて green か確認して。
カバーされていない振る舞いがあれば、リファクタ前に
「現状の振る舞いを固定するテスト」を追加して。
テストが薄い領域では、先に振る舞いを固定するテスト(characterization test)を足してから本体を触らせます。これで「変えたつもりがないのに壊れた」を検知できます。
ステップ5:1ステップずつ適用し、毎回検証する
ここがいちばん重要です。計画の1ステップだけを実行させ、テストを通し、コミットしてから次へ進みます。
計画のステップ1だけを実行して。それ以外は触らないで。
変更したらテストを実行して、結果を見せて。
green なら、このステップだけをコミットして(メッセージは refactor: で始める)。
ポイントは次の通りです。
- 差分を小さく保つ:1ステップ=1つの関心事。無関係な変更を混ぜない。レビューしやすく、壊れたときに切り分けやすくなります。
-
各コミットを「ビルド・テストが通る状態」に保つ:問題が起きたコミットだけを
git revertで戻せます(Git Commit Best Practices)。 - リファクタと機能変更・バグ修正を混ぜない:混ぜると差分の意図が読めなくなります(My git Workflow for Refactoring - Kyle Shevlin)。
各ステップが終わったら差分を確認します。
git diff --stat
git diff
意図しないファイルが変わっていないか、想定外の挙動変更が混ざっていないかをここで弾きます。
Hooksで機械的なガードをかける
Claude CodeのHooks機能を使うと、ツール実行の前後に任意のコマンドを自動実行できます。たとえばファイル編集後に自動でフォーマッタやテストを走らせる、といったガードを仕込めます。人間がレビューする前に機械でチェックできる部分は、Hooksに任せると取りこぼしが減ります。
ステップ6:レビューを挟み、コンテキストを区切る
ステップを何個か進めたら、まとまった単位でレビューします。差分が小さいので、人間のレビューもAIへの自己レビュー依頼もやりやすくなっています。
これまでのステップ1〜3の差分をレビューして。
振る舞いが変わっていないか、規約に沿っているか、
見落としている呼び出し箇所がないかをチェックして報告して。
長い作業が続くとコンテキストが膨らんで精度が落ちやすくなります。1つの論理的なまとまりが終わったら/clearでコンテキストを区切るのが有効です。次のまとまりはCLAUDE.mdと現在のコード(=コミット済みの状態)から再スタートできるので、会話履歴を引きずらずに済みます。
まとめ:AIにこそ「小さく・検証しながら」を徹底させる
大規模リファクタリングをClaude Codeで安全に進める流れは次の通りです。
- 調査:Plan mode+Exploreで影響範囲を洗い出す(書かせない)
- 計画:小さいステップに分割させ、レビューして承認
- 規約:CLAUDE.mdで既存パターンに合わせさせる
- ガード:テストを先に固める(必要なら特性化テストを追加)
- 適用:1ステップずつ実行→テスト→小さくコミット
-
レビュー:まとまり単位で確認し、
/clearで区切る
AIは一括で大量に書けてしまうぶん、人間以上に「小さく刻んで毎回検証する」規律が効きます。承認ゲートとテストと小さな差分、この3つを外さなければ、リファクタリングは追える範囲に収まります(実際の効果はコードベースの規模やテストの整備状況によって異なります)。
Claude Codeをすぐ試せる無料スキル4つをGitHubで公開しています:claude-code-skills-starter。Claude Codeの実践Tipsは X @k___n___t_1125 で発信しています。