약 7분

실행 파일 하나만 주고 코드베이스를 통째로 재현하게 시켜봤다

ICML 2026. 컴파일된 바이너리에서 코드베이스를 재구축하게 하는 ProgramBench — 1부.

목차

이 글은 ICML 2026에서 들은 발표를 발표자 1인칭 시점으로 재구성한 것입니다.

지금 널리 쓰이는 코딩 에이전트 벤치마크는 대부분 patch-based다. SWE-bench 계열이 대표적인데, 이미 정해진 코드베이스에 패치를 적용하고 유닛테스트를 통과하는지로 채점한다. 그런데 이 구조를 곱씹어 보면 이상한 지점이 있다. 코드베이스의 아키텍처, 모듈 구조, 추상화가 이미 다 고정되어 있는 상태에서 모델에게 맡기는 일은 사실상 “남의 설계를 편집하는” 것에 그친다. 에이전트가 처음부터 끝까지 구조를 잡아가는 long-horizon, bottom-up 코딩 능력은 이 방식으로는 전혀 측정할 수 없다.

그사이 업계에서는 정반대 방향의 이야기들이 나오고 있었다. Anthropic은 병렬로 띄운 여러 Claude가 C 컴파일러를 만드는 실험을 블로그에 공개했고, Cursor는 일주일간 자율 코딩만으로 브라우저를 만드는 과정을 보여줬다. “아이디어 하나를 던지면 코드베이스 하나를 돌려받는” 능력이 이제는 핵심 셀링포인트가 되어가고 있었다. 그런데 정작 이런 능력을 정직하게 측정할 벤치마크는 없었다. 그 간극에서 ProgramBench를 만들었다.

문서와 바이너리만으로 문제를 정의하다

ProgramBench의 아이디어는 단순하다. 컴파일된 실행 파일을 에이전트에게 주고, 그 실행 파일의 동작을 그대로 재현하는 코드베이스를 처음부터 재구축할 수 있는지를 본다. 에이전트가 받는 건 딱 두 가지, 컴파일된 실행 파일과 문서(documentation)뿐이다. 원본 소스코드는 완전히 제거되어 있어서 에이전트는 원본 솔루션에 아예 접근할 수 없다. 바이너리와 문서, 이 둘이 곧 “문제 정의”인 셈이다.

여기서 핵심 난이도가 하나 생긴다. 에이전트는 프로그램과 직접 상호작용하고 probe하면서 동작을 먼저 파악해야, 그다음에야 구현을 시작할 수 있다. 소스가 없으니 짐작이 아니라 실제로 찔러보고 관찰하는 interactive black-box 방식으로 접근할 수밖에 없다. 최종적으로 에이전트는 소스 저장소와 빌드 스크립트를 제출해야 하고, 이건 실제로 컴파일이 되어야 한다. 실제 에이전트의 trajectory를 들여다보면 질의하고 구현하고 다시 질의하는 turn-based 전략이 반복적으로 관찰됐다. 블랙박스를 두드려보고, 이해한 만큼 짓고, 또 두드려보는 식이다.

언어가 아니라 행동으로 채점한다

채점 방식도 기존 벤치마크와는 완전히 다르게 설계했다. 원본 소스코드나 구현별 유닛테스트는 아예 보지 않는다. 대신 에이전트가 만든 프로그램과, 원본 소스로 컴파일한 ground-truth 실행 파일에 동일한 입력을 넣어 실행시킨다. 그리고 stdout, stderr는 물론 side effect까지 포함한 모든 동작(behavior)을 통째로 비교하는 fully behavior-level 테스트를 적용했다. 이 방식 덕분에 에이전트가 어떤 언어로, 어떤 아키텍처로 구현하든 상관없이 통과할 수 있다. 결과만 같으면 되는 구조다.

