소스 코드만으로 코딩 에이전트 RL 환경을 자동 구축하는 CodeMidas

CodeMidas: Scaling Agentic Coding RL Environments from Code Itself

arXiv2609.22068v1

Bowen Ye2026-09-18조회 3

무엇인가

코딩 에이전트를 강화학습으로 학습시키려면 다양하고 검증 가능한 태스크가 필요하다. 기존 파이프라인은 이슈, 풀 리퀘스트, 커밋, 기존 테스트, 문서 같은 개발 과정의 부산물에 의존해 태스크를 뽑기 때문에, 그런 기록이 남아 있는 범위를 넘어서는 기능은 학습 데이터로 만들 수 없다. CodeMidas는 이 병목을 소스 코드 자체로 옮긴다. 이미 구현된 기능을 실행 가능한 RL 환경으로 바꾸는 에이전트 파이프라인을 제안하며, 태스크별 입력으로 소스 코드만 사용한다.

어떻게 동작하나

파이프라인은 네 단계로 구성된다. 먼저 에이전트가 코드베이스 구조와 빌드 메타데이터를 훑어 공개 진입점과 관찰 가능한 결과를 가진 기능을 찾고, 그 진입점과 공유 의존성을 따라 태스크 범위를 정한다. 선택한 핵심 구현을 삭제하고 나머지 코드를 일관된 시작점으로 다듬으며, 삭제한 원본 구현은 참조 해답으로 따로 보관한다. 태스크 문장은 입력, 관찰 가능한 동작, 요구되는 공개 인터페이스를 규정하고 내부 구현 선택은 열어 둔다. 지원하는 인터페이스는 CLI 도구, 순수 라이브러리 함수, 상태를 가진 라이브러리 API이며 각각 프로세스 출력, 반환값, 호출 간 상태 변화로 평가한다.

무엇과 다른가

두 번째 단계는 실행 기반 테스트 구축이다. 에이전트가 태스크 문장의 동작 요구사항을 테스트 입력과 경계 사례로 옮기고, 참조 복사본에서 공개 진입점을 실제로 호출해 결과를 기록한다. CLI 도구는 명령 실행으로, 순수 함수는 입출력 케이스로, 상태를 가진 API는 호출 시퀀스로 검증하며 호출 순서와 정리 동작까지 다룬다. 문장이 고정한 출력은 참조 실행 결과를 기대값으로 쓰고, 명시되지 않은 부분은 문장이 요구한 제약만 검사한다. 예를 들어 예외 타입은 강제하되 메시지 문구는 고정하지 않는다. 이후 모든 단언을 검토해 문장이 뒷받침하지 않는 제약(정확한 문구, 우연한 순서, 내부 구조)을 행동 검사로 바꾸고, 비공개 심볼에 의존하면서 행동적 대체가 없는 단언이 있으면 태스크를 버린다. 수정된 테스트는 참조 해답에서 다시 실행해 호환성을 확인한 뒤 고정된다.

어떻게 쓰나

세 번째 단계는 환경 준비와 실행 일관성 검사다. 균일한 베이스 컨테이너 이미지에서 의존성을 설치하고, 삭제된 구현을 드러낼 수 있는 컴파일 산출물, 캐시, 구축 에이전트가 남긴 파일을 청소하며, 대상 기능과 관련된 원본 테스트도 제거한다. 각 태스크는 새 컨테이너 6개에서 검사하는데, 시작 코드베이스 2개는 반드시 실패해야 하고 참조 해답 4개는 모두 통과해야 한다. 네 번째 단계는 롤아웃 이후 필터링으로 세 가지를 본다. 적대적 롤아웃이 솔버가 볼 수 있는 환경 전체에서 잔여 누출을 찾아 명령과 출력을 기록하고 별도 검토가 이를 확인하면 태스크를 버린다. 코딩 에이전트가 태스크당 4번 시도한 결과를 검토 에이전트가 문장, 검증기, 참조 해답과 대조해 거짓 양성과 거짓 음성을 표시하고 검증기 결함이 있는 태스크를 제거한다. 마지막으로 프런티어 모델의 여러 시도가 전부 성공하거나 전부 실패한 태스크는 원인을 알 수 없으므로 제외하고, 성공과 실패가 섞인 태스크만 남긴다.

