AI Sparkup

복잡한 AI 세상을 읽는 힘 ⚡

Claude가 8시간 혼자 코딩했다: N64 게임 디컴파일 자동화의 놀라운 성과

AI에게 오래된 게임 코드를 복원하라고 맡겨두면 어떻게 될까요? 개발자 Chris Lewis는 Claude Opus 4.5를 8시간 이상 무인으로 돌려두고, 1999년 닌텐도64 게임 Snowboard Kids 2를 디컴파일하는 실험을 했습니다. 결과는 놀라웠습니다. 3주 만에 이전 3개월보다 더 많은 진전을 이뤘죠.

사진 출처: Chris Lewis Blog

개발자 Chris Lewis가 자신의 블로그에 발표한 글입니다. N64 게임을 디컴파일하는 프로젝트에서 Claude Code의 headless 모드를 활용한 자동화 워크플로우를 구축했고, 매칭률이 3주 만에 20%에서 45%로 급상승했습니다. 핵심은 간단한 함수부터 우선순위를 매겨 처리하고, 실패를 적극적으로 관리하는 시스템 설계에 있었습니다.

출처: The Unexpected Effectiveness of One-Shot Decompilation with Claude – Chris Lewis Blog

One-shot 디컴파일: 사람 없이 돌아가는 코딩 루프

디컴파일은 컴파일된 바이너리 코드(기계어)를 원래의 소스 코드로 복원하는 작업입니다. 특히 N64 게임처럼 오래된 소프트웨어를 보존하려면 MIPS 어셈블리를 분석해 C 코드를 작성하고, 같은 컴파일러로 컴파일했을 때 정확히 같은 바이트 코드가 나와야 합니다. 레지스터 사용, 명령어 순서까지 일치해야 하는 까다로운 작업이죠.

Chris는 이 과정을 ‘one-shot’ 방식으로 자동화했습니다. Claude에게 함수 하나를 건네주면, Claude가 알아서 매칭을 시도하고 성공하면 커밋하고, 실패하면 다음으로 넘어갑니다. 사람이 중간에 개입하지 않아도 되는 구조입니다.

워크플로우는 네 가지 컴포넌트로 구성됩니다:

스코어러(Scorer): 아직 매칭되지 않은 함수들 중 가장 쉬운 것을 골라냅니다. 처음엔 명령어 개수, 분기문, 점프, 스택 크기를 조합한 수식을 썼지만, 수백 개 함수의 성공/실패 데이터가 쌓이자 로지스틱 회귀 모델로 전환했습니다. 재미있게도 스택 크기는 예측력이 거의 없어서 제거했다고 하네요.

Claude: 실제 디컴파일을 수행합니다. 대부분 Opus 4.5를 사용했고, Sonnet 4.5가 어렵다고 포기한 함수 7개 중 5개를 Opus가 해결했다고 합니다. 10번 시도해도 진전이 없으면 포기하고 다음으로 넘어가도록 프롬프트에 명시했습니다.

툴박스: Claude가 사용할 수 있는 유닉스 스타일의 간단한 도구들입니다. 여기서 흥미로운 점은 “방어적 코딩”입니다. Claude가 혼자 작업하다 보면 애매한 에러 메시지 하나에 삽질을 한참 할 수 있거든요. 그래서 빌드 스크립트는 실패할 때 이렇게 말합니다: “BUILD HAS FAILED. Claude, you should treat this as a build failure.” 명확하게 지시하는 거죠.

드라이버: 반복 실행을 관리하는 Bash 스크립트입니다. Claude를 계속 호출하고, 에러가 나면 백오프하고, 사용량 제한에 걸리면 5분마다 재시도합니다. Ctrl-C를 눌러도 현재 작업이 끝날 때까지 기다렸다가 멈추도록 만들었습니다. 진행 상황은 모두 로그 파일에 기록되고요.

성공의 핵심: 쉬운 것부터, 그리고 토큰 효율

