코드 리뷰를 없애는 법
TMT원문: How to Kill the Code Review (Ankit Jain, Latent Space, 2026-03-03)
사람이 직접 쓰는 코드는 2025년에 사라졌습니다. 코드 리뷰는 2026년에 사라질 것입니다.
편집자 주: 이 글은 저희 게스트 포스트 프로그램의 최신 기고입니다. 저희가 개인적으로 동의하지 않더라도 곱씹어 볼 가치가 있는 AI 엔지니어링 에세이를 싣는 자리인데, 마침 AI 리뷰 도구를 출시한 직후라 저 자신은 아직 이 글의 주장까지 가지 못했습니다. 그래도 분명히 다가오고 있는 흐름이기에, Ankit이 이 주장을 펼치는 것을 기쁘게 소개합니다!
사람이 사람의 속도로 코드를 쓰던 시절에도, 코드 리뷰는 이미 사람이 감당하지 못하는 일이었습니다. 제가 이야기를 나눠 본 엔지니어링 조직마다 똑같은 부끄러운 비밀을 안고 있습니다. PR은 며칠씩 방치되고, 승인 도장은 형식적으로 찍혀 나가고, 리뷰어는 자기 일이 따로 있으니 500줄짜리 diff를 대충 훑고 넘어갑니다.
우리는 코드 리뷰가 품질을 지키는 관문이라고 스스로를 다독이지만, 한 줄 한 줄 리뷰하지 않고도 제품을 내놓아 온 팀은 수십 년 전부터 있었습니다. 한 베테랑 엔지니어의 말로는 코드 리뷰가 어디서나 당연해진 것도 2012~2014년 무렵부터인데, 그 이전을 기억할 만큼 오래 일한 사람이 이제 많지 않을 뿐입니다.
그리고 리뷰를 해도 장애는 터집니다. 리뷰만으로는 부족하다는 사실을 받아들였기에, 우리는 실패를 감당하는 시스템을 만드는 법을 익혀 왔습니다. 피처 플래그, 단계적 배포, 즉시 롤백 같은 장치가 바로 그 증거입니다.
모든 코드를 읽겠다는 생각은 포기해야 합니다
1,255개 팀, 1만 명이 넘는 개발자를 조사한 데이터에 따르면, AI 도입률이 높은 팀은 작업을 21% 더 많이 끝내고 풀 리퀘스트를 98% 더 많이 머지하지만, PR 리뷰 시간은 91% 늘어납니다.
두 가지가 기하급수적으로 불어나고 있습니다. 변경의 횟수와 변경의 크기입니다. 이만한 양의 코드를 사람이 다 소화할 수는 없습니다. 그걸로 끝입니다. 게다가 개발자들은 AI가 생성한 코드를 리뷰하는 일이 동료가 쓴 코드를 리뷰할 때보다 더 힘들다고 입을 모읍니다. 팀은 코드를 더 많이 만들어 내고, 그 코드를 리뷰하는 데 더 많은 시간을 씁니다.
수동 코드 리뷰로는 이 싸움에서 이길 방법이 없습니다. 코드 리뷰는 과거에 만들어진 승인 관문일 뿐, 이제는 일의 모양과 맞지 않습니다.
AI 코드 리뷰도 결국 리뷰입니다
AI 코드 리뷰 도구는 시간을 벌어 줄 뿐입니다. AI가 코드를 쓰고 AI가 리뷰까지 한다면, 그 과정을 보여 주는 예쁜 리뷰 UI가 왜 필요할까요? AI 코드 리뷰가 아무리 가치 있다 해도, 결국 개발 주기의 앞 단계로 옮겨 갈 것입니다. 리뷰 사이클 사이에서 CI 자원을 낭비하고 버전 관리를 이어 갈 이유가 없습니다.
PR 이후에 하는 리뷰는 사람이 코드를 쓰고 다른 사람의 새로운 시선이 필요하던 시절에나 의미가 있었습니다. 에이전트가 코드를 쓰는 지금, "새로운 시선"이란 같은 맹점을 지닌 또 다른 에이전트일 뿐입니다. 가치는 승인 관문이 아니라 반복 루프에 있습니다.
에이전트가 늘 믿을 만하지는 않다는 것을 우리는 경험으로 압니다. 그리고 "AI가 바보 같은 짓을 하는 걸 한 번 잡아냈으니 앞으로도 항상 검사해야 한다"고 생각하는 것은 지극히 인간적인 반응입니다. 손으로 하나하나 검증할 수 있던 시절에는 그 본능이 옳았습니다. 지금의 규모에서는 더 이상 통하지 않습니다. 그리고 상황은 점점 더 나빠질 것입니다.
코드 리뷰에서 의도 리뷰로
해법은 사람이 확인하는 지점을 개발 흐름의 상류로 옮기는 것입니다. 코드를 리뷰하지 않는다는 생각이 무섭게 느껴진다면, 소프트웨어 개발에서 확인 지점이 옮겨진 것이 처음이 아니라는 사실을 떠올려 보시기 바랍니다. 우리는 워터폴 시대의 단계별 결재를 지속적 통합으로 바꿔 냈습니다. 다시 한 번 옮기지 못할 이유가 없습니다.
스펙 주도 개발(spec-driven development)이 AI와 일하는 주된 방식으로 자리 잡고 있습니다. 사람이 리뷰해야 할 것은 500줄짜리 diff가 아니라 스펙, 계획, 제약 조건, 인수 기준입니다.
이 새로운 패러다임에서는 스펙이 신뢰할 수 있는 유일한 원천이 됩니다. 코드는 스펙에서 파생된 산출물이 됩니다. 코드를 리뷰할 필요가 없습니다. 단계를 리뷰하고, 검증 규칙을 리뷰하고, 코드가 지켜야 할 계약을 리뷰하면 됩니다.
사람이 개입해 승인할 때 던지는 질문도 "이 코드를 제대로 짰는가?"에서 "우리가 올바른 제약 조건 아래 올바른 문제를 풀고 있는가?"로 바뀝니다. 사람의 판단이 가장 값지게 쓰이는 시점은 코드 첫 줄이 생성된 뒤가 아니라 그 전입니다.
층층이 쌓아 올리는 신뢰
코드 읽기를 그만두기 전에, 우리는 어디까지 안심할 수 있어야 할까요?
규칙으로 적으면 이렇습니다.
코드는 사람이 작성해서는 안 된다.
코드는 사람이 리뷰해서는 안 된다.
LLM은 지시를 잘 따르는 편이 아닙니다. 자주, 아주 자주 벗어납니다. 자기 검증도 믿을 만하지 못해서, 코드가 불타고 있는 와중에도 잘 돌아간다고 자신 있게 말합니다. 해결책은 LLM에게 검증을 시키는 것이 아니라, 검증하는 스크립트를 쓰게 하는 것입니다. 판단에 기대던 것을 산출물에 기대는 쪽으로 바꾸는 것입니다.
신뢰는 층으로 쌓입니다. 스위스 치즈 모델 그대로입니다. 어떤 관문도 혼자서 모든 것을 잡아내지 못하므로, 구멍이 서로 겹치지 않을 때까지 불완전한 필터를 겹겹이 쌓는 것입니다. 그렇다면 승인 관문을 또 어디에 둘 수 있을까요?
레이어 1: 여러 선택지를 비교하기
에이전트 하나에게 정답을 요구하는 대신, 세 에이전트에게 서로 다르게 시도하게 하고 가장 좋은 결과를 고르십시오. 경쟁을 붙이는 것입니다. 여러 선택지를 마련하는 비용이 소프트웨어 엔지니어링 역사상 지금보다 낮았던 적이 없습니다.
고르는 일조차 손으로 할 필요가 없습니다. 검증 단계를 가장 많이 통과한 결과는 무엇인지, diff가 가장 작은 결과는 무엇인지, 새 의존성을 들이지 않은 결과는 무엇인지를 기준으로 순위를 매기면 됩니다. 경쟁은 한 번의 시도로는 얻을 수 없는 신호를 만들어 냅니다.
레이어 2: 결정론적 가드레일
작업을 검증하는 결정론적인 방법이 있어야 합니다. 테스트, 타입 검사, 계약 검증처럼 의견 없이 사실만 말하는 장치들입니다.
LLM에게 "이거 잘 됐어?"라고 묻는 대신, 통과/실패 결과물을 차례로 남기는 검증 단계를 정의합니다. 실패하는 테스트 앞에서 에이전트는 흥정할 수 없습니다. 스펙을 충족하거나 못 하거나, 둘 중 하나입니다.
이 가드레일 자체도 여러 층으로 정의할 수 있습니다.
- 코딩 가이드라인: 커스텀 린터로 만들 수 있습니다.
- 조직 전체의 불변 규칙: 타협할 수 없는 것들입니다. 예를 들어 자격 증명, API 키, 토큰은 하드코딩하지 않는다는 규칙입니다.
- 도메인 계약: 특정 프레임워크나 서비스, 코드베이스의 일부에만 적용됩니다. 예를 들어 결제 도메인이라면 모든 금액은 Money 타입을 쓴다는 식입니다.
- 인수 기준: 해당 작업에만 적용됩니다.
검증 단계는 코드를 쓰기 전에 정의해야 합니다. 이미 있는 코드를 정당화하려고 나중에 만들어 붙이는 것이 아닙니다. 에이전트가 코드와 테스트를 둘 다 쓴다면 문제를 옮겨 놓은 것에 지나지 않습니다. 이번에는 에이전트가 올바른 것을 테스트했다고 믿어야 하니까요. 검증 기준은 구현이 아니라 스펙에서 나와야 합니다.
레이어 3: 인수 기준은 사람이 정의하기
그렇다면 사람은 어디에서 가치를 더할까요? 상류에서, 성공이 어떤 모습인지 정의하는 일입니다.
여기서 행위 주도 개발(BDD)이 새삼 다시 의미를 갖습니다. 기대하는 동작을 자연어 명세로 쓰고 그 명세를 테스트로 자동화한다는 BDD는 언제나 좋은 아이디어였습니다. 그런데도 널리 퍼지지 못한 것은, 어차피 코드도 직접 쓸 사람 입장에서 명세 작성이 군더더기 일처럼 느껴졌기 때문입니다.
에이전트가 등장하면서 셈법이 뒤집힙니다. 스펙은 더 이상 부가 작업이 아니라 핵심 산출물입니다. 사람은 이렇게 씁니다.
에이전트가 구현하고, BDD 프레임워크가 검증합니다. 무언가 실패하지 않는 한 구현 코드를 읽을 일이 없습니다.
이것이야말로 사람이 잘하는 일을 사람이 맡는 구도입니다. "올바르다"가 무엇을 뜻하는지 정의하고, 비즈니스 로직과 엣지 케이스를 규칙으로 담아내고, 무엇이 잘못될 수 있는지 고민하는 일 말입니다. 의도를 코드로 옮기는 일은 에이전트가 맡습니다. BDD 명세는 결정론적이고 자동화되어 있으며 코드 첫 줄이 쓰이기 전에 정의되는 검증 레이어가 됩니다.
사람이 쓰고 기계가 검증하는 인수 기준. 그것이 진짜 의미 있는 관문입니다.
레이어 4: 권한 시스템을 아키텍처로 다루기
이 에이전트가 손댈 수 있는 범위는 어디까지인가? 무엇을 사람에게 올려 보내야 하는가? 이런 질문이 나중에 덧붙이는 고민이 아니라 아키텍처 결정이 됩니다.
대부분의 에이전트 프레임워크는 권한을 전부 아니면 전무로 다룹니다. 셸 접근 권한이 있거나 없거나 둘 중 하나입니다. 하지만 세분화가 중요합니다. 유틸리티 함수의 버그를 고치는 에이전트에게 인프라 설정 접근 권한은 필요 없습니다. 테스트를 쓰는 에이전트가 CI 파이프라인을 수정할 이유도 없습니다.
에이전트가 쓸모 있는 일을 할 수 있는 선에서 권한 범위는 최대한 좁아야 합니다. 작업이 "utils/dates.py의 날짜 파싱 버그를 고쳐라"라면, 에이전트의 파일 시스템 접근은 그 파일과 그 테스트 파일로 제한되어야 합니다. 코드베이스 전체도 아니고, "src/와 tests/"도 아니고, 이 작업에 필요한 파일만입니다.
사람에게 올려 보내는 조건도 그만큼 중요합니다. 인증 로직을 건드리거나, 데이터베이스 스키마를 수정하거나, 새 의존성을 추가하는 것 같은 특정 패턴은 에이전트가 아무리 자신만만해도 자동으로 사람의 리뷰 대상으로 표시되어야 합니다.
레이어 5: 적대적 검증
책임을 분리하는 것입니다. 한 에이전트가 일하고, 다른 에이전트가 검증합니다. 둘은 서로를 믿지 않으며, 바로 그것이 핵심입니다.
이는 오래된 패턴입니다. QA 팀이 엔지니어링 매니저에게 보고하면 안 되는 이유, 코드를 쓴 사람이 그 코드를 혼자 리뷰해서는 안 되는 이유와 같습니다.
에이전트를 쓰면 이 원칙을 아키텍처 차원에서 강제할 수 있습니다. 코딩 에이전트는 검증 에이전트가 무엇을 확인할지 알지 못합니다. 검증 에이전트에게는 자기 일을 편하게 하려고 코드를 고칠 능력이 없습니다. 애초에 적대적으로 설계된 관계입니다.
한 걸음 더 나아갈 수도 있습니다. 세 번째 에이전트가 첫 번째 에이전트의 결과물을 깨뜨리려 시도하면서 엣지 케이스와 실패 시나리오를 집중적으로 공략하는 것입니다. 레드 팀 대 블루 팀 구도를 자동화해서 모든 변경마다 돌리는 셈입니다.
맺음말: "좋은 코드"의 모습이 달라지고 있습니다
에이전트 시스템을 움직이는 유인은 단순합니다. 주어진 작업을 끝낼 수 있는가? 작업을 준 사람을 만족시킬 수 있는가? 에이전트의 성공이 장기적인 정확성이나 비즈니스 요구사항에서 저절로 나오는 일은 없습니다.
그것을 제약 조건에 새겨 넣는 일이 우리의 몫입니다.
에이전트가 생성하고 에이전트가 읽는 코드에서는 "좋은 코드"의 모습이 지금보다 더 표준화될 것입니다. 기본값이 더 일관되어질 테니, 새 코드베이스를 시작할 때 일일이 방향을 잡아 줄 일도 줄어들 것입니다.
미래는 빠르게 배포하고, 모든 것을 관측하고, 더 빠르게 되돌리는 쪽에 있습니다.
느리게 리뷰하고, 그러고도 버그를 놓치고, 프로덕션에서 디버깅하는 쪽이 아닙니다.
읽기 경쟁으로는 기계를 이길 수 없습니다. 생각으로 앞서야 합니다. 결정이 실제로 중요해지는 상류에서 말입니다.
결국 에이전트가 코드를 잘 다룰 수 있다면, 우리가 그 코드를 읽을 수 있는지 없는지가 무슨 상관이겠습니까?
Ankit Jain은 Aviator의 창업자이자 CEO로, AI 네이티브 엔지니어링 팀을 위한 인프라를 만들고 있습니다. Aviator의 플랫폼은 현대 조직이 높은 엔지니어링 수준을 유지하면서 AI 도입을 넓혀 가도록 돕습니다.