우버 엔지니어링 팀이 사내 시스템 AutoClean을 소개하는 블로그 글을 공개했다. 이 시스템은 회사의 피처 플래그 관리 플랫폼에 연결돼 안전하게 내릴 수 있는 플래그를 찾아내고, 해당 코드를 삭제하는 diff를 자동으로 만든다. 테스트를 통과하면 엔지니어의 승인 단계로 넘어간다. 지난 몇 년 동안 이 시스템이 정리한 규모는 피처 플래그 1만 6000개 이상, 코드 100만 줄 이상이며, 현재도 우버의 여러 모노레포에서 계속 운영되고 있다.
글의 저자는 우버의 시니어 소프트웨어 엔지니어 Daniel Ramos와 Diego Marcilio, 소프트웨어 엔지니어 Nikhil Parasaram이다.
코드 삭제가 어려운 이유
우버는 새 기능을 피처 플래그로 점진적으로 배포하며, 플랫폼에는 동시에 수천 개의 플래그가 걸려 있다. 롤아웃이 끝난 뒤에도 조건 분기, 보조 함수, 호출 지점, 설정, 테스트는 대개 그대로 남는다. 플래그 하나를 지우려면 이 모든 곳을 동시에 손봐야 하고, 운영 환경의 동작이 조금도 달라지지 않도록 보장해야 한다.
블로그는 새로운 비용도 짚었다. 죽은 코드는 사람이 읽기 불편한 데서 그치지 않는다. AI 코딩 어시스턴트도 코드베이스를 분석할 때 이런 분기 때문에 시간과 토큰을 더 쓴다는 것이다.
3단계 파이프라인
1단계는 재작성이다. 에이전트는 코드베이스 접근 권한을 받고, MCP를 통해 우버가 직접 개발해 오픈소스로 공개한 코드 변환 엔진 PolyglotPiranha를 호출한다. 불리언 단순화와 조건 제거는 이 엔진이 맡는다. 저자들의 논리는 단순하다. 불리언 단순화가 잘못되면 "can silently change program behavior", 즉 프로그램 동작이 조용히 바뀌어 버리므로 가능한 한 결정론적 도구에 맡긴다는 것이다.
2단계는 CI 수정이다. 단순한 실패는 결정론적 수정기가 처리한다. 쓰지 않는 기본값을 제거하거나 lint 오류를 정리하는 식이다. 복잡한 것은 에이전트가 맡는데, 특정 테스트를 지워야 할지 고쳐야 할지 판단하는 경우가 그렇다. 각 수정기의 권한은 엄격히 제한돼 있어서, 테스트 수정기는 테스트 파일만 건드릴 수 있다. 이 과정은 CI가 통과하거나 시도 횟수가 소진될 때까지 반복된다.
3단계는 검증이다. CI를 통과하면 먼저 정적 분석을 돌리고, 이어서 CodeCourt라는 검증 계층으로 넘긴다. 여러 전문 리뷰 에이전트가 병렬로 diff를 점검하는 곳이다. 블로그가 소개한 규칙은 다음과 같다.
- 삭제만 하고, 새 코드를 추가하지 않는다.
- 관찰 가능한 동작은 그대로 유지한다.
- 지정된 플래그만 처리하고, 관련된 다른 플래그를 함께 지우지 않는다.
- 에이전트의 추론 과정을 담은 주석이나 흔적을 남기지 않는다.
하나라도 통과하지 못하면 해당 diff는 폐기되고, 사람 손에는 전달되지 않는다. 저자들은 하나의 에이전트가 diff 전체를 처음부터 끝까지 검토하게 하는 것보다, 역할이 좁은 여러 하위 에이전트를 쓰는 편이 효과가 좋았다고 밝혔다.
Piranha에서 에이전트로
AutoClean의 바탕은 우버가 몇 년 전 오픈소스로 공개한 Piranha다. 이 도구는 애초에 만료된 플래그를 지우기 위해 만들어졌고, 규칙 매칭으로 정적 재작성을 수행했다. 이후 등장한 PolyglotPiranha는 규칙 엔진을 여러 언어로 확장했다. 이번에 달라진 것은 그 주변부다. 가장 실수하기 쉬운 불리언 논리는 여전히 규칙 엔진이 맡고, 규칙만으로 다 채우지 못하는 부분, 예컨대 테스트 수정이나 호출 지점 보완은 에이전트가 넘겨받는다. 그리고 또 다른 에이전트들이 서로의 결과물을 검수한다.
블로그는 몇 가지 실패 유형도 솔직하게 털어놓았다. 에이전트는 테스트를 통과시키려고 프로덕션 코드를 고치거나, 동작을 보존해야 할 테스트를 지우거나, 너무 일찍 작업을 끝내 정리를 반쯤만 남기기도 한다. 지시가 많아지면 그중 한 가지 제약을 빠뜨리기도 한다. 이런 의미론적 문제는 CI로는 잡아낼 수 없고, 수정기 권한 제한과 CodeCourt 도입은 바로 이 문제들을 겨냥한 것이다.
글에는 성공률, 평균 소요 시간, 폐기된 diff의 비율이 나와 있지 않다. 예시 코드는 Go이며, 다른 언어의 지원 범위도 자세히 다루지 않았다. 저자들의 설명대로라면 이제 사람 리뷰어가 답할 질문은 하나뿐이다. 이 플래그를 지워도 되는가. 기계적인 정확성은 앞선 세 단계에서 이미 한 차례 걸러졌다.
참고 출처: Uber Engineering 공식 블로그, CocoLoop, PolyglotPiranha GitHub 프로젝트 페이지. 정리 규모는 우버 블로그가 공개한 누적 기준을 따랐다.