AI가 코드 검토를 무너뜨린 것이 아니라, 우리가 코드 검토로 잘못된 문제를 해결하려 했던 것일 수 있다.
요약
혹은 문제는 AI가 코드 검토를 망가뜨렸다는 것이 아니라, 우리가 코드 검토로 잘못된 문제들을 해결하려 해왔다는 것일지도 모른다
최근 Moderne이 주최한 자리에서 Code Remix의 DX 소속 Brian Houck와 함께 패널에 참여했다. 내가 했던 패널 중 더 흥미로운 축에 속했는데, 주로 우리가 의견이 달랐기 때문이다. 내 동료 Martin Fowler가 말하듯, 패널은 사람들이 의견이 다르고 양쪽 모두 좋은 논거를 가질 때 훨씬 더 흥미롭다. Brian과 나는 확실히 그랬다.
Brian은 이후 도대체 코드 검토는 무엇을 위한 것인가?라는 사려 깊은 글을 썼다. 그는 자신의 입장에 분명한 열정을 갖고 있고, 나 역시 내 입장에 충분한 열정이 있어서 이 답글을 쓰고 있다. 분명히 하자면, 우리는 대체로 같은 것을 원한다고 생각한다. 다만 나는 코드 검토가 그것들을 얻는 가장 좋은 방법이라고 생각하지 않는다. 그나저나 Brian은 멋진 사람이며, 내가 이 글을 쓰도록 격려해 주었다. 하지만 끝까지 읽고 나서 여러분이 내가 옳다고 생각해 주길 바라지 않는다고 말한다면 거짓말일 것이다 :)
그렇다면 우리는 무엇에 대해 의견이 달랐을까?
AI는 사람이 현실적으로 검토할 수 있는 것보다 더 많은 코드를 만들고 있다. Brian은 꽤 인상적인 수치를 인용한다. Meta에서는 인간이 반영한 변경분 하나당 유의미한 코드 줄 수가 1년 동안 106% 증가한 것으로 알려졌고, DX 자체 데이터에서는 풀 리퀘스트 크기 중앙값이 64% 증가했다.
나도 공유하는 그의 우려는 코드 검토를 그저 자동화해 없애 버리면, 우리가 코드 검토에 활용하는 다른 모든 것을 잃을 위험이 있다는 점이다. 코드 검토는 단지 버그를 찾는 일이 아니다. 팀이 지식을 공유하고, 주니어 엔지니어를 가르치며, 공동 소유 의식을 만들고, 아키텍처 이해를 퍼뜨리는 방식이기도 하다.
내 질문은 이것이다. 왜 우리는 그 모든 일을 코드 검토 때까지 기다렸다가 하는가?
나는 소프트웨어 개발 과정의 중심으로서 풀 리퀘스트를 특별히 좋아한 적이 없다. 엔지니어들이 서로의 코드를 보면 안 된다고 생각해서가 아니라, 무언가를 만들고, 완성하고, 포장해서, 다른 누군가에게 넘긴 뒤, 그때서야 우리가 올바른 것을 올바른 방식으로 만들었는지에 관한 중요한 대화를 나눠야 한다는 생각이 늘 불편했기 때문이다.
병합 충돌 이야기는 꺼내지도 말자. 내 인생에서 너무 많은 시간을 잃었다.
Thoughtworks에서 아주 일찍 배운 원칙 중 하나는 피드백 루프를 짧게 만드는 것이었다. 피드백이 가치 있다면 없애지 말라. 그것이 알려 주는 의사결정에 더 가깝게 옮겨라.
코드 검토가 우리에게 준다고 말하는 것들을 생각해 보자.
대안적 해결책을 탐색하고 싶다면, 그중 하나를 구현하기 전에 그렇게 하는 편이 낫다.
지식 전수를 원한다면, 페어로 작업하라. 누군가가 문제를 추론해 나가는 동안 물리적으로든 가상으로든 곁에 앉아 있으면, 나중에 완성된 해결책을 읽는 것보다 훨씬 더 많이 배운다.
주니어 엔지니어가 경험 많은 엔지니어의 사고방식을 배우기 원한다면, 그들이 사고하는 동안 경험 많은 엔지니어와 함께 일하게 하라. 여기서도 페어링이 떠오르지만, 팀은 무언가를 작성하기 전에, 또는 에이전트에게 작성하라고 지시하기 전에 화이트보드를 활용해 함께 설계 세션을 할 수도 있다.
공동 소유를 원한다면, 누군가가 이미 만든 것을 풀 리퀘스트로 모두에게 알리는 데 의존하기보다 사람들이 실제로 소프트웨어를 함께 만들고 운영하도록 팀을 구성하라. 이를 위해서도 페어링, 몹 프로그래밍 또는 화이트보드 중심의 팀 설계 세션을 활용하라.
아키텍처 정렬을 원한다면, 함께 설계하고(페어링과 팀 설계 세션 이야기를 반복하지는 않겠다, 아 잠깐…) 중요한 제약 조건을 피트니스 함수로 인코딩하라.
서식, 린팅, 알려진 보안 문제 또는 결정적으로 테스트할 수 있는 것들을 위해 코드를 검토한다면, 그것들을 자동화하라. 2026년에 여전히 공백을 두고 논쟁해서는 정말 안 된다.
페어 프로그래밍, 트렁크 기반 개발, 자동화된 테스트, 정적 분석, 피트니스 함수 및 보안 스캐닝은 모두 피드백을 더 이르게 가져온다. 점점 더 에이전트도 설계에 이의를 제기하고, 가정을 시험하며, 만들어지는 것을 지속적으로 검증하면서 그 루프에 참여할 수 있다. 하지만 진짜 사고는 경험 많은 인간에게서 나오며, 그 경험이 팀 전체에 도움이 되기를 바란다면 코드 검토보다 훨씬 이른 시점부터 팀처럼 행동해야 한다.
이 모든 것이 아무도 코드를 검토하지 않는다는 뜻은 아니다. 나는 분명 다른 경험 많은 사람이 살펴보기를 원하는 변경이 있다. 예를 들어 근본적인 아키텍처 변경이 그렇다. 더 넓은 팀과 설계 세션을 했다고 가정하면, 팀으로서 코드를 검토하거나 그것이 올바르게 구현되었는지 합의하거나, 무엇을 바꾸고 싶은지 논의할 수 있다. 다른 예로는 민감한 보안 경계를 넘는 작업, 파급 범위가 매우 큰 변경, 핵심 시스템 중 익숙하지 않은 부분, 또는 단순히 팀이 “이것에 자신이 없어요”라고 말하는 경우가 있다.
바로 그런 곳에서 인간의 판단이 가치 있다. 하지만 이는 역사적으로 신뢰를 만들기 위해 사용해 온 절차라는 이유로 모든 변경을 사람이 검사하도록 요구하는 것과는 매우 다르다.
이제 우리는 이 길을 계속 가는 것이 가능하지 않다는 것을 알고 있다. 그래서 코드 검토가 계속 문제나 장애물로 거론된다. 에이전트가 열 배의 코드를 만들 수 있지만 모든 줄이 결국 시니어 엔지니어의 검사를 기다리는 대기열에 들어간다면, 우리는 열 배 규모의 엔지니어링 조직을 만든 것이 아니라 큰 백로그와 새로운 병목을 만든 것이다.
그리고 정확히 같은 과정을 더 빠른 속도로 유지할 수 있도록 AI 에이전트가 인간 검토자인 척하는 것이 답이라고 생각하지 않는다. 그것은 왜 그 절차가 존재하는지 질문하기보다 절차를 자동화하는 일이다.
그렇지만 Brian의 주장에는 내가 우려하는 한 가지가 있다. 그는 팀에 인지적 부채와 의도 부채가 축적된다고 말한다. 소프트웨어는 성장하지만, 그것을 책임지는 인간은 왜 그것이 그런 방식으로 작동하는지 점점 덜 이해하게 된다는 것이다. 나는 이것이 매우 현실적인 문제라고 생각한다. 다만 의무적인 풀 리퀘스트가 이에 대한 특별히 강력한 방어책이라고는 생각하지 않는다.
에이전트가 구현의 상당 부분을 만들어 낼 예정이라면, 우리는 협업 설계, 페어링, 좋은 경계, 실행 가능한 아키텍처, 공유된 운영 책임, 그리고 아마도 아직 발명하지 못한 몇 가지 실천법을 통해 인간의 이해를 유지하는 데 훨씬 더 의도적이어야 한다.
우리는 엔지니어가 변경분이 아니라 시스템을 이해하도록 해야 한다.
어쩌면 AI가 드러내는 것이 바로 이것일지도 모른다. 우리는 수년간 소박한 코드 검토에 엄청나게 많은 책임을 실어 왔다. 품질 관문, 보안 검사, 아키텍처 검토, 멘토링 장치, 지식 공유 체계, 소유 모델.
인간이 코드를 빠르게 만들 수밖에 없던 동안에는, 어쨌든 어느 정도 작동했다. 그 제약은 사라지고 있다. 그러니 질문은 코드를 어떻게 더 빨리 검토할지가 아닐지도 모른다. 애초에 왜 우리는 모든 중요한 대화를 코드 검토 때까지 기다렸다가 나누는가가 질문일지도 모른다.