article · 2026-08-07

AI 코드리뷰의 병목은 승인 수가 아니다

코드가 빨라질수록 더 희소해지는 것은 사람의 주의력이다

AI로 코드를 만들기 시작하면 처음에는 리뷰가 곧 사라질 것처럼 보인다. 코드를 쓴 쪽도 AI이고, 테스트를 돌린 쪽도 AI이고, diff를 읽는 쪽도 AI가 될 수 있으니 말이다.

그런데 실제로 먼저 늘어나는 것은 승인 버튼이 아니라 PR이다. 이전에는 며칠 걸려 만들던 변경이 한나절 안에 여러 개로 나뉘어 올라온다. 수정도 빨라진다. 리팩터링도 커진다. 그러면 사람은 더 적은 코드가 아니라, 더 많은 판단을 마주하게 된다.

이때 병목은 승인 수가 아니다. 사람의 주의력이다.

문구 수정, 격리된 테스트, 명확한 생성물은 자동 검사를 통과시키기 쉽다. 반면 인증, 결제, 개인정보, 배포, 의존성, 데이터 migration은 줄 수가 적어도 무겁다. 이 두 종류를 같은 줄에 세우고 모두 같은 방식으로 리뷰하면, 빨라진 코드 생성은 느린 대기열로 바뀐다.

그래서 AI 코드리뷰의 핵심은 자동 승인율이 아니라 위험 라우팅에 가깝다. 어떤 변경은 자동 검사가 충분한지, 어떤 변경은 어느 도메인의 사람이 봐야 하는지, 그 사람에게 무엇을 먼저 보여 줄지를 정하는 일이다.

리뷰는 통과 의식이 아니라 코드베이스의 건강을 다루는 일

Google의 코드 리뷰 가이드는 리뷰의 주된 목적을 코드베이스의 건강이 시간이 갈수록 나아지게 하는 일로 설명한다.[1] 이 표현이 좋다. 리뷰를 누군가의 실수를 잡아내는 관문이나 승인 도장으로만 보지 않기 때문이다.

물론 리뷰가 지나치게 무거우면 반대의 일이 생긴다. 모든 변경이 지연되고, 개발자는 작은 개선조차 포기하게 된다. Google 역시 리뷰어가 변경을 어렵게 만들기만 하면 개선의 유인이 사라질 수 있다고 적는다.[1] 품질과 속도 사이의 긴장은 새롭지 않다. AI가 바꾼 것은 그 긴장을 없앤 것이 아니라, 훨씬 더 자주 마주하게 만든 것이다.

작고 자기완결적인 변경을 권하는 가이드도 같은 맥락이다. 작은 CL은 설계와 코드 건강을 자세히 다듬기 쉽고, 기능 변경과 리팩터링을 분리하면 무엇을 검토하는지 분명해진다.[2] AI가 한 번에 수백 줄을 만들 수 있다고 해서, 수백 줄을 하나의 의미 있는 변경으로 리뷰할 수 있다는 뜻은 아니다.

코드 양이 아니라 변경의 경계가 리뷰를 어렵게 만든다.

위험은 하나의 점수보다 이유의 묶음에 가깝다

“AI가 PR마다 위험 점수를 매기면 되지 않을까”라는 생각도 자연스럽다. 하지만 하나의 숫자는 편한 만큼 위험하다. 82점이 왜 높은지, 38점이 왜 낮은지 설명하지 못하면 리뷰어는 그 숫자를 믿거나 무시하는 둘 중 하나를 택하게 된다.

실제 변경의 위험은 서로 다른 축에서 온다. 영향 범위가 넓고 되돌리기 어려운가. 인증·권한·secret처럼 신뢰 경계를 건드리는가. 결제나 개인정보처럼 도메인 비용이 큰가. 자동 테스트가 그 위험을 실제로 덮는가. 해당 경로에 익숙한 소유자가 있는가. 사람이 설계한 작은 수정인가, 대량 생성된 낯선 변경인가.

이 축들은 서로 상쇄되지 않는다. 인증 모듈을 한 줄 바꿨다고 낮은 위험이 되는 것은 아니다. 테스트가 모두 통과했다고 배포 script의 권한 변경을 가볍게 볼 수도 없다. 반대로 파일이 여러 개여도 문서 형식과 격리된 테스트만 바꿨다면 사람의 깊은 검토가 꼭 필요하지 않을 수 있다.

그래서 좋은 라우터는 “이 PR은 위험하다”라고 말하는 대신, “권한 경로 변경, code owner 미확인, rollback 계획 없음”처럼 사람이 확인할 수 있는 이유를 내놓아야 한다. 점수는 정렬에 쓸 수 있다. 책임을 설명하는 언어는 따로 필요하다.

AI가 찾아야 하는 것은 버그만이 아니다