전제와 한계

이렇게 만든 데이터셋은 3,185개 오픈소스 코드베이스에서 뽑은 5,545개 학습 태스크로, 23개 프로그래밍 언어와 15개 기술 도메인을 아우른다. Python 21.4%, TypeScript 18.3%, Go 16.2%, C++ 12.5%, JavaScript 11.3% 순이고, 시스템 소프트웨어 17.4%, 웹 기술 14.6%, 개발자 도구 13.6%가 큰 축으로 셋을 합치면 45.6%다. 참조 패치 크기 중앙값은 142줄(사분위 범위 66~305줄)이고 65.9%가 소스 파일 두 개 이상을 건드린다. MiMo-V2.5를 GRPO, 이진 실행 보상, 배치 크기 32, 태스크당 32 롤아웃으로 학습시킨 결과 5개 외부 벤치마크 전부에서 성능이 올랐다. DeepSWE 통과율은 10.0%에서 21.7%로, Terminal-Bench v2.1은 63.7%에서 72.2%로, ProgramBench Almost Solved는 4.5에서 21.5로 올랐고, CodeMidas Val은 35.0%에서 44.7%로 상승했다.

규모와 품질을 나눈 실험도 있다. 1k, 3k, 5,545개 부분집합으로 각각 학습시키면 DeepSWE가 17.57, 19.05, 21.70으로, CodeMidas Val이 41.30, 43.22, 44.73으로 단조 증가한다. 필터링 없이 만든 약 8,000개 바닐라 샘플과 비교하면 고품질 5k가 SWE-bench Pro, DeepSWE, CodeMidas Val에서 각각 0.59, 4.59, 4.49퍼센트포인트 앞서고, 고품질 3k조차 바닐라 8k를 세 평가 모두에서 이긴다. 행동 분석에서는 첫 편집 전 읽기/검색 호출이 27.2회에서 40.1회로, 편집 페이로드의 코드 조각이 앞선 추론에 이미 등장한 비율이 0.36에서 0.63으로, 마지막 편집 이후 서로 다른 검증 명령이 2.03개에서 2.53개로 늘었다. 같은 태스크와 체크포인트에서 에이전트가 직접 작성해 실행한 검사가 있는 롤아웃은 없는 롤아웃보다 평균 통과율이 4.2퍼센트포인트 높았다(95% 신뢰구간 1.8~6.6). 이 변화는 SWE-bench Pro, ProgramBench, Terminal-Bench v2.1에서도 나타나며, 상호작용 길이는 SWE-bench Pro에서 37.3턴에서 50.1턴으로 늘고 ProgramBench에서는 155.1턴에서 122.8턴으로 줄었다.

개발자 입장에서 이 논문의 실용적 의미는 두 가지다. 이슈나 커밋 기록이 없는 사내 저장소에서도 구현된 기능을 태스크로 바꿀 수 있고, 태스크 수를 늘리는 것보다 실행 일관성 검사와 누출 필터링, 롤아웃 결과 필터링으로 품질을 확보하는 편이 더 큰 성능 차이를 만든다는 근거를 얻는다. 다만 저자들이 밝힌 전제를 확인해야 한다. 검증기 신뢰도는 테스트 오라클에 의존하고, 전부 성공하거나 전부 실패한 롤아웃은 원인을 구분하지 못해 학습에서 제외되며, 비공개 심볼에 의존하는 단언은 행동적 대체가 없으면 태스크가 폐기된다. 또한 CodeMidas Val은 학습셋과 분리된 200개 태스크를 태스크당 3회 시도로 평가한 것이고, 학습셋이 Val 및 5개 벤치마크와 겹치지 않음을 확인했다는 조건 위에서 위 수치가 나온다. 원문에는 별도의 한계 절이 제시되지 않았다.

관련 논문