MF Blogs 便利ツール
コードブロックを小さなブロックに分割し矢印で並べた抽象的なリファクタリングのイラスト

記事

Claude Codeで既存コードを壊さずリファクタリングする依頼文:影響範囲調査からテスト先行までのテンプレート

Claude Codeにリファクタリングを任せて事故を起こさないための依頼文テンプレートをまとめます。影響範囲の調査、失敗テスト先行、小分け実装、差分レビューまでの流れと、避けたい失敗例も整理します。

0:00 0:00

結論:リファクタリングは「失敗テスト先行→Plan Mode→小分けコミット」で進める

Claude Codeにリファクタリングを依頼するときの事故は、ほとんどが**「振る舞いが変わった」「スコープが膨らんだ」「依頼外のファイルまで触られた」**の3パターンです。これらを避けるには、依頼文の中で次の3つを明示します。

  • 挙動を固定するためのテストを先に追加させる(または既存テストの実行を前提にする)
  • Plan Modeで影響範囲と作業計画を出させてから承認する
  • 1コミット=1意図になるよう、小分けで提案させる

公式のベストプラクティスでも、調査→計画→実装→コミットの4フェーズに分ける運用が推奨されています。この記事ではリファクタリング特有の依頼文と、失敗例の回避策を整理します。基本のCLI操作やPlan Modeの使い方は、基本コマンド計画してから実装させるプロンプト例を先に押さえておくと読みやすくなります。

リファクタリングと「機能追加」を依頼文で明示的に分ける

リファクタリングの定義は「外から見た振る舞いを変えずに、内部構造だけを改善すること」です。依頼文が曖昧だと、Claude Codeは「ついでに気になった箇所」を直したり、APIシグネチャを変えたりしがちです。

依頼文の冒頭で次のように宣言しておくと、スコープが安定します。

## タスクの種類
リファクタリング(振る舞いは変えない)

## 触ってよいファイル
src/services/order/ 配下のみ

## 触ってはいけないこと
- 公開API(関数シグネチャ・戻り値の型・例外の種類)の変更
- データベーススキーマ・マイグレーション
- 依存パッケージの追加・削除・バージョン変更
- src/services/order/ 以外のファイル
- インポート順や空行の整形などの便乗修正

「やらないこと」を明示するのは、公式ドキュメントのProvide specific context in your promptsにもある通り、曖昧さを下げる一番効く手法です。

ステップ1:影響範囲の調査をPlan Modeで先に出させる

リファクタリング対象を選んだら、最初に呼び出し元と依存関係を把握させます。Plan Modeは読み取り系ツールしか使えないため、勝手に書き換えられる心配がありません。

claude --permission-mode plan "src/services/order/ をリファクタリングしたい。まず影響範囲を調査して報告して"

依頼文には「何を返してほしいか」を具体化します。

## お願い(このターンでは調査と要約のみ)
1. src/services/order/ 配下のファイル一覧と、各ファイルの責務を1行で
2. 公開関数(exportされている関数)と、その呼び出し元の一覧
3. 既存テストの場所とカバー範囲(どのケースが既にテストされているか)
4. 振る舞いの不変条件として外せない仕様を3〜5個
5. リファクタリング案を、変更の小さい順に2〜3個

## 注意
- ここでは実装も計画策定もしない。まず現状把握だけ
- 調査の途中で気になった他ディレクトリの問題は、別タスクとしてメモするだけ

公式ドキュメントのCommon Workflowsにもあるように、Plan ModeではReadGrepといった読み取り系ツールしか動かないので、調査だけを安全に任せられます。

ステップ2:失敗テスト先行(または既存テスト実行)で挙動を固定する

リファクタリング前に現在の振る舞いを再現するテストが通っている状態を作ります。テストが薄い場所は、特性化テスト(Characterization Test)を先に追加してもらいます。

## お願い
1. リファクタリング対象の現在の振る舞いを固定するテストを追加して
   - 正常系の代表ケース
   - 境界値(0件、最大件数、null/undefined、エラー時の戻り)
   - 例外パスと、その例外型
2. 既存テストと合わせて `npm test -- src/services/order` が緑になることを確認
3. テストはモックを増やさない方針で(既存のフィクスチャやファクトリを使う)

## 制約
- このターンではテスト追加と実行までで停止
- リファクタリング本体は次のターンで承認後に進める

テスト先行が機能するのは、リファクタリングで挙動が変わった瞬間にClaude Code自身が気づけるためです。公式ベストプラクティスのGive Claude a way to verify its workは「最も効果が高い1つ」と明言されています。

ステップ3:リファクタリング計画を出させてレビューする

テストが緑になったら、Plan Modeで計画を出させます。

claude --permission-mode plan "テストが緑の状態で、src/services/order/ の重複ロジックを切り出すリファクタリング計画を出して"

計画レビューでは次の観点を見ます。

  • 触るファイルが宣言したスコープに収まっているか
  • 公開シグネチャの変更がないか(戻り値の型、例外の種類、引数の順序)
  • 依存追加がないか
  • 削除予定のコードが本当に未使用か
  • テストの追加・修正が振る舞いを変えていないか
  • コミットの分け方が「1コミット=1意図」になっているか

問題があれば、全部やり直させるのではなく、計画だけを差分で直すよう依頼します。例:「order.repository.tsは今回触らない。トランザクション境界の見直しは次回別タスクで」。

ステップ4:小分けコミットで実装させる

