본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 05. 15. 15:50

30일 동안 AI에게 PR 리뷰를 맡겨보았다 — 데이터는 참혹했다

요약

개발자가 워크플로우 최적화를 위해 로컬 LLM 에이전트를 도입하여 Pull Request(PR) 리뷰를 맡겼으나, 초기에는 버그 포착 및 병목 현상 해소로 큰 성공을 거두었다. 그러나 시간이 지나면서 AI가 과도하게 조심스러워져 오탐(False Positive)이 범람했고, 개발자는 봇의 코멘트를 관리하는 데 더 많은 시간을 소요했다. 궁극적으로는 AI에 의해 승인된 코드에서 미묘하고 서서히 진행되는 품질 저하를 발견하며 실험을 마무리했다.

핵심 포인트

  • LLM 에이전트는 초기 단계에서 명확한 버그(예: SQL 인젝션, null 체크 누락)와 보안 취약점을 효과적으로 포착할 수 있다.
  • AI의 과도한 신중함은 오탐(False Positive)을 대량으로 발생시켜 개발자의 업무 부하를 '코드 읽기'에서 '봇 관리하기'로 전환시킨다.
  • 자동화된 리뷰 시스템에 의존할 경우, 인간이 놓치기 쉬운 미묘하고 서서히 진행되는 코드 품질 저하가 발생할 수 있다.
  • AI의 코멘트를 검증하는 데 소요되는 시간이 실제 수동 리뷰 시간보다 더 비효율적일 수 있다.

나는 2026년 3월 1일에 Pull Request (PR)를 수동으로 리뷰하는 것을 중단했다. 이것은 워크플로우 (workflow)를 최적화하려는 욕구에서 비롯된 전략적 결정이 아니었다. 그것은 순전한 탈진이었다. 나는 지난 2주 동안 사소한 공백 변경부터 우리의 레거시 인증 모듈 (legacy authentication module)의 복잡한 리팩토링 (refactor)에 이르기까지 다양한 diff (차이점)를 응시하며 시간을 보냈다. 내 뇌는 마치 죽처럼 느껴졌다. 그래서 나는 우리 팀의 스타일 가이드 (style guide)와 보안 규칙 (security rules)이 설정된 로컬 LLM 에이전트 (LLM agent)인 "ReviewBot"을 우리의 GitHub 저장소에 연결했다. 약속은 간단했다. 그것은 구문 오류 (syntax error)를 잡아내고, 잠재적인 보안 취약점 (security vulnerability)을 표시하며, 명명 규칙 (naming convention)을 강제할 것이다. 나는 오직 아키텍처 결정 (architectural decision)과 로직 검증 (logic validation)을 위해서만 개입할 것이다. 나는 일주일에 10시간을 절약할 것으로 기대했다. 더 깨끗한 코드를 기대했다. 내가 얻은 것은 엄청난 속도 (velocity)의 증가와, 내가 알아차리는 데 3주가 걸린 미묘하고 서서히 진행되는 코드 품질의 저하였다. 여기 그 한 달 동안 정확히 어떤 일이 일어났는지, 지표와 내가 마주한 구체적인 실패 모드 (failure modes)를 포함하여 기술한다.

설정 및 초기 성과
우리는 Next.js와 Python으로 구축된 중간 규모의 SaaS 플랫폼에서 일하는 6명의 개발자 팀이다. 우리의 평균 PR 크기는 변경된 코드 약 400줄이다. 실험 전, "Open"에서 "Merged"까지의 평균 시간은 18시간이었다. 여기에는 자신의 업무로 바쁜 인간 리뷰어들을 기다리는 시간이 포함되어 있었다. 나는 커스텀 시스템 프롬프트 (system prompt)를 사용하여 에이전트를 설정했다. 나는 우리의 eslint 설정, 우리의 pylint 규칙, 그리고 우리의 내부 베스트 프랙티스 (best practices)가 포함된 마크다운 (markdown) 파일을 에이전트에게 입력했다. 또한 에이전트가 문맥 (context)을 이해할 수 있도록 최근 커밋 히스토리 (commit history)에 대한 읽기 전용 권한을 부여했다.
첫 주는 환상적이었다. 봇은 세 개의 실제 버그를 잡아냈다. 하나는 TypeScript 인터페이스 (interface)에서 누락된 null 체크 (null check)였으며, 이는 런타임 크래시 (runtime crash)를 유발했을 것이다. 다른 하나는 표준 린터 (linter)가 놓친 raw query (원시 쿼리)에서의 SQL 인젝션 (SQL injection) 취약점이었는데, 변수 보간 (variable interpolation)이 언뜻 보기에 안전해 보였기 때문이었다. 내 팀원들은 그것을 매우 좋아했다. 그들은 더 이상 내가 깨어나서 그들의 오전 커밋을 리뷰하기를 기다릴 필요가 없었다.

평균 머지 시간 (merge time)은 4시간으로 줄어들었다. 나는 내가 천재가 된 것 같았다. 병목 현상 (bottleneck)을 해결했다고 생각했다. 그러다 두 번째 주가 시작되었고, 노이즈 (noise)가 발생하기 시작했다.