AI 리뷰어에게 버그를 찾으라고 하면, 이슈 목록을 길게 만드는 방향으로 최적화되기 쉽다. 하지만 리뷰어가 원하는 것은 경고의 양이 아니다. 자신이 지금 읽어야 하는 가장 중요한 변경과, 그것이 왜 중요한지다.

2025년 LLM 보조 코드리뷰의 현장 연구는 실제 리뷰에서 맥락 부족과 잦은 컨텍스트 전환이 문제였다고 보고했다. 연구 참가자들은 AI가 주도하는 리뷰를 선호하기도 했지만, 그 수용은 리뷰어가 코드베이스에 얼마나 익숙한지와 PR의 심각도에 따라 달라졌다. false positive와 신뢰 문제도 함께 나타났다.[3]

이 결과는 AI 리뷰의 역할을 조금 다르게 보게 한다. AI는 “발견자”만이 아니라 “준비자”여야 한다. diff를 짧게 요약한다. 영향을 받을 수 있는 경로를 찾는다. 관련 테스트와 과거 이슈를 붙인다. 변경이 CODEOWNERS가 있는 영역을 건드리는지 알려 준다. 그리고 확신 없는 finding에는 확신 없다고 표시한다.

모델이 낸 코멘트는 판결이 아니라 검토 가설이다.

코드 리뷰 코멘트가 생각보다 어려운 이유도 있다. CodeReviewQA는 실제 리뷰 코멘트가 암묵적이고, 모호하며, 구어적일 수 있어서 코드만이 아니라 사람의 의도를 이해해야 한다고 지적한다.[4] “이 방식은 나중에 문제가 된다”는 한 줄은 diff 안에 없는 운영 맥락, 팀의 규칙, 과거의 사고를 전제할 수 있다. AI가 그 맥락을 모르면 자신감 있게 틀린 경고를 만들거나, 반대로 중요한 위험을 놓칠 수 있다.

소유권은 사람을 호출하는 주소록이다

고위험 변경에 사람이 필요하다는 말은 너무 일반적이다. 누가 봐야 하는가가 남는다.

GitHub의 CODEOWNERS는 경로나 파일 패턴별로 책임자나 팀을 지정하고, branch protection과 결합하면 해당 소유자의 승인을 병합 조건으로 둘 수 있다.[5] 이것이 전문성을 자동으로 만드는 장치는 아니다. CODEOWNERS에 이름이 있다고 그 사람이 모든 변경을 이해한다는 보장은 없다. 그래도 “이 코드는 누구의 문맥 안에 있는가”라는 질문에 답할 수 있게 한다.

AI는 여기서 적합한 라우터가 될 수 있다. diff가 바꾼 경로를 읽고, 소유자를 찾고, 변경 요약과 영향 후보를 같이 보낸다. 보안 경로와 결제 규칙을 동시에 바꿨다면 한 사람에게 모든 판단을 몰아주지 않고, 필요한 도메인 소유자에게 서로 다른 질문을 보낼 수 있다.

다만 소유권은 리뷰 요청의 시작이지 끝이 아니다. 실제 담당자가 부재할 수 있고, 오래된 ownership map이 현실을 반영하지 않을 수 있으며, 여러 변경의 결합 위험은 경로 하나로는 잡히지 않는다. 그래서 “누구에게 보낼까”와 함께 “무엇을 판단해 달라고 할까”가 필요하다.

병합 gate는 AI 리뷰와 분리되어야 한다

AI가 위험을 요약하고 리뷰어를 추천한다고 해서, AI가 병합 권한까지 가져야 하는 것은 아니다. GitHub의 protected branch 설정은 필요한 승인 수, code-owner review, 최신 변경 뒤 재승인, 상태 검사를 병합 조건으로 둘 수 있다.[6] 이런 정책 층은 리뷰 코멘트를 쓰는 도구와 분리해 두는 편이 좋다.

왜냐하면 리뷰의 발견은 확률적이지만, 병합의 권한은 규칙이어야 하기 때문이다. AI가 “아마 괜찮다”고 말할 수는 있다. 하지만 보안 설정 파일을 건드린 PR은 보안 담당자의 검토가 필요하다는 규칙은 더 단단해야 한다. 테스트가 통과했어도 migration에는 rollback 계획이 있어야 한다는 규칙도 마찬가지다.

그래서 자동 병합은 ‘AI가 안전하다고 선언한 상태’가 아니라, 미리 합의한 낮은 위험 범위 안에 있고, 필수 검사를 통과했으며, 되돌릴 수 있고, ownership 정책도 충족했다는 상태로 보는 편이 맞다. 이 네 조건 중 하나라도 비어 있으면, 빠르게 병합하는 것보다 올바르게 라우팅하는 편이 낫다.

무엇을 측정하면 라우터가 망가지는지 보인다

자동 승인 비율이 높아지면 처음에는 좋아 보인다. 하지만 그 수치 하나만 보면 위험한 변경까지 빨리 합친 것과, 정말 단순한 변경을 잘 분류한 것을 구분할 수 없다. AI finding 수가 늘어도 마찬가지다. 사람들이 무시하는 경고만 늘었을 수 있다.

