# Claude Code로 대규모 코드 마이그레이션을 수행한 방법

> Clean Markdown view of GeekNews topic #31855. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=31855](https://news.hada.io/topic?id=31855)
- GeekNews Markdown: [https://news.hada.io/topic/31855.md](https://news.hada.io/topic/31855.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2026-07-27T10:03:01+09:00
- Updated: 2026-07-27T10:03:01+09:00
- Original source: [claude.com](https://claude.com/blog/ai-code-migration)
- Points: 8
- Comments: 0

## Topic Body

- Anthropic 개발자들은 Claude Fable 5, Claude Opus 4.8과 동적 워크플로를 이용해 최근 한 달간 수만~수십만 줄 규모의 패키지 10개를 이전했으며, 개별 코드를 고치는 대신 **코드를 생성하는 반복 과정**을 개선함  
- Bun의 Zig→Rust 이전은 2주 미만에 **100만 줄**을 생성하고 병합 전 기존 테스트를 100% 통과했으며, Python→TypeScript 프로젝트는 주말 동안 16만5,000줄을 옮기면서 수백 개 에이전트와 8개 단계 관문, 3회의 적대적 검토를 활용함  
- 대규모 이전은 작업을 병렬화할 수 있고 기존 코드가 명세와 정답 역할을 하며, 컴파일·테스트 실패가 다음 작업 대기열을 자동 생성하므로 **객관적인 검증 루프**를 구성하기 좋음  
- 판정 기준 준비부터 규칙집·의존성 지도·차이 목록 작성, 규칙 스트레스 테스트, 전체 번역, 컴파일, 실행, 동작 비교까지 단계적으로 진행하며, 반복 오류는 파일별로 수정하지 않고 **상위 규칙을 고쳐 재생성**함  
- 비용은 여전히 수만~수십만 달러 이상이지만 실패한 브랜치를 폐기하고 다시 시도할 수 있으며, Bun 이전은 API 가격 기준 약 16만5,000달러를 사용한 뒤 메모리 사용량 감소, 바이너리 크기 19% 축소, 실제 워크로드 성능 2~5% 향상을 달성함  
  
---  
  
### 코드가 아닌 생성 루프를 개선하는 방식  
- **AI 코드 마이그레이션**은 에이전트가 프로덕션 코드베이스를 새로운 언어나 프레임워크로 옮기는 방식임  
  - 엔지니어가 파일을 직접 번역하는 대신 이전 규칙과 검증 루프를 작성함  
  - 에이전트는 새 코드의 동작이 원본과 일치할 때까지 번역·컴파일·테스트를 반복함  
  - 과거 여러 해가 걸리던 프로젝트를 수주 단위로 단축할 수 있음  
- Anthropic에서는 Claude Fable 5, Claude Opus 4.8과 [동적 워크플로](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code)를 사용해 한 달 동안 수만~수십만 줄 규모의 코드 패키지 10개를 이전함  
- 핵심 운영 원칙은 생성된 코드를 직접 수선하는 것이 아니라 **그 코드를 만든 루프를 수정**하는 것임  
  
### 실제 마이그레이션 사례  
- ## Bun의 Zig→Rust 이전  
  - Jarred Sumner는 Claude Code로 [Bun을 Zig에서 Rust로 이전](https://bun.com/blog/bun-in-rust)함  
  - 2주 미만에 **100만 줄**의 코드를 생성함  
  - 병합 전 CI에서 Bun의 기존 테스트 스위트를 100% 통과함  
  - 병합 후 발견된 회귀 19건은 모두 수정됨  
  - Rust 포트는 6월 Claude Code에 탑재됨  
  - Bun은 월간 다운로드가 1,000만 회를 넘고 Claude Code 내부에서도 광범위하게 사용됨  
- ## Python→TypeScript 이전  
  - Mike Krieger는 주말 동안 Python 코드베이스를 **16만5,000줄의 TypeScript**로 이전함  
  - 수백 개 에이전트, 8개 단계 관문, 3회의 적대적 검토를 사용함  
  - 모든 명령의 출력을 Python 원본과 비교하는 최종 동등성 검사를 수행함  
  - 전체 마이그레이션 결과를 버리고 규칙과 워크플로를 수정하는 과정을 반복했으며, 세 번째 실행 결과를 채택함  
  
### 언어 이전을 다시 검토할 조건  
- 최초 개발 이후 기술 환경이 바뀌어 기존 절충점이 제약으로 작용하거나, 더 나은 접근법이 등장하거나, 원래 생태계가 축소됐다면 이전을 검토할 수 있음  
- Zig는 C 수준 성능과 단순성을 제공해 혼자 Bun을 개발하던 초기 환경에 적합했지만, 그 단순성에는 알려진 절충점이 있었음  
- 과거에는 언어 이전을 위해 로드맵을 중단하고 여러 분기의 자원을 투입해야 했음  
  - 두 코드베이스를 수분기 또는 수년간 병행 유지해야 할 수 있었음  
  - 최종 동작 일치율이 90%에 그치면 시작 전보다 더 큰 유지보수 문제가 생길 수 있었음  
  - 이제는 실패한 브랜치를 삭제하고 다시 실행하는 선택지가 생김  
- 100만 줄 이전이 더 이상 4년간 엔지니어링 비용 **300만~400만 달러**를 요구하지는 않지만, 여전히 수만~수십만 달러 이상이 들 수 있음  
  - Bun 이전은 캐시되지 않은 입력 토큰 59억 개와 출력 토큰 6억9,000만 개를 소비함  
  - API 가격 기준 비용은 약 16만5,000달러임  
  - Mike의 포트에서 핵심 구간은 2,700만 토큰을 사용함  
- 이전의 사업적 근거가 반드시 존립을 좌우할 정도일 필요는 없어졌으며, 1년간 반복된 메모리 버그 수정이나 만성적인 병목 하나로도 정당화할 수 있음  
- ## Python 빌드 병목 해소  
  - Mike의 내부 도구는 사용자에게 단일 바이너리로 제공됐지만, Python 도구 체인으로 플랫폼별 바이너리를 만드는 데 약 8분이 걸렸음  
  - 전체 빌드 매트릭스에서는 릴리스마다 약 **30분**을 기다려야 했음  
  - TypeScript 이전 후 컴파일은 약 2초로 줄고 바이너리 시작은 6배 빨라졌으며, 별도의 배포 파이프라인도 폐기함  
  
### AI 에이전트가 이전에 적합한 이유  
- **병렬 작업**이 가능함  
  - 파일과 크레이트 등 수천 개의 독립 단위로 나눠 여러 에이전트가 동시에 처리할 수 있음  
- 기존 코드가 명확하고 포괄적인 **명세** 역할을 함  
  - 번역 에이전트용 지침을 만드는 핵심 참고 자료로도 활용할 수 있음  
- 테스트 스위트가 내장된 판정자 역할을 함  
  - 검증이 객관적이면 사람이 품질을 계속 중재하지 않아도 모델이 정답을 기준으로 며칠간 반복 작업할 수 있음  
- 컴파일이나 테스트 실패가 자동으로 다음 작업 항목이 되므로 별도의 작업 대기열을 작성할 필요가 줄어듦  
- 일관성과 예외 처리를 루프에 포함할 수 있음  
  - 검토자는 각 문제를 위반된 규칙과 연결함  
  - 예외를 해결한 방법은 이후 모든 에이전트가 따르는 규칙으로 바뀜  
  - 조용한 동작 불일치 대신 규칙 위반이 명시적인 작업 항목이 됨  
- Fable과 Opus 4.8은 하위 에이전트의 병렬 작업을 위임·지휘·검증하고, 목표에 도달할 여러 경로를 찾는 데 사용됨  
- 여러 모델 등급을 조합하는 **자문 패턴**으로 토큰 사용량을 최적화함  
  
### 사전 조건: 원본과 포트를 동등하게 판정하기  
- 이전을 시작하기 전에 원본과 대상 코드를 같은 기준으로 평가할 강력한 **판정자**가 필요함  
  - 판정자가 없으면 성공 기준과 종료 조건도 없음  
  - 원본 언어의 내부 함수에 의존하는 테스트는 대상 코드에서 그대로 실행되지 않을 수 있음  
- 기존 테스트를 외부 호출로 표현할 수 있는 테스트와 포트되지 않을 내부 구현 의존 테스트로 분류함  
- 외부 동작 테스트는 원본과 포트 양쪽에서 실행할 수 있는 단언으로 다시 작성함  
  - 적대적 에이전트가 재작성 과정에서 단언이 약해지지 않았는지 검증함  
- 판정자를 원본 코드에 실행해 성공하는지 확인한 뒤, 의도적으로 망가뜨린 코드에서는 실패하는지도 검사함  
- Jarred는 제3의 언어인 TypeScript로 작성된 대규모 테스트 스위트를 보유했음  
- Mike는 실제 사용 시나리오 7개로 **동등성 하네스**를 만들고 모든 동작 변화를 수정해야 할 버그로 취급함  
  
### 1단계: 규칙집·의존성 지도·차이 목록  
- 기반 산출물은 단순 번역 결과가 아니라 리팩터링할 위치의 목록, 번역 방식의 규칙집, 작업 순서를 정하는 의존성 지도임  
- 작성 순서가 중요함  
  - 먼저 규칙집의 기본값을 정해야 그 기본값으로 처리할 수 없는 항목을 차이 목록으로 정의할 수 있음  
  - 규칙집과 차이 목록은 공동 감사를 통해 함께 검증함  
- ## 규칙집  
  - [규칙집](https://github.com/anthropics/code-migration-kit-with-claude-code/blob/main/templates/RULEBOOK.md)의 형태는 새 코드가 기존 구조를 유지할지 완전히 재설계할지에 따라 달라짐  
  - Jarred처럼 구조를 유지하면 언어 간 타입과 관용 표현의 **대응표**가 중심이 되고, 번역하기 어려운 구성요소는 차이 목록을 참조함  
  - Mike처럼 재설계하면 규칙집이 설계 문서 역할을 함  
  - Jarred는 Claude와 대화하며 모호한 영역마다 정책을 만들고, 예상되는 8개 오류 범주를 각각 검토하도록 하위 에이전트 8개를 구성함  
- ## 의존성 지도  
  - 병렬 이전에서는 어떤 파일을 먼저 옮기고 어떤 파일을 같은 배치에 넣을지 결정하기 위해 파일 의존성을 파악해야 함  
  - 명시적 매니페스트가 없는 레거시 코드와 C/C++, Python 등의 코드베이스에서는 의존성을 직접 발견하고 지도화해야 함  
  - Claude Code 에이전트는 결정론적 스크립트를 작성·실행하고 검토·수정하는 루프로 지도를 생성할 수 있음  
  - 일반화된 예시는 [의존성 지도 프롬프트](https://github.com/anthropics/code-migration-kit-with-claude-code/blob/main/prompts/01-dependency-map.md)에서 확인할 수 있음  
- ## 언어 차이 목록과 회의적 검토자  
  - **차이 목록**은 기존 코드에 암묵적으로 들어 있지만 대상 언어에서는 명시해야 하는 지식을 기록함  
  - Zig→Rust에서는 메모리 관리 방식이 주요 차이였음  
  - Zig에서는 호출자가 버퍼를 해제해야 한다는 사실이 주석에만 있을 수 있고, 해제를 빠뜨려도 컴파일되며 누수는 실행 중 발견됨  
  - Rust에서는 소유권이 호출자에게 이동하고 메모리가 자동 해제되며, 이동 후 사용이나 이중 해제는 컴파일되지 않음  
  - Python→TypeScript에서는 인터페이스와 계약이 주요 차이였음  
  - Python은 전달받는 객체와 반환값의 형태를 선언하지 않아도 됨  
  - TypeScript에서는 메서드, 인수, 반환 형태의 계약을 작성해야 컴파일됨  
  - Jarred는 번역 전에 차이를 목록화했고 Mike는 먼저 번역한 뒤 감사 과정에서 목록을 만들었으므로, 프로젝트에 따라 두 접근을 모두 사용할 수 있음  
  - 일반화된 예시는 [차이 목록 생성 프롬프트](https://github.com/anthropics/code-migration-kit-with-claude-code/blob/main/prompts/02-gap-inventory.md)에서 확인할 수 있음  
  
### 2단계: 규칙 스트레스 테스트  
- 전체 이전에 앞서 소규모 **시험 이전**으로 규칙집을 흔들어 보고 문제를 찾음  
- Jarred는 세 가지 에이전트 작업을 비교함  
  - 첫 번째 에이전트는 규칙집에 따라 파일 3개를 번역함  
  - 두 번째 에이전트는 숙련된 Rust 엔지니어처럼 같은 규모를 번역함  
  - 세 번째 에이전트는 두 결과의 차이를 바탕으로 새로운 번역 규칙을 작성함  
- 이 과정에서 1,448개 파일 전체로 확산되기 전에 중대한 문제 2개를 발견함  
- 이 방식은 동일 파일의 두 번역 결과를 줄 단위로 비교할 수 있는 **구조 보존형 이전**에서만 작동함  
- Mike처럼 재설계하는 경우에는 적대적 검토자가 설계 문서를 공격하고, 폐기 가능한 종단 간 실행으로 검증해야 함  
- 시험에서 번역한 파일은 모두 버려야 하며, 목적은 점진적인 코드 진척이 아니라 규칙 개선임  
- 일반화된 작업 예시는 [스트레스 테스트 프롬프트](https://github.com/anthropics/code-migration-kit-with-claude-code/blob/main/prompts/03-stress-test.md)에서 확인할 수 있음  
  
### 3단계: 전체 코드 번역  
- 이후 단계는 모두 **구현→검토→수정**의 다중 에이전트 루프를 사용함  
- 대량 구현은 작은 모델에 맡기고 검토는 큰 모델이 담당할 수 있음  
  - Mike는 핵심 이전을 병렬화할 때 Claude Sonnet 하위 에이전트 12개를 사용함  
- 작업 대기열은 기계적으로 관리함  
  - 배치 스크립트가 번역 파일의 디스크 존재 여부로 완료 상태를 판단함  
  - 남은 파일을 구현 에이전트용 배치로 나눔  
  - 실행할 때마다 디스크 상태에서 대기열을 재구성하므로 기본적으로 중단 후 재개할 수 있음  
- 에이전트가 지나치게 조심스럽게 적은 양만 처리한다면, 다음 단계에서 컴파일러가 오류를 잡는다는 맥락과 함께 더 직접적으로 지시할 수 있음  
- 확신을 갖고 처리하지 못한 항목은 `// TODO(port): &lt;reason&gt;`으로 표시하고 4단계에서 해결함  
- 이후 작업 목록은 컴파일 오류, 스모크 테스트 충돌, 테스트 실패에서 자동 생성됨  
- ## 적대적 검토와 규칙 갱신  
  - 독립된 컨텍스트의 적대적 검토자 2개가 구현 결과를 평가하고, 의견이 다르면 세 번째 에이전트가 판정함  
  - 여러 파일에서 같은 오류가 반복되면 파일을 개별 수정하지 않음  
  - 규칙집에 문장 하나를 추가하고 영향을 받은 배치를 다시 생성함  
  - 번역 단계에서도 규칙집은 계속 확장되며, 규칙과 어긋난 코드를 수작업으로 패치하지 않음  
- ## 컴파일러 배치 위치  
  - 컴파일 시간이 짧으면 번역 루프 안에 포함할 수 있음  
  - Mike는 TypeScript 컴파일이 단위별로 수초 안에 끝나므로 모든 루프에서 실행함  
  - 컴파일이 오래 걸리면 다음 단계로 미룸  
  - Jarred는 `cargo` 실행에 수분이 걸려 번역 루프에서 컴파일러 사용을 금지함  
  - 이 단계부터 프롬프트는 짧아지며, 예시는 [번역 시작 프롬프트](https://github.com/anthropics/code-migration-kit-with-claude-code/blob/main/prompts/04-translation-kickoff.md)에서 확인할 수 있음  
  
### 4~6단계: 컴파일·실행·동작 일치  
- 세 단계는 같은 루프 구조를 공유하며, 뒤로 갈수록 필요한 인간 판단이 줄어듦  
- 언어와 프로젝트 규모에 따라 **컴파일 단계**는 전체 번역 단계에 흡수될 수 있음  
- ## 4단계: 컴파일  
  - Jarred는 오케스트레이터 스크립트가 전체 워크스페이스에서 컴파일러를 한 번 실행하도록 구성함  
  - 수정 에이전트들이 오류 목록을 병렬 처리하고 적대적 검토를 거친 뒤 다시 빌드하는 과정을 반복함  
  - 오류 목록 검토는 개별 오류가 아니라 시스템적 문제를 발견하는 데 사용함  
  - Zig의 지연 컴파일이 허용하던 순환 임포트를 수정한 뒤 Rust 모듈 오류 수천 개가 발생함  
  - 어떤 의존성을 삭제·이동하거나 경계를 재구성할지 분류하는 로직을 루프에 추가함  
- ## 5단계: 실행과 스모크 테스트  
  - 스모크 테스트에서 발생한 충돌이 컴파일 오류 목록과 같은 **기계적 정답** 역할을 함  
  - 문제를 개별 처리하지 않고 근본 원인별 범주로 묶은 뒤 적대적 하위 에이전트가 검토함  
- ## 6단계: 원본과 동작 비교  
  - 번역·컴파일·스모크 테스트를 마친 코드를 분할하고, 사전 단계에서 준비한 테스트 스위트를 원본과 포트에 실행함  
  - 수정 에이전트는 실패한 테스트와 양쪽 코드베이스를 함께 검토하며, 적대적 검토자가 수정 결과를 확인함  
  - [빌드 데몬](https://github.com/anthropics/code-migration-kit-with-claude-code/blob/main/scripts/build_daemon.sh)만 바이너리를 다시 빌드할 수 있도록 제한함  
  - 수정 에이전트는 패치를 작성하고, 데몬은 패치를 모아 한 번만 재빌드함  
  - 영향받은 테스트를 다시 실행해 결과를 반환함  
  - 여러 에이전트가 비싼 빌드를 각각 실행하지 않도록 작업을 직렬화함  
  - 같은 실패가 여러 테스트에서 반복되면 버그를 만든 상위 규칙을 수정하고, 그 규칙이 영향을 준 파일만 재생성함  
- ## 테스트 스위트가 없는 경우  
  - Mike는 실제 시나리오 7개를 원본 Python 코드와 새 포트에 실행하고 결과를 비교하는 작은 스크립트를 Claude로 생성함  
  - 실패한 시나리오마다 별도 수정 에이전트를 배정하고 7개가 모두 통과할 때까지 반복함  
  - Claude가 자체 종단 간 테스트 스위트도 설계해 밤새 자율 실행함  
  - 오류를 수정하고 다시 실행하는 작업을 나흘 밤 동안 반복함  
  - 미리 작성한 시나리오 목록으로 예측하기 어려운 사소한 사용성 문제까지 발견함  
  - 기존 테스트가 없어도 원본 코드베이스를 정답으로 삼아 Claude가 판정자를 만들 수 있음  
  
### 반복 실행에서 확인된 운영 원칙  
- 가이드를 그대로 따르기보다 프로젝트 특성에 맞춰 Claude와 이전 계획을 세운 뒤 착수해야 함  
- 개별 실패는 수정 에이전트가 처리하도록 두고, 사람은 반복되는 **오류 패턴**에 집중해야 함  
- 검토는 적대적으로, 검증은 기계적으로 구성함  
  - 적대적 검토는 장시간 작업에 유용하며 추가 토큰 소비를 감수할 가치가 있을 수 있음  
  - 컴파일러, diff, 테스트 스위트 같은 스크립트를 최종 판정자로 사용함  
- 모든 작업에 가장 큰 모델을 사용하지 않음  
  - 작은 모델은 대량 구현 병렬화에 활용함  
  - 가장 큰 모델은 검토와 다른 에이전트가 따를 규칙 작성에 집중함  
- 사람의 작업 시간은 규칙집과 스트레스 테스트에 **선투입**해야 하며, 이후 과정은 대부분 대기열을 소진하는 작업임  
- 완료 상태는 ‘출력 파일이 디스크에 존재함’처럼 기계적으로 판별할 수 있어야 하고, 대기열은 재개 가능해야 함  
  
### Bun 이전 결과와 제약  
- Bun의 Rust 포트는 프로덕션에서 운영 중이지만, Rust 코드의 약 **4%가 `unsafe` 블록** 안에 있음  
  - 대부분 C/C++ 경계의 한 줄짜리 포인터 연산임  
- 도구로 탐지 가능한 모든 메모리 누수를 수정함  
  - 빌드를 2,000회 반복한 벤치마크에서 메모리 사용량이 6,745MB에서 **609MB**로 감소함  
- Linux와 Windows 바이너리 크기는 19% 줄어듦  
- 언어 간 최적화를 통해 HTTP 서비스와 `next build`, `tsc` 같은 실제 워크로드 성능이 2~5% 향상됨  
- 대규모 이전에서는 생성된 코드 한 줄 한 줄보다 **루프가 만든 결과와 반복 패턴**을 검토해야 함  
  
### 관련 자료  
- [Migration starter kit](https://github.com/anthropics/code-migration-kit-with-claude-code): 본문의 절차를 일반화한 템플릿이며 실제 두 포트가 이 키트로 실행된 것은 아님  
- [Code-modernization plugin](https://github.com/anthropics/claude-plugins-official/tree/main/plugins/code-modernization): 언어 포트가 아닌 레거시 현대화와 프레임워크 업그레이드용 플러그인  
- [Dynamic workflows in Claude Code](https://claude.com/blog/introducing-dynamic-workflows-in-claude-code): Claude Code의 동적 워크플로 소개

## Comments



_No public comments on this page._
