코드 청결도는 코딩 에이전트에 영향을 미치는가? 통제된 최소쌍 연구
3 hours ago
5
- 자율 코딩 에이전트 평가는 주로 고정된 코드베이스에서의 작업 성공률을 봐 왔지만, 이 연구는 코드 자체의 청결도가 탐색·수정 비용을 바꾸는지 분리해 측정함
- 아키텍처, 의존성, 외부 동작은 같고 SonarQube 규칙 위반과 인지 복잡도만 다른 최소쌍 저장소 6개와 숨겨진 테스트 기반 작업 33개를 구성함
- Claude Code와 Claude Sonnet 4.6으로 각 작업을 저장소 쌍의 양쪽에서 10회씩 실행해 총 660회 실험을 수행했으며, 에이전트는 어느 쪽 코드인지 알지 못함
- 코드 청결도는 통과율을 바꾸지 않았지만, 더 깨끗한 코드에서 토큰 등가 지표는 7~8% 줄고 파일 재방문은 34% 감소함
- 모델이나 프롬프트만이 아니라 코드베이스 상태도 에이전트의 계산 비용과 탐색 효율을 좌우하는 실무 변수로 남아 있음
연구 질문과 문제 설정
- 자율 코딩 에이전트는 빠르게 확산 중임
- 2026년 128,018개 GitHub 프로젝트 조사에서 첫 실용 에이전트 출시 후 1년이 되지 않은 시점에 22~29%의 프로젝트에서 에이전트 활동 흔적이 발견됨
- 에이전트 실행 비용도 작지 않음
- SWE-bench Verified에서 단일 작업은 프런티어 LLM 기준 평균 약 400만 토큰을 사용함
- 전체 사용량에서는 입력 토큰이 대부분을 차지함
- 기존 평가는 SWE-bench 같은 벤치마크에서 작업을 해결했는지에 집중해 왔고, 최근 연구들은 통과율과 함께 자원 사용량도 측정하기 시작함
- 일반적인 비교는 코드베이스를 고정한 뒤 에이전트나 스캐폴딩을 바꾸는 방식이었음
- 이 연구는 반대로 에이전트와 작업을 고정하고 코드베이스의 청결도만 바꿔 비교함
코드 청결도와 최소쌍 구성
- 코드 청결도는 유지보수 가능한 코드와 연결되는 특성들의 묶음으로 다뤄짐
- 읽기 쉬움
- 낮은 인지 복잡도
- 잘 분리된 헬퍼
- 명확한 이름
- 적은 죽은 코드, 중복 로직, 우발적 결합
- 연구는 코드 청결도를 엄밀한 형식 정의로 고정하지 않고, SonarQube 정적 분석 규칙 위반 수를 느슨한 대리 지표로 사용함
- 사용 도구는 SonarQube Cloud Enterprise Edition
- 규칙 세트는 “default quality gate”
- 최소쌍 저장소는 내부 청결도만 다르고 다음 조건은 맞추도록 구성됨
- 같은 언어와 프레임워크
- 같은 의존성
- 같은 테스트 또는 동등한 테스트 커버리지
- 같은 외부 동작
- 동작 동등성은 같은 입력에서 외부적으로 관찰 가능한 출력과 상태 전이가 같은 경우로 봄
- 실제 검증은 같은 테스트 스위트를 같은 커버리지로 통과하거나, 리팩터링처럼 관찰 불가능한 변경을 보정한 테스트 쌍을 통과하는 방식으로 이뤄짐
최소쌍 생성 파이프라인: Slopify와 Vibeclean
- 최소쌍은 양방향으로 만들어짐
- 깨끗한 저장소를 더 지저분하게 만드는 Slopify
- 지저분한 저장소를 정리하는 Vibeclean
-
Slopify
- 깨끗한 코드베이스를 코드 리뷰나 린팅 없이 성장한 듯한 버전으로 바꿈
- 의도적으로 망가뜨린 코드가 아니라, 정적 분석이 없었을 때의 대체 역사 버전을 목표로 함
- 세 단계가 각각 새로운 에이전트에 의해 수행됨
- Build: 저장소를 빌드하고 테스트가 통과되게 한 뒤 build instructions.md에 명령을 고정
- Explore: 저장소를 훑고 정리 대상 디렉터리마다 summary.md 작성
- Transform: 지정된 디렉터리에 SonarQube 규칙 위반을 도입하고, 각 패스 뒤 테스트를 다시 실행해 깨진 변경은 거부
- 헬퍼 인라인화, 경로별 로직 중복, 죽은 코드 추가, 일부 모듈의 단일 파일 병합 등으로 인지 복잡도를 늘림
-
Vibeclean
- 자연적으로 규칙 위반이 많은 코드베이스를 외부 동작을 유지한 채 정리함
- 에이전트의 작업 목록은 분석기가 잡아낸 이슈 목록이며, 각 이슈는 코드 범위에 연결됨
- 수정 범위는 분석기가 표시한 문제로 제한되고, 전체 재설계는 목표가 아님
- 두 단계로 동작함
- Build: 빌드와 테스트 명령을 확인하고 build instructions.md에 고정
- Clean: 모듈별로 분석기 규칙 위반을 기계적으로 정리하고, 모듈 처리 뒤 테스트로 동작 동등성을 확인
- 문자열 리터럴 중복 제거, 주석 처리된 코드 삭제, 레거시 컬렉션 관용구 교체, 죽은 분기 제거 등을 수행함
- 분석기가 실제 거대 구조를 지적한 경우 200줄 이상 dispatch switch를 이름 있는 헬퍼로 바꾸거나, 2,800줄 클래스에서 영속성 헬퍼를 추출함
- 다만 추출이 복잡도를 제거하기보다 더 많은 메서드로 재분배할 수 있고, 일부 가장 큰 거대 구조는 wontfix로 남음
벤치마크 저장소와 작업 설계
- 벤치마크는 Harbor framework v0.4.0 위에 구축됨
- 총 6개의 최소쌍 저장소가 사용됨
- Java 중심 3개, Python 중심 3개
- 일부 저장소는 다른 언어 코드를 소량 포함함
- 공개 오픈소스 저장소 3개와 비공개 SonarSource 코드베이스 3개로 구성됨
- 비공개 쌍은 평가 대상 LLM이 공개 저장소로 학습했을 가능성에 대비한 암기 방지 역할을 함
- 저장소별 청결한 쪽과 지저분한 쪽의 주요 수치는 다음과 같음
- sonar-sca*: 이슈 94 / 2,825, 이슈 밀도 0.73 / 20.66, 인지복잡도 밀도 30.6 / 56.5
- sonar-caas-poc*: 이슈 16 / 855, 이슈 밀도 0.61 / 27.16, 인지복잡도 밀도 179.8 / 218.9
- sonarcloud-codedatalake*: 이슈 199 / 1,319, 이슈 밀도 4.36 / 34.39, 인지복잡도 밀도 34.0 / 216.5
- commons-bcel: 이슈 694 / 2,711, 이슈 밀도 12.60 / 49.46, 인지복잡도 밀도 102.8 / 108.3
- genie: 이슈 152 / 1,262, 이슈 밀도 1.28 / 10.81, 인지복잡도 밀도 22.2 / 23.5
- ckan: 이슈 1,006 / 3,632, 이슈 밀도 7.54 / 27.50, 인지복잡도 밀도 69.3 / 76.5
- 작업 설계는 세 가지 규칙을 따름
- 핫스팟 경유: 쌍의 양쪽에서 이슈 밀도와 인지 복잡도 차이가 큰 코드 영역을 지나가도록 작업을 배치
- 외부 관찰 가능 설명: 입력·출력과 예시 시나리오만 제공하고, 파일·함수·내부 구조 이름은 제공하지 않음
- 공개 표면 테스트: CLI, HTTP 라우트, 라이브러리/API 등 애플리케이션이 호출자에게 제공하는 인터페이스를 통해 숨겨진 테스트를 실행
- 작업 생성은 에이전트와 사람이 나눠 맡음
- 에이전트가 깨끗한 변형과 지저분한 변형을 비교해 차이 지도를 만듦
- 다른 에이전트가 작업 개요와 테스트 가능성을 작성함
- 사람이 그중 그럴듯하고 흥미로운 개요를 선택·편집·큐레이션함
- 세 번째 에이전트가 실제 지시문, 숨겨진 공개 표면 테스트, 내부용 참조 구현을 만듦
- 참조 구현은 양쪽 저장소에서 숨겨진 테스트를 통과해야 함
- 수정 전 저장소는 숨겨진 테스트를 통과하면 안 됨
- 두 번의 반복 뒤에도 조건을 만족하지 못한 작업은 사람이 다시 쓰거나 제거함
- 최종 작업 수는 33개이며 세 트랙으로 나뉨
- 13개 인지 핫스팟 작업: 단일 메서드나 단일 클래스의 고밀도 복잡 영역을 통과
- 14개 다중 모듈 작업: 둘 이상의 모듈을 가로지르는 변경 필요
- 6개 보정 작업: 양쪽이 동일한 영역에서 단순한 작업을 수행해 청결도와 무관한 변화가 있는지 확인
실험 설정과 측정 지표
- 모든 실험은 기본 도구 세트를 사용하는 Claude Code로 수행됨
- 보고된 수치는 Claude Sonnet 4.6 실행에서 나옴
- Claude Haiku 4.5도 같은 작업 세트에서 훑었지만, 통과율이 너무 낮아 footprint 차이를 명확히 읽기 어려워 본 결과에서 제외됨
- 에이전트는 작업 설명만 읽음
- 코드 청결도에 대한 추가 프라이밍을 받지 않음
- 자신이 최소쌍의 어느 쪽에서 작업하는지 모름
- 각 작업은 쌍의 양쪽에서 10회씩 실행됨
- 총 실험 수는 33 × 2 × 10 = 660회
- 각 실행은 컨테이너화된 샌드박스에서 수행됨
- CPU, 메모리, 저장소, 벽시계 시간이 제한됨
- 공개 패키지 레지스트리에 접근 가능함
- 기본 이미지는 저장소별 툴체인, 빌드 캐시, 서비스를 포함함
- 쌍 내부에서는 /app에 마운트되는 소스 트리만 다름
- 기록 지표는 10개임
- 통과율: 최종 상태에서 숨겨진 테스트가 통과한 비율
- 입력 토큰: 모든 턴에서 모델이 읽은 토큰 수이며 파일 내용과 이전 대화 재전송이 대부분을 차지함
- 출력 토큰: 모델과 하위 에이전트가 낸 산출물 전체로, 산문·코드·추론 흔적·도구 호출을 포함함
- 추론 문자 수: Anthropic API가 추론 토큰을 별도로 노출하지 않아 추론 콘텐츠 블록의 평문 문자 수를 셈
- 대화 턴 수: 에이전트-도구 교환 총수
- 첫 편집 전 턴 수: 첫 파일 수정 전까지 걸린 턴
- 첫 편집 전 문자 수: 같은 구간의 대화 문자 수
- 읽은 파일 수: 실행 중 열어본 고유 파일 수
- 파일 재방문: 이미 읽고 수정한 파일을 다시 읽은 횟수
- 수정한 줄 수: 최종 패치가 바꾼 소스 줄 수
- 파일 재방문은 읽기 → 편집 → 다른 작업 가능 → 다시 읽기 같은 흐름으로 나타남
- 연구에서는 폭넓은 탐색보다 이전 편집에 대한 불확실성 신호로 해석함
- 에이전트 footprint 지표는 같은 작업을 고정 온도에서 반복해도 크게 달라질 수 있어 이상치 필터를 적용함
- 각 (작업, 쪽) 조합 안에서 10회 반복의 중앙값보다 50% 이상 벗어난 실행을 평균 전 제거함
- 실제로는 전체 실행의 9.7% 가 제거됨
- 데이터셋 수준 수치는 33개 작업에 대해 마이크로 평균됨
- 각 지표별로 작업별 청결한 쪽 평균과 지저분한 쪽 평균을 합산한 뒤 비율 차이를 계산함
- 통과율은 예외적으로 청결한 쪽과 지저분한 쪽의 절대 퍼센트포인트 차이로 보고됨
결과: 성공률보다 탐색 비용에 영향
- 코드 청결도는 에이전트의 통과율에는 유의미한 변화를 만들지 않음
- 더 깨끗한 코드에서는 토큰 등가 지표가 7~8% 감소함
- 파일 재방문은 34% 감소해, 깨끗한 코드가 같은 작업에서도 되짚어 읽는 비용을 줄일 수 있음을 보임
- 따라서 코드 청결도는 모델 선택, 하네스, 프롬프트와 함께 에이전트 실행 비용을 좌우하는 별도 축으로 볼 수 있음
-
Homepage
-
Tech blog
- 코드 청결도는 코딩 에이전트에 영향을 미치는가? 통제된 최소쌍 연구