오탐 (False Positive)의 범람
8일 차에 접어들자 신호 대 잡음비 (signal-to-noise ratio)가 급락했다. AI가 지나치게 조심스러워진 것이다. AI는 단지 자신의 학습 데이터 (training data)에 있는 가장 흔한 예시와 일치하지 않는다는 이유만으로 유효한 패턴을 안티 패턴 (anti-patterns)으로 표시하기 시작했다. 예를 들어, 우리는 API 라우트에서 에러 핸들링 (error handling)을 위해 커스텀 로거 (custom logger)와 함께 try-catch 블록으로 프로미스 (promises)를 감싸는 특정 패턴을 사용한다. AI는 이를 12개의 서로 다른 PR에서 "불필요한 에러 핸들링 (redundant error handling)"이라고 표시했다. AI는 try-catch 블록을 제거할 것을 제안했는데, 이는 프로덕션 (production) 환경에서 에러를 소리 없이 삼켜버릴(swallow) 위험이 있는 행동이었다. 나는 매일 한 시간씩 이러한 오탐 (false positives)을 기각하는 데 시간을 써야 했다. 이것은 시간을 절약하는 것이 아니었다. 업무 부하가 "코드 읽기"에서 "봇 관리하기"로 옮겨진 것뿐이었다.

다음은 2주 차 동안 AI가 생성한 코멘트의 상세 내역이다:

카테고리횟수필요한 조치소요 시간
유효한 버그 포착 (Valid Bug Catch)4코드 수정 (Fix Code)20분
스타일 지적 (Style Nitpick)142기각/무시 (Dismiss/Ignore)35분
잘못된 로직 플래그 (Incorrect Logic Flag)18개발자에게 설명 (Explain to Dev)45분
보안 오탐 (Security False Alarm)9확인 및 기각 (Verify & Dismiss)15분
봇 관리에 사용된 총 시간약 1시간 55분

이는 내가 직접 코드를 리뷰하는 것보다 더 나빴다. 내가 코드를 리뷰할 때는 명백한 것들은 건너뛸 수 있다. 하지만 봇은 쓰레기 같은 코멘트 사이에 진짜 문제가 숨어 있지 않은지 확인하기 위해 모든 코멘트를 하나하나 다 살펴보도록 강요했다.

미묘한 품질 저하
진정한 충격은 4주 차에 찾아왔다. 나는 실험 기간 동안 머지된 코드에 대해 무작위 감사 (random audit)를 실시하기로 했다. 내가 초기 코멘트들을 기각한 후, 오로지 AI에 의해서만 승인된 PR 10개를 선정했다. 나는 거기서 "게으른" 코딩 패턴을 발견했다. 개발자들은 AI가 논리적 비효율성 (logical inefficiencies)을 잡아내지 못한다는 사실을 알고 있었다. AI는 오직 구문 (syntax)과 엄격한 규칙 준수 여부만을 확인했다. 그래서 그들은 검사는 통과하지만 구조적으로는 형편없는 코드를 작성하기 시작했다.

한 개발자는 AI가 순환 복잡도 (cyclomatic complexity)가 15라는 엄격한 임계값 (threshold)을 초과하지 않는 한 이를 지적하지 않았기 때문에 조건문 (conditional statements)을 5단계나 중첩시켰다. 코드는 작동했지만, 읽을 수 없는 상태였다. 또 다른 개발자는 AI가 해당 함수가 이미 다른 곳에 존재한다는 것을 파악할 수 있는 전역 문맥 (global context)을 갖지 못했기 때문에, 헬퍼 함수 (helper function)를 세 개의 파일에 걸쳐 중복해서 작성했다. AI는 품질 (quality)이 아니라 준수 (compliance)를 위해 최적화하고 있었다. 그리고 우리 팀은 속도 (speed)를 위해 최적화하고 있었다. 나는 우리의 버그 추적 시스템 (bug tracking system)을 살펴보았다. 실험 전 한 달 동안, 우리는 새로운 기능과 관련된 4개의 사소한 버그를 기록했다. AI 전용 리뷰를 진행한 30일 동안에는 11개를 기록했다. 그중 3개는 AI가 놓친 논리적 공백 (logical gaps)의 직접적인 결과였다.

인간적 요소는 대체 불가능하다
나는 코드 리뷰가 단순히 버그를 찾는 것만이 아니라는 점을 깨달았다. 그것은 지식 공유 (knowledge sharing)에 관한 것이다. 내가 주니어 개발자의 코드를 리뷰할 때는, 왜 특정 접근 방식이 더 나은지 설명하는 코멘트를 남긴다. 문서 (documentation) 링크를 첨부한다. 그들이 엣지 케이스 (edge cases)에 대해 생각하도록 강제하는 질문을 던진다. AI는 이 중 어느 것도 하지 않는다. AI는 이진 피드백 (binary feedback)만을 제공한다. 통과(Pass) 또는 실패(Fail). 이 줄을 수정할 것. 저 임포트(import)를 삭제할 것. 우리 주니어 개발자들은 학습을 멈췄다. 질문하는 것도 멈췄다. 그들은 그저 봇이 고치라고 말하는 것을 고치고 코드를 머지(merge)했다. 멘토링 루프 (mentorship loop)가 깨진 것이다. 나는 또한 문맥 (context)을 놓치고 있었다. AI는 우리가 다음 달에 UserService 클래스를 폐기 (deprecate)할 계획이라는 사실을 알지 못한다. 💡 추가 읽을거리 : 나는 AI 자동화와 오픈 소스 도구들을 실험한다. Pi Stack에서 더 많은 가이드를 찾아보세요.

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0