Claude Codeのコードモダナイゼーション — レガシー移行の進め方
Claude Codeで大規模なレガシーシステムを移行する手順を、依存関係マッピング・段階的移行・テストの物差し・ドキュメント復元の4本柱で追います。
Claude Codeのコードモダナイゼーションは何をどこまで任せる取り組みか
コードモダナイゼーションとは、何十年も動き続けてきた基幹コードを、業務ロジックを壊さずに新しい言語・基盤・フレームワークへ移す取り組みです。Claude Codeは、その中で最も工数を食う「読んで理解する」工程を自動化する役割を担います。
Anthropicのソリューションページは、Claude Codeの役割を次の5つに分けています。
| 工程 | ページが述べる内容 |
|---|---|
| レガシーシステムの分析 | ページが述べる内容依存関係グラフの生成、デッドコードの特定、複雑度と業務影響に基づく優先順位づけ |
| 体系的な変換 | ページが述べる内容業務の継続性を保ちつつ、現行のフレームワークへ移す |
| テストと検証 | ページが述べる内容改修後コードの単体テスト生成、不足カバレッジの特定、回帰テストの作成 |
| セキュリティとコンプライアンス | ページが述べる内容脆弱性の特定と修正。レガシーに埋め込まれた規制対応のパターンは維持 |
| ドキュメント生成 | ページが述べる内容ドキュメントの無いコードから現代的な文書を作り、失われかけた知見を残す |
進め方は「人間を介在させたまま」が前提です。全部を自動で書き換える話ではありません。任せるのは調査・翻訳・検証ループで、何から移すかと、どこまで合格とみなすかは人間が決めます。
この記事は、こうした大規模移行の進め方を扱います。テストが無い小さなコードを安全に直す手順は、Claude Codeリファクタリングを安全に進める手順にあります。
なぜCOBOLのような古い資産ほど「理解」がボトルネックになるのか
Anthropicの解説記事は、COBOL移行が滞ってきた理由を「理解するコストが書き直すコストを上回っていた」と説明しています。コードを読める人が減り、ドキュメントは更新されず、暗黙の知識はコードの中にしか残っていません。
普通のリファクタリングとは性質が違います。作法の古いコードを新しい書き方に直すのではなく、数十年前のシステムから業務ロジックを逆算する作業になります。
移行の方針は4つに分かれます。
- リホスト: COBOLをそのまま安いインフラへ移す。速いが、保守しづらさは残る
- リファクタ: 振る舞いを変えずに構造を整える
- リライト: JavaやPythonなど現代の言語へ書き換える。効果が最も大きく、従来は費用とリスクも最大
- リプレース: 合う商用製品があるなら、システムごと置き換える
AIで経済性が最も変わるのはリライトの道です。以降はこのリライト寄りの進め方を追います。リホストやリプレースでも、分析の工程はそのまま使えます。
手順1: 依存関係マッピングで、暗黙の結合を先に洗い出す
最初の工程は、コードベース全体を読ませて構造を地図にすることです。Claude Codeは入口となるプログラム、サブルーチンを通る実行経路、モジュール間のデータの流れ、数百ファイルにまたがる依存関係を追い、ワークフローの文書も同時に作れます。
肝は暗黙の依存です。共有データ構造、ファイル操作が生む結合、実行時の挙動に効く初期化順序は、データがファイルやDB、グローバルな状態を経由するため、静的解析には出てきません。移行が壊れる典型はここにあり、事前に見つける価値が最も高い部分です。
実際にClaude Codeへ投げる指示は、たとえば次のような形になります。ここでは調査だけをさせ、ファイルは書かせません。
claude --permission-mode planplan modeでは、Claudeがファイルを読んで計画を出し、承認するまで編集をしません。ステータスバーに ⏸ plan mode on と出ている間は、読み取り専用の調査として使えます。セッション中に Shift+Tab を押して切り替える方法もあります。
src/billing 配下のCOBOLプログラムについて、呼び出し関係・共有COPYBOOK・
読み書きするファイルとテーブルを洗い出し、モジュール間の結合が強い順に
並べてください。ファイルは変更しないでください。出力が大きくなる調査は、サブエージェントに任せると本体のコンテキストを守れます。公式のcommon workflowsも、大きなコードベースの探索は探索用のサブエージェントに委ね、発見だけを受け取る形を勧めています。サブエージェントのモデル配分はサブエージェントのモデル配分設計で扱っています。
手順2: 人間が優先順位を決め、テストの合格基準を先に置く
地図ができたら、どこから移すかを決めます。結合が強いモジュールは移行のリスクが高く、独立した部品は早い段階で単独に移せる候補になります。重複したロジックはリファクタの入口で、技術的負債の溜まった領域は移行前に文書化します。
役割分担ははっきりしています。AIが出すのは優先順位の提案です。規制要件・業務上の優先度・運用上の制約・許容できるリスクは、COBOLを知るエンジニアが判断します。ここは人間の仕事です。
同じ段階で、コードを変える前にテストと検証も決めます。AIは、移行後のコードがCOBOLと同一の出力を返すことを確かめる機能テストの叩き台を設計します。それで足りるか、どの業務シナリオを業務担当者が手で確認するか、性能の基準をどこに置くかは、チームが決めます。
言語移植の大型事例では、この物差しが「審判(judge)」と呼ばれています。Anthropicの移行ガイドは、審判を用意することを開始の前提条件に置き、次の3手順を挙げています。
- 既存テストを分類する。外部呼び出しとして書けるものと、移植先に存在しない内部関数に依存するものを分ける
- 外向きのテストを、元コードと移植後コードの両方で動く形に書き直す
- 審判自体を検証する。元コードで通ること、わざと壊したコードで落ちることを確認する
壊れたコードを落とせない審判は審判ではない、という一文が3つ目の根拠です。テストが無いレガシーでも同じ考え方を使えます。既存コードを真実として、現行システムの出力と新システムの出力を突き合わせるスクリプトを作ればよく、Anthropic社内ではPythonからTypeScriptへの移植で、実在のシナリオ7本を新旧両方に流して結果を比較する形が取られました。
手順3: 一度に全部ではなく、コンポーネント単位で動かして検証する
実行は1コンポーネントずつです。AIがCOBOLのロジックを現代の言語へ翻訳し、残す側のレガシーにはAPIラッパーを被せ、移行の間は新旧を並べて動かせる足場を作ります。
ステップごとに成功して検証されるか、失敗して小さいうちに直されます。数週間分の変更が宙に浮いたままロールバックする状況を作らない、というのが段階移行の狙いです。動く部品が増えるほどチームの自信がつき、より複雑な部分へ進めます。
始め方も具体的です。境界がはっきりしていて、複雑さが中程度の単一コンポーネントかワークフローを1つ選びます。それを徹底的に分析・文書化し、エンジニアと計画を立て、テストしながら少しずつ実装し、慎重に検証する。この一巡で組織の確信が育ち、自社のシステムに必要な調整も見えてきます。
手順4: 移行ループを回す — ルールブックを先に作り、直すのはコードでなくループ
コンポーネントが数百〜数千に及ぶ移行では、手で1つずつ進めるのをやめ、複数エージェントのループに切り替えます。核心は、コードを直すのではなく、コードを生んだ手順(ループ)を直すことです。
流れは次のとおりです。言語移植の事例をレガシー移行に読み替えています。
| ステップ | 内容 |
|---|---|
| 準備 | 内容変換ルールを書いたルールブック、ルールが吸収できない箇所のギャップ一覧、移行順を決める依存関係マップを作る |
| ルールの負荷試験 | 内容少数のファイルで小さな移行を試し、ルールの穴を出す。翻訳したファイルは捨てる |
| 全体の翻訳 | 内容実装・レビュー・修正のループで全体を訳す。翻訳者が自信を持てない箇所は // TODO(port): 理由 を残す |
| コンパイル・実行・挙動一致 | 内容コンパイラのエラー一覧、スモークテストのクラッシュ、テストスイートの失敗を、次の作業キューとして修正エージェントに流す |
ルールブックはギャップ一覧より先に作ります。ギャップ一覧は「ルールブックの既定では扱えない箇所」で定義されるからです。ルールブックの形も設計判断で変わります。新しいコードが元と同じ構造なら型やイディオムの対応表が中心になり、全面的に作り直すなら設計文書になります。
依存関係の把握は、明示的なマニフェストを持たない言語で特に効きます。C/C++やPythonのような言語やレガシーのコードベースでは、依存は「発見して地図にする」対象です。Claude Codeに決定的なスクリプトを作らせて地図を出します。手順1で作った地図が、そのまま移行順の根拠になります。
レガシー向けの公式の入口も2つあります。フレームワーク更新を含むレガシーの近代化向けのcode-modernization pluginと、上記の手順を一般化したMigration starter kitです。starter kitはBunなどの実際の移植で使ったものではなく、テンプレートとして用意されています。
ルールブックは、次のような形で最初の骨格を作れます。以下は書き方の一例です。
# 移行ルールブック(billing)
## 型の対応
- PIC 9(n)V9(m) → BigDecimal(scale=m)。double は使わない
- PIC X(n) → String。末尾空白の扱いは rules/trim.md に従う
## 移植しない・人間判断
- COPYBOOK の REDEFINES を含む構造 → gap-inventory.md に記録し保留
- 日次バッチの実行順序に依存する初期化 → 移行順の決定後に扱う負荷試験は、ルールだけで訳したものと、腕のいい担当者のつもりで訳したものを比べ、差分から新しいルールを起こす形です。BunのZigからRustへの移植では、1,448ファイルに展開する前にこの試験で重大な問題を2つ捕まえました。ただし、この比較は元と同じ構造を保つ移植でのみ成立します。作り直しの移行では、設計文書を敵対的なレビュアーに攻撃させる形になります。
全体の翻訳の段階では、実装役に小さいモデル、レビュー役に大きいモデルを充てられます。Anthropic社内のPythonからTypeScriptへの移植では、実装側の12のサブエージェントにSonnetが使われました。作業キューは機械的にします。翻訳済みファイルがディスクにあるかで完了を判定し、未処理をバッチに分ける仕組みなら、途中で止まっても再開できます。
同じミスがファイルをまたいで繰り返されたら、個々を直しません。ルールブックに1文足し、影響したバッチだけを再生成します。コードに手でパッチを当てないのがこの型の規律です。
手順5: 非対話モードで大量ファイルに流し、ドキュメントを復元する
ループの実装役をClaude Codeで回すなら、非対話モードが土台になります。claude -p はCIやバッチ処理向けの実行方法で、標準入出力がUnixのツールと同じように使えます。
git log --oneline -20 | claude -p "summarize these recent commits"権限は --allowedTools で絞ります。プレフィックス一致の書式が使え、たとえば Bash(git diff *) は git diff で始まるコマンドだけを許可します。スペースを入れずに Bash(git diff*) と書くと git diff-index にも一致するため、スペースは省けません。
未処理ファイルを1件ずつ非対話で流す骨格は、次のようになります。ファイル名・ルールブックのパスは例です。
for f in $(cat pending.txt); do
claude -p "rules/rulebook.md に従い $f を Java へ移行し、
移行後に同じ入力での出力が一致することをテストで確認して" \
--allowedTools "Read,Edit,Bash(./gradlew test *)"
done並列の分離には、worktreeが使えます。claude --worktree 名前 で、別のブランチ上に独立したチェックアウトを作れます。ただしリポジトリに最初のコミットが要り、コミットが無いと Failed to resolve base branch "HEAD" で失敗します。別のターミナルで名前を変えて同じコマンドを実行すると、独立した並列セッションが立ち上がり、編集が衝突しない状態を作れます。
ドキュメントの復元も同じループの副産物です。データの流れを入力から出力まで追えば、誰も作った覚えがないのに全員が頼っている処理パイプラインの図と説明文を作れます。移行前に文書化する対象を決め、コードから起こしたワークフロー文書を、業務担当者に見てもらって確認する。この順番なら、コードに埋まっていた知識が保存されます。
大規模移行で残る限界と、判断が要る場所
ここまでの流れは、AIが全部やる話ではありません。実績と限界を分けて読む必要があります。
言語移植の実績は次のとおりです。
- BunをZigからRustへ。約100万行が2週間足らずで生成され、既存テストスイートは100%がCIで通ってからマージされた。マージ後に19件の回帰が見つかり、すべて修正済み
- Python製のツールを、週末のうちに16万5千行のTypeScriptへ。数百のエージェント、8つのフェーズゲート、3回の敵対的レビュー、全コマンドの出力を元のPython版と突き合わせる最終確認を経ている
費用と代償も明示されています。Bunの移行は、キャッシュなしの入力約59億トークン(5.9 billion)と出力約6.9億トークン(690 million)を使い、API価格でおよそ16万5千ドルでした。移行後のコードの約4%が unsafe ブロックに入っており、多くはC/C++との境界にある1行のポインタ操作です。
この規模の話は、COBOLの基幹システムにそのまま当てはまるわけではありません。ガイド自身が「この手順を鵜呑みにしないこと」と注記しており、移行ごとに事情が違うので、まずClaudeと自分の移行を計画してから進める前提です。
新旧の出力を突き合わせる審判は、COBOLからJavaへのリライトでも作れます。成立しなくなるのは、ルールだけの訳と熟練者の訳を比べる負荷試験のほうです。この比較は元と同じ構造を保つ移植(BunのZigからRustへ)でしか意味を持たず、作り直しの移行では設計文書への敵対的レビューがその役を担います。リライトの成否は、出力の審判に加えて、変換ルールの穴を誰がどこで見つけるかで決まります。
ソリューションページには、CI/CDやバージョン管理との統合、エンタープライズ向けのセキュリティ・コンプライアンスも掲げられています。詳細な導入条件やプランごとの提供範囲はページ上には出ていません。契約や導入の相談は、ページの「Speak with sales」から進める形です。
どこから始めるかの早見表
| 状況 | 最初にやること | 詳細 |
|---|---|---|
| テストが無い小規模なコード | 最初にやること現状の振る舞いを固定するテストを書く | 詳細リファクタリングの手順 |
| 依存が不明な大規模レガシー | 最初にやることplan modeで依存関係の地図と結合の強い順を出す | 詳細手順1 |
| 移行の合格基準が無い | 最初にやること新旧を突き合わせるスクリプトを作り、壊れたコードで落ちることを確認する | 詳細手順2 |
| 数百ファイル以上を同じルールで移す | 最初にやることルールブックとギャップ一覧を作り、少数ファイルで負荷試験をする | 詳細手順4 |
| 規制産業の基幹システム | 最初にやること提携企業の事例を参照し、導入は営業窓口へ | 詳細DXCとの提携 |
まとめ
Claude Codeのコードモダナイゼーションは、コードを書き換える力より、レガシーを読み解く力と検証を回し続ける力に重心があります。依存関係の地図、合否を返す物差し、1コンポーネントずつの移行、ルールブックを直すループ。この4つが揃うと、費用と期間の見立てが変わります。
一方で、何から移すか、どこまでを合格とするかは人間の判断のままです。最初は境界がはっきりした単一のコンポーネントで、分析から検証までを一巡させることから始めます。