리뷰 라우터를 운영한다면 자동 승인 비율과 함께 rollback·incident·누락된 결함을 봐야 한다. finding 수와 함께 사람이 실제로 채택한 비율, 기각한 이유, 표본 검토에서의 정확도를 봐야 한다. code owner 요청 수와 함께 응답 지연, 재할당, override 이유를 봐야 한다. 리뷰 시간이 줄었다면 change failure와 재작업이 줄었는지도 확인해야 한다.

이 지표들은 AI를 감시하기 위한 숫자만은 아니다. 팀의 주의력이 어디에서 막히는지 보여 주는 지도다. 보안 담당자에게 요청이 몰린다면 모델을 바꾸기 전에 ownership과 승인 정책을 바꿔야 할 수 있다. false positive가 많다면 더 많은 경고를 만들기보다 근거 표현을 고쳐야 할 수 있다.

AI가 코드를 더 빨리 만드는 시대에 리뷰는 사라지지 않는다. 오히려 사람의 판단이 필요한 순간을 더 정교하게 골라내는 일이 된다. 좋은 코드리뷰 AI는 모든 PR에 LGTM을 붙이는 도구가 아니다. 사람이 가장 잘 아는 위험한 코드 앞에, 충분한 맥락을 갖춰 도착하게 만드는 도구에 가깝다.

그 경로를 잘 설계하는 팀은 코드 생성 속도보다 조금 더 오래 가는 것을 얻을지도 모른다. 사람의 주의력을, 정말 비싼 변경에 남겨 둘 수 있으니까.

여기서 작은 함정이 하나 있다. 저위험 변경을 빨리 통과시키려다 보면, 큰 변경을 인위적으로 잘게 쪼개 위험을 숨길 수 있다. 각 PR만 보면 문서 한 줄, 설정 한 줄, dependency 한 줄인데, 합치면 권한 경계가 바뀌는 경우다. 그래서 라우터는 PR 한 장의 diff만 읽어서는 안 된다. 같은 작업 티켓, 같은 브랜치, 가까운 시간에 이어진 변경, 함께 배포되는 configuration을 가능한 한 연결해 보아야 한다. 작은 변경을 권하는 것과 작은 단위만 보라는 것은 다른 말이다.

또한 라우팅은 공정성의 문제이기도 하다. AI가 특정 디렉터리의 PR만 계속 ‘고위험’으로 표시하면, 그 영역의 담당자는 항상 긴급한 검토 요청을 받게 된다. 반대로 조직도가 오래되어 CODEOWNERS가 실제 전문성을 반영하지 못하면, 가장 바쁜 사람에게도 가장 낯선 변경이 도착한다. 요청 수, 응답 지연, 재할당, override 사유를 기록하는 이유는 모델의 정확도만 재기 위해서가 아니다. 주의력의 부담이 팀 안에서 어디에 쏠리는지 보기 위해서다.

그래서 잘 만든 라우터는 단지 PR을 분류하지 않는다. 리뷰 요청을 더 좋은 질문으로 바꾼다. 보안 리뷰어에게는 “이 변경이 인증 경계를 넓히는가”를, 도메인 담당자에게는 “이 예외가 환불 규칙과 충돌하는가”를, 릴리스 담당자에게는 “실패하면 어느 상태까지 되돌릴 수 있는가”를 묻는다. 같은 diff를 세 번 읽게 하는 대신, 세 사람이 자신이 잘 아는 질문 하나씩에 집중하게 한다.

이런 구조에서 AI의 실패도 더 관리하기 쉬워진다. 발견을 놓쳤다면 어떤 위험 축이 비어 있었는지 볼 수 있다. 거짓 경고가 많다면 모델을 즉시 바꾸기보다, 근거 없이 심각도를 붙이는 정책이 문제인지 확인할 수 있다. 리뷰어가 계속 override한다면 ownership map이 낡았는지 살필 수 있다. 결국 리뷰 자동화의 품질은 AI가 몇 개의 버그를 잡았는가보다, 팀이 변화의 위험을 더 빨리 이해하고 더 적절하게 나누게 되었는가에 가까울 것이다.

이 관점은 코드리뷰를 인간과 AI의 대결로 만들지 않는다. AI는 반복 확인과 맥락 정리를 맡고, 사람은 위험을 받아들일지와 무엇을 포기하지 않을지를 결정한다. 둘의 경계가 분명할수록, 자동화는 더 빨라져도 리뷰의 책임은 흐려지지 않는다.

[1]: The Standard of Code Review

[2]: Small CLs

[5]: GitHub Docs: About code owners

[6]: GitHub Docs: About protected branches

[3]: Rethinking Code Review Workflows with LLM Assistance: An Empirical Study

[4]: CodeReviewQA