이때 테스트 케이스 자체를 어떻게 만드느냐가 벤치마크의 신뢰도를 좌우한다. 우리는 SWE agent 자체를 guided fuzzing에 활용해서, coverage 같은 테스트 품질 지표를 최적화 타겟으로 삼아 테스트 케이스를 생성했다. 사람이 손으로 짠 테스트가 아니라, 에이전트가 프로그램의 구석구석을 캐내도록 스스로 fuzzing 전략을 짜게 만든 것이다.

100년 치 개발 공수를 담은 데이터셋

ProgramBench는 총 수백 개(a couple hundred) 태스크로 구성했다. 규모는 작은 CLI 툴부터 FFmpeg, SQLite 같은 대형 툴링까지 폭넓게 걸쳐 있다. 원본은 주로 Rust, Go, C 같은 컴파일 언어로 작성됐지만, 에이전트는 어떤 언어로도 답할 수 있고 실제로도 대부분 ground-truth와는 다른 언어로 답했다. 흥미로운 건 ground-truth 코드베이스 자체가 Python처럼 자주 쓰이는 언어 쪽으로 편향(affinity)되어 있다는 점인데, 이건 SWE-bench Multilingual 같은 다른 multilingual 세팅에서도 똑같이 나타나는 현상이다.

태스크 하나의 평균 규모는 약 8,000줄, 약 50개 파일이고, 원본 저장소들은 GitHub 평균 2,100 stars를 받은, 실전에서 이미 잘 알려진 프로젝트들이다. 가장 어려운 축에 속하는 저장소로는 PHP 컴파일러, SQLite, Country Sitter를 꼽을 수 있는데, 이 셋만 합쳐도 누적 개발 공수가 100년 규모에 이른다.

아직 아무도 풀지 못한 벤치마크

출시 시점에 9개 최신 frontier 모델을 mini-SWE-agent 스캐폴드로 평가했다. 결과는 명확했다. 태스크를 완전히 해결한 모델은 하나도 없었다. 0개 solve다. 부분적인 진전은 있었다. 테스트 케이스의 약 95%를 통과하는 것을 기준으로 삼은 “almost” 지표로는 약 7%의 인스턴스가 여기에 해당했다. 하지만 완전 해결(fully solved) 비율은 단 3%에 그쳤다. 이 almost 지표는 조심해서 봐야 한다. 단 하나의 실패 테스트가 사실은 근본적인 설계 결함을 의미하는 경우가 많기 때문에, 95% 통과를 완전한 성공의 지표로 보기는 어렵다. 그리고 최근 새로운 모델들이 계속 릴리즈되고 있음에도 이 수치들에는 유의미한 진전이 보이지 않았다. 아직 갈 길이 멀다는 뜻이다.

겉으로 보이는 실력과 실제 코드 추론 능력의 격차

베이스라인 실험을 더 파고들면서 흥미로운 지점을 하나 더 발견했다. 모델이 생성한 코드가 정답(ground-truth) 코드베이스와 같은 프로그래밍 언어를 쓰는 비율은 약 50%에 불과했다. 절반의 확률로 언어 선택부터 어긋난다는 뜻인데, 상당히 낮은 수치다. 이 부분은 Python 기반의 강화학습(RL) 코드 환경 사례에서도 비슷하게 드러났다. 그리고 최고 성능을 낸 모델들조차 코드 추론(code inference) 능력에서는 현저히 떨어지는 모습을 보였다. 벤치마크 점수가 가장 높은 모델이라고 해서 코드를 실제로 “추론”하는 능력까지 뛰어난 건 아니었다.

결국 이 작업이 말해주는 건 하나다. 모델의 절대적인 코드 생성 성능이 아무리 높아 보여도, 정답 코드베이스와의 언어 일치도나 코드 추론 능력 같은 축으로 들여다보면 여전히 큰 격차가 남아 있다. patch 하나를 잘 맞추는 것과, 실행 파일 하나만 보고 코드베이스를 처음부터 다시 짓는 것은 완전히 다른 종류의 능력이다. ProgramBench가 보여준 0% solve rate는 그 차이가 우리 생각보다 훨씬 크다는 증거다.