「100万行コード移行は4年がかり」はもう昔話 Claude Codeで「2週間」に縮める6ステップ/ベストプラクティス:JavaScriptランタイム「Bun」のコードベースをZigからRustに移行(2/3 ページ)
Anthropicは、本番コードベースを別の言語に移植する大規模なコード移行プロジェクトをどのように実施しているかを解説したブログ記事を公開した。
ステップ1:ルールブック、依存関係マップ、ギャップインベントリを作成する
ルールブックは、コードの翻訳方法を定義する。その具体的な形は、「新しいコードが元の構造を維持するかどうか」(サムナー氏のプロジェクト)、「新しいコードを完全に再設計するかどうか」(クリーガー氏のプロジェクト)などで決まる。前者では、ルールブックは、型やイディオムを対応付けるルックアップテーブルが中心となり、後者では設計文書となる。
サムナー氏は、Claudeと対話しながらルールブックを構築し、よくある失敗モードの8つのカテゴリーを検査する8つのサブエージェントにレビューさせた。
依存関係マップは、並列ワークストリームの順序付けと関連ファイルのバッチ化に使う。明示的なマニフェストを持つエコシステムもあるが、「C」「C++」、Pythonのような言語では、Claude Codeがエージェントを展開し、依存関係を発見する決定論的スクリプトを作成、実行する。
ギャップインベントリは、ルールブックのデフォルト(既定)では扱えない暗黙知を捕捉する。ZigからRustへの移行では、手動メモリ管理が、PythonからTypeScriptへの移行では、Pythonが宣言を強制しないインタフェースと契約がこれに当たる。
Zigでは、メモリ解放を忘れた呼び出し側もコンパイルを通過し、リークは実行時に初めて表面化する。
fn readConfig(allocator: std.mem.Allocator) ![]u8 {
const buf = try allocator.alloc(u8, 1024);
// ...fill buf...
return buf; // caller must free this -・but only the comment says so
}
// A caller that forgets 'defer allocator.free(buf)' still compiles -・the leak only surfaces at runtime.
Rustでは、所有権が呼び出し側に移動し、メモリは自動的に解放される。
fn read_config() -> Vec<u8> {
let buf = vec![0u8; 1024];
// ...fill buf...
buf // ownership moves to the caller; memory is freed automatically
}
// Use it after it's moved? Free it twice? Neither compiles.
// Forget to free it? There's no free call to forget -・drop is automatic.
Pythonでは、どのオブジェクトが渡されるかは、コードベース全体を読まないと分からない。
def register(handler):
handler.setup()
return handler.run({"retries": 3})
# Any object with .setup() and .run() works here. Which objects actually get passed in? Read the whole codebase to find out.
TypeScriptでは、契約を明示的に記述しなければ、コンパイルを通過しない。
interface RunResult { ok: boolean }
interface Handler
{ setup(): void;
run(opts: { retries: number }): Promise<RunResult>;
}
function register(handler: Handler): Promise<RunResult> {
handler.setup();
return handler.run({ retries: 3 }); }
// The contract must be written down before this compiles
ステップ2:ルールをストレステストする
このステップは、大規模な移行に向けた“試運転”となる小規模な移行だ。
サムナー氏は、エージェントの一つにルールブックを使って3つのファイルを翻訳させ、別のエージェントに「シニアRustエンジニアのように」同じファイルを翻訳させ、さらに別のエージェントに、両者の差分を用いて新しい翻訳ルールを作らせた。
これにより、全1448ファイルに拡散する前に、2つの重大な問題を発見できた。
この種のストレステストは、「構造を維持する移行」でのみ有効だ。クリーガー氏のプロジェクトのように、コードを完全に再設計する場合は、同等なテストとしては、敵対的レビュアーを通じて設計文書を直接検証し、その後、使い捨てのエンドツーエンド実行で妥当性を確認することになる。
いずれの場合も、翻訳済みファイルは破棄する。このステップの目的はルールを洗練させることであり、作業を進めることではない。
ステップ3:全てを翻訳する
以降のステップでは、「実装、レビュー、修正」というマルチエージェントループを実行する。実装は、小規模なモデルに任せられる。クリーガー氏は、Claude Sonnetで12のサブエージェントを展開した。レビュアーには、より大規模なモデルが割り当てられる。
作業キューは、機械的に管理する。バッチスクリプトが「翻訳済みファイルがディスク上に存在するかどうか」で完了を判定するので、移行は構造的に再開可能になる。エージェントが自信を持って翻訳できない箇所は、「TODO(port)」コメントを付けて後のステップに回す。
2つの敵対的レビュワーが別々のコンテキストで成果物を評価し、意見が割れた場合は3つ目のエージェントが裁定する。レビュワーが同じミスを繰り返し検出したら、修正はファイル単位では行わない。ルールブックに1文を追加し、影響を受けたバッチを再生成する。
重要な設計判断の一つが「コンパイラをどこに置くか」だ。クリーガー氏は、ユニットを数秒でチェックできるTypeScriptコンパイラを全ループ内で実行した。サムナー氏は、コンパイラをループから排除し、コンパイルを次のステップに先送りした。cargoに数分かかるからだ。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
Anthropic、Mythos級モデル「Claude Fable 5」を提供開始 5000万行のRubyコード移行を2カ月から1日に
Anthropicは、「Claude Mythos Preview」と同等以上の性能に安全対策を加えた最新AIモデル「Claude Fable 5」の一般提供を開始した。コーディングや専門的な実務などで過去最高水準の性能をうたう。同時に、「Project Glasswing」を通じて、安全対策の一部を解除した「Claude Mythos 5」を限定提供する。
塩漬け“17年”のレガシー刷新作業を「2年→2日に短縮」 常石造船の事例で見えた、AIプロジェクトの成否
AIエージェントの活用が本格化する中、レガシーシステム刷新の工程が、AIエージェントを活用することで2年から2日に短縮するという事例も生まれた。一方で多くのAIプロジェクトではPoCで止まり、本番運用への障壁を乗り越えられていないという現状もある。API管理ベンダーKongが事業戦略説明会で語った常石造船の事例などを踏まえて、成否の条件を考える。
COBOLも古いJavaももう“塩漬け”にしなくていい? AIを制御し「数年を数日まで」短縮できるレガシー刷新の今
老朽化し、仕様を知る担当者も退職するなどして塩漬けにされる「レガシーシステム」。調査だけで億単位のコストを要し、ビジネス変革の足かせになりかねない難題にAI駆動開発でどうアプローチできるのか。Scalarが取り組むAIエージェントを使ったモダナイゼーションについて聞いた。
生成AIの品質を“AIで測る”――「LLM as a Judge」を機能させる3つの要素
AIの出力を別のAIが評価する手法「LLM as a Judge」。その基礎をdotDataがブログで解説した。AIにAIを評価させながら、その品質を確保するにはどのような手法が有効なのか。
AIに「絶対するな」は通じない、Anthropicが明かすClaude Code使いこなし術まとめ
2026年のAIコーディング現場は「Claude Code」の採用が増えており、その便利さを現場で実感している一方で、新たな課題が顕出されていると思います。Anthropicが公式ブログで提供したClaude Codeの使いこなし術をまとめました。