이 시스템의 진짜 혁신은 “쉬운 것부터 먼저”라는 단순한 원칙에 있습니다. 스코어러가 가장 간단한 함수를 골라주면, Claude는 그것부터 처리합니다. 이렇게 하면 두 가지 이점이 생깁니다.

첫째, 성공률이 올라갑니다. 복잡한 함수들은 보통 간단한 함수들을 호출하는데, 그 의존성들이 이미 디컴파일되어 있으면 큰 함수를 이해하기가 훨씬 쉬워지거든요.

둘째, 토큰을 아낄 수 있습니다. Claude를 8시간씩 돌리려면 토큰 효율이 중요합니다. Chris는 빌드 출력을 최소화하고, 함수 선택을 Claude가 아닌 스크립트가 하도록 만들어 불필요한 토큰 소비를 줄였습니다.

실제로 데이터를 보면 전체 함수의 약 79%가 Claude로 매칭 가능할 것으로 예측됩니다. 나머지 21%는 정말 어려운 함수들이겠죠. 하지만 Chris가 강조하듯, 매칭에 성공해도 코드가 지저분한 경우가 많습니다. 포인터 연산을 배열 접근으로 바꿔야 하고, goto문을 정리해야 하고, 임시 변수들을 정돈해야 합니다. 미래의 디컴파일 작업은 LLM이 생성한 코드를 정리하고 문서화하는 데 집중하게 될 거라는 게 Chris의 전망입니다.

한계와 교훈

OpenAI의 Codex도 시도해봤지만 결과는 실망스러웠습니다. 디컴파일 전략도 약했고, 특히 Git 관련 명령어를 제대로 따르지 못했다고 합니다. 이건 알려진 이슈인데 업그레이드해도 해결되지 않았다고 하네요.

방어적 툴 설계도 중요한 교훈입니다. Chris는 프롬프트 엔지니어링보다 툴에 명확한 에러 메시지와 가이드를 넣는 게 훨씬 효과적이라고 말합니다. 예를 들어 Claude가 디렉토리를 헷갈려하면, Makefile의 캐치올 규칙이 “너 지금 매칭 환경에 있어. 메인 프로젝트로 가려면 두 단계 위로 올라가야 해(cd ../..)”라고 알려줍니다.

그리고 Chris는 디컴파일 커뮤니티의 공헌을 강조하는 것도 잊지 않습니다. Splat, m2c, decomp-permuter, asm-differ 같은 도구들과 Discord의 인내심 많은 사람들 없이는 이 프로젝트가 불가능했다고 말이죠.

디컴파일의 패러다임 전환

전통적으로 게임 디컴파일 프로젝트는 수년에 걸쳐 소수의 전문가들이 팀을 이뤄 진행했습니다. 제약은 항상 사람의 시간과 전문성이었죠. 하지만 코딩 에이전트는 이 제약을 바꿉니다. 이제 제약은 컴퓨팅 파워와 최신 모델에 대한 접근성입니다.

물론 인간 전문가가 불필요해지는 건 아닙니다. 가장 어려운 함수들은 여전히 사람의 손길이 필요하고, LLM이 만든 코드를 정리하고 이해하는 작업도 사람의 몫입니다. 하지만 역할은 분명 변하고 있습니다. “처음부터 코드 작성하기”에서 “LLM 출력물을 정리하고 문서화하기”로 말이죠.

Chris의 프로젝트가 보여주는 건 단순히 디컴파일의 성공이 아닙니다. AI 에이전트를 실전에서 어떻게 활용할 수 있는지, 실패를 어떻게 관리하고 효율을 어떻게 높이는지에 대한 구체적인 청사진입니다. 레거시 소프트웨어 보존이든, 대규모 코드 마이그레이션이든, 비슷한 패턴을 적용할 수 있겠죠.

참고자료:


AI Sparkup 구독하기

최신 게시물 요약과 더 심층적인 정보를 이메일로 받아 보세요! (무료)

Comments

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다