承認後の実装フェーズでは、1コミット=1意図を守らせます。

## 実装方針
1. 計画の項目ごとに、1ステップずつ実装→テスト→git diff確認→コミット
2. 各ステップ後に `npm test -- src/services/order` を流す
3. 落ちたら直前のステップまで戻し、原因を1〜2文で報告してから次に進む
4. コミットメッセージは "refactor(order): <内容>" の形式
5. 1ステップで触るファイル数が3を超えたら、それ以上分割できないか検討する

## 中断条件
- テストが2回連続で落ちたら止めて、失敗内容を要約して報告
- 計画と実装が乖離し始めたら、いったん止めて差し戻し案を出す

中断条件は計画してから実装させるプロンプト例でも触れた通り、依頼文に書くかCLAUDE.mdに共通ルールとして書いておくと毎回の指示が短くなります。CLAUDE.mdの整備は最初に作るべきCLAUDE.mdの書き方を参照してください。

リファクタリングの種類別テンプレート

「リファクタリング」と一口に言っても性質が違うので、3種類のテンプレートを用意しておくと使い回しが効きます。

A. 関数の抽出・重複の解消

## ゴール
src/services/order/calculate.ts と src/services/cart/calculate.ts に
重複している割引計算ロジックを共通化する。

## 進め方
1. Plan Mode: 重複箇所の差分(共通点と相違点)を要約して
2. Plan: 共通モジュールの配置先候補(src/shared/pricing など)を2案出して
3. レビュー後、承認した案で実装
4. 既存呼び出し元の挙動が変わらないことをテストで確認
5. 1コミットで完了するなら1コミット、難しければ「抽出」と「移行」で分割

B. 命名変更・型の整理

## ゴール
OrderItem 型のプロパティ name を productName にリネームする。

## 制約
- 公開APIの戻り値JSONのキー名は変えない(互換のため内部だけ変える)
- DBカラムも変えない
- 影響箇所は IDE のリネーム相当で、機械的に置換できる範囲に絞る

## 進め方
1. 影響箇所の一覧を出して
2. 全置換ではなく、ファイルごとに段階的に置き換える計画を出して
3. 各段階でテストを流す

C. 依存方向の整理(レイヤー違反の修正)

## ゴール
src/ui/ から src/db/ を直接インポートしている箇所を、
src/services/ 経由に直す。

## 注意
- インターフェース変更を伴う場合は、計画段階で明示する
- 大きすぎる場合は、ファイル単位で複数PRに分ける案を出す
- 既存テストが落ちる場合は「なぜ落ちたか」を先に説明してから直す

よくある失敗と回避策

失敗パターン起きやすい依頼回避策
公開APIが変わってしまう「読みやすくして」「整理して」「公開シグネチャは変えない」を明文化
依頼外ファイルまで触る範囲指定なし「触ってよいファイル」を依頼文に書く
依存パッケージが勝手に追加される「もっと良いライブラリで」依存追加禁止を明記
テストが書き換えられて緑になる「テストも整理して」「振る舞いを変えるテスト変更は禁止」を追加
コミットが巨大になる「全部終わったら教えて」「1コミット=1意図」「ステップごとに止まる」を明記
ロジックの便乗最適化が混ざる「気になった所も直して」「便乗修正は別タスクとしてメモするだけ」と書く

やり直しを依頼するときの短い言い方

実装が始まってから方向修正したいときは、感情を込めず具体的に差し戻します。

直近の差分は破棄して、計画を修正してほしい。
- order.repository.ts は今回触らない(次回タスク)
- 例外型を Error から OrderValidationError に変えるのは中止(公開API変更のため)
- 共通化のゴールは「割引計算の重複解消」だけに絞る

差分を一度破棄させる場合は、基本コマンドEsc Escまたは/rewindで会話・コードのチェックポイントから戻すこともできます。git側でも、コミット前ならgit restoreで安全に戻せます。

レビュー時に人間が必ず見る観点

Claude Codeの差分が「テスト緑」でも、人間レビューを省いてはいけません。リファクタリング差分では特に次を確認します。

  • 関数の引数順や戻り値の型が変わっていないか
  • 例外の種類・メッセージが変わっていないか(呼び出し元のcatch条件に影響)
  • ログ出力の文言・レベルが変わっていないか(運用監視への影響)
  • 削除されたコードが本当に未使用か(リフレクションや動的インポート経由がないか)
  • テストの「期待値」自体が書き換えられていないか
  • 依存パッケージやpackage.jsonに変更が紛れていないか

公式ベストプラクティスのThe trust-then-verify gapが指摘する通り、それっぽく見える差分ほど検証が必要です。

まとめ:依頼文の型を3つ持っておく

リファクタリングをClaude Codeに任せるコツは、難しいテクニックではなく依頼文の型です。

  • 影響範囲調査テンプレ(Plan Modeで読むだけ)
  • 失敗テスト先行テンプレ(挙動を固定してからリファクタ)
  • 小分け実装テンプレ(1コミット=1意図、中断条件付き)

この3つを持っておけば、refactor(order): extract discount calculatorのような小さな差分が積み上がる運用に変わり、「読みやすくして」と一言投げて巨大PRを生み出す事故が減ります。

次のステップとしては、計画してから実装させるプロンプト例でPlan Modeの使い分けを深め、最初の機能追加の手順で通しのフローに慣れておくと、リファクタリング以外のタスクにも応用が効きます。