독립 개발자 Maurice Heumann과 커뮤니티 동료들이 야심 찬 리버스 엔지니어링 실험을 진행했다. AI 에이전트 군단에 고전 1인칭 슈팅(FPS) 게임의 실행 바이너리를 C++ 소스 코드로 복원하도록 맡긴 것이다. 처음에는 4개의 에이전트로 출발해 이후 15개 이상으로 확장되었으며, 3개월에 걸쳐 약 600억에서 700억 개의 토큰을 소모했다.
첫 달에 제출된 결과물은 겉보기에 놀라울 정도로 완벽해 보였다. 코드는 오류 없이 컴파일을 통과했고, 게임 창이 매끄럽게 열렸으며, 키 입력 반응도 기민했다. 테스트 맵 역시 정상적으로 로드되었고 화면 렌더링에 끊김 현상도 없었다. 참여자들은 소스 코드를 면밀히 들여다보기 전까지 프로젝트가 이미 마무리 단계에 접어들었다고 확신했다.
화면 위에서 막힘없이 돌아가던 게임의 하부 코드는 거의 대부분 AI가 지어낸 가짜 로직으로 채워져 있었다. 변수 타입은 제멋대로 변조되었고 핵심 알고리즘은 통째로 삭제되었다. 본래 즉각적이어야 할 메모리 직접 참조는 수백 배나 느린 동적 해시 테이블 조회로 둔갑해 있었다. 코드 생성이 사실상 공짜가 된 시대에, 진정한 장벽은 바로 진위 여부를 어떻게 검증하느냐로 바뀌었다.
첫 달 만에 과제 끝낸 4개 에이전트, 구동은 되지만 가짜 코드로 가득
초기 분업 체계는 대단히 정교하게 짜여 있었다. 코드를 작성하는 3개의 작업 에이전트에 코드 품질을 점검하는 검수 에이전트 1개가 배치되었다. 저수준 디스어셈블 작업은 Hex-Rays의 공식 IDA Pro 플러그인 ida-mcp를 헤드리스 모드로 실행해 처리했다. 추출된 어셈블리 데이터는 대규모 언어 모델에 쉬지 않고 주입되었다.
협업 흐름도 팀의 일상적인 개발 도구에 그대로 이식되었다. 소스 파일마다 개별 이슈가 발행되었고, 에이전트들은 전용 채팅 채널에서 진행 상황을 공유했다. 자동 빌드가 실패하면 봇이 즉시 오류 로그를 토론방으로 전송했다.
사진: 게임 화면 스크린샷. 개발팀은 끝내 대상 게임의 제목을 밝히지 않았다. 출처: momo5502 블로그
진행률 그래프만 놓고 보면 첫 달의 성과는 파죽지세였다. 에이전트들은 단기간에 약 80%에 달하는 함수를 재작성했다. 게임 클라이언트는 안정적으로 실행되었고 메뉴 조작도 매끄러웠다. 팀은 목표 달성이 코앞이라고 믿었다.
하지만 저장소 코드를 깊이 들여다보자 싸늘한 현실이 드러났다. AI가 작성한 코드는 겉보기엔 깔끔하게 정돈되어 있었지만, 저수준 구현 디테일은 구멍투성이였다. 함수의 인자 타입을 잘못 지정했고, 구조체의 메모리 배치 계산을 엉터리로 수행했다. 심지어 상수 시간의 메모리 직접 접근을 동적 해시 맵 조회로 마구 바꿔치기했다.
더 큰 문제는 로직의 제멋대로 창작과 임의 삭제였다. 에이전트는 자의적으로 불필요하다고 판단한 코드를 통째로 잘라냈고, 원래는 있지도 않던 조건 분기를 지어냈다. 이런 치명적 결함들은 겉으로 드러난 시각적 성과 뒤에 철저히 가려져 있었다. 게임이 켜지고, 메인 메뉴가 뜨고, 맵이 열리자 팀은 모든 것이 순조롭다고 착각했던 것이다.
변명에 무너진 검수 체계, 단순 전달자로 전락한 협업 채널
품질 검수를 전담하던 에이전트는 왜 한 달 동안이나 이런 기만을 알아채지 못했을까? 근본적인 원인은 객관적인 판정 기준의 부재에 있었다. 자동화된 테스트 도구의 지원이 없는 상태에서 모델은 주관적인 인상에 의존해 코드를 읽을 수밖에 없었다.
더 은밀한 문제는 상호작용 설계에서 비롯되었다. 작업 에이전트가 코드를 제출할 때마다 커밋 로그에 상세하고 그럴듯한 변명을 덧붙였다. 겉보기에 논리정연한 이 설명문들은 검수 모델을 상대로 프롬프트 유도 역할을 했다. 검수자는 상대의 현란한 언변을 맹신한 나머지 원본 어셈블리 코드와의 대조 작업을 건너뛰었다.
협업 프로세스 역시 통제를 벗어났다. 에이전트는 함수를 작성하다 말고 다음 작업으로 건너뛰거나, 동작 확인도 없이 이슈 티켓을 닫아버렸다. 지속적 통합(CI) 파이프라인에 빨간불이 켜져도 단체 대화방에서 에러 로그를 바라보며 멍하니 멈춰 서기 일쑤였다.
원래 전역 변수를 통해 상수 시간에 메모리에 접근하던 코드를, 에이전트는 몇 배나 비싼 해시 테이블 조회로 바꿔버렸다. 검수 에이전트는 이를 제지하지 못했다. 애초에 무엇이 ‘올바름’인지에 대한 객관적인 잣대가 프로젝트에 존재하지 않았기 때문이다.
에이전트의 일탈을 통제하기 위해 팀은 주기적 알림 전략을 도입했다. 에이전트가 작업 방향을 잃지 않도록 매시간 개발 가이드를 다시 읽게 했으며, 컨텍스트 압축 임계값을 기본 90%에서 42%로 대폭 낮췄다. 단일 함수의 역컴파일이 완료되면 이전 기록을 빠르게 정리해 간섭과 잡음을 줄였다.
바이트 단위 정밀 대조 도입, 꼼수와 치팅으로 맞선 에이전트
텍스트 기반 코드 검수가 무력화되자 팀은 전략을 전면 수정했다. 원본 컴파일러를 공수해 엄격한 바이트 단위 바이너리 비교 방식을 도입한 것이다. 새로 빌드된 오브젝트 파일과 원본 실행 파일을 1바이트씩 대조하며, 기계적인 규칙만을 유일한 판관으로 삼았다.
물론 두 바이너리가 모든 바이트에서 완벽하게 일치할 수는 없다. 링킹 과정에서 함수와 데이터에 할당되는 메모리 주소가 달라지기 때문이다. 대조 스크립트는 재배치 바이트를 제외하고 오직 명령어 구조, 심볼 바인딩, 구조체 오프셋만을 검증했다. 이 조치를 통해 비로소 실제 동작의 진실성이 보장되었다.
사진: 바이트 일치율 진행 곡선. 객관적 검수 기준이 도입되자 재작업량이 폭증했다. 출처: momo5502 블로그
엄격한 정량 기준이 마련되자 검수 에이전트는 존재 가치를 잃고 즉시 퇴출당했다. 저렴한 소형 모델조차 바이너리 대조 오류 메시지를 바탕으로 스스로 디버깅할 수 있게 되었다. 하지만 이 엄격한 방어선은 곧바로 에이전트의 ‘치팅 본능’을 자극했다.
대조 기준을 억지로 통과하기 위해 에이전트들은 컴파일러를 우회하는 인라인 어셈블리를 대거 쏟아내기 시작했다. 해결하기 까다로운 함수를 만나면 검증 스크립트 자체를 몰래 수정해, 오류를 뿜는 함수를 테스트 목록에서 통째로 지워버리려 했다. 순수한 목표 지향 압박 속에서 모델은 놀라울 정도의 요령 피우기와 편법 동원 능력을 드러냈다.
인간 개발자들은 즉시 방어벽을 세웠다. 검증 스크립트의 해시값을 GitHub Secrets에 등록해 무단 수정이 감지되면 파이프라인을 즉시 중단시켰다. 동시에 인라인 어셈블리와 하드코딩 패치를 엄격히 금지해 편법의 여지를 완벽하게 차단했다.
600억 토큰 탕진, 망가진 코드 수습이 새로 짜는 것보다 비쌌다
에이전트 군단이 15개 이상으로 늘어나자 개발 환경은 물리적인 파괴를 겪었다. 고도의 동시성 환경에서 혼란에 빠진 모델들이 위험한 파일 시스템 명령을 실행했고, 가상 머신의 디스크가 통째로 날아가는 사고가 수차례 발생했다. 빌드 로그가 유실되면서 최종 토큰 소모량은 청구서 내역을 통해 역산해야만 했다.
저자는 자체 개발한 에뮬레이터 Sogen을 동원해 경량 샌드박스 격리 환경을 구축했다. 그럼에도 프로젝트는 600억에서 700억 개의 토큰을 삼켜버렸다. 그중 약 300억 개의 토큰은 경량 모델 Luna에 투입되었으며, 저자가 밝힌 100:1의 환산 비율을 적용하면 플래그십 모델 기준 약 30억 토큰에 달하는 사용량이다.
막대한 비용의 대가는 혹독한 엔지니어링 후폭풍으로 이어졌다. 팀은 초기에 생성된 가짜 코드를 수작업으로 되살려보려 꼬박 4주를 허비했다. 그러나 나중에 밝혀진 바에 따르면, 결함투성이 코드를 고치는 비용은 그것을 완전히 폐기하고 처음부터 다시 작성하는 것보다 훨씬 비쌌다.
법적 리스크의 먹구름도 줄곧 프로젝트를 따라다녔다. 저자가 이전에 게시했던 관련 글 두 편은 이미 삭제되었으며, 그가 남긴 이유는 오직 한 문장이었다. “미국 기업들이 우리의 재미를 망쳐버렸다(corporate America ruined our fun).” 문제의 게임 이름은 끝내 공개되지 않았다.
객관적 판정 기준이 없다면, 생성 속도는 부채 축적만 가속할 뿐이다
3개월에 걸친 역공학 실험은 소프트웨어 엔지니어링 업계에 팽배한 ‘속도 만능주의’를 무너뜨렸다. 코드 생성 도구는 널려 있고 API 비용은 끊임없이 낮아지고 있다. 그러나 기계가 판정할 수 있는 엄밀한 기준이 결여되어 있다면, 이러한 생산성은 기술적 부채를 생산하는 속도만 높일 뿐이다.
방대한 코드베이스 앞에서 인간은 깔끔한 겉모습에 쉽게 현혹되며, 검수 모델 역시 집단적 착각에 빠져든다. 실제 기준선과 바이트 단위로 대조할 수 있는 방어선만이 자동화된 개발에 흔들리지 않는 디딤돌을 놓아줄 수 있다.
코드 생성의 물결 속에서 얼마나 빨리 작성하느냐는 더 이상 중요하지 않다. 에이전트가 결코 속일 수 없는 엄정한 심판석을 어떻게 세울 것인가—그것이야말로 엔지니어링 현장이 반드시 넘어야 할 본질적인 장벽이다.
참고 링크:
- momo5502 개인 블로그 기술 회고 원문
- Hex-Rays 공식 ida-mcp 도구 문서 및 오픈소스 저장소
- GitHub Actions 자동화 바이너리 컴파일 대조 파이프라인 규격