모든 코드를 검토해야 하는 것이 아닐지도 모릅니다
요약
AI가 코드 리뷰의 필요성을 재정의하게 만들고 있으며, 단순히 버그를 찾는 것을 넘어 지식 공유와 아키텍처 이해도 확산에 초점을 맞춰야 합니다. 필자는 풀 리퀘스트 중심의 개발 프로세스 자체에 의문을 제기하며, 피드백 루프를 '판단 시점 왼쪽으로 이동'시키는 것이 중요하다고 강조합니다.
핵심 포인트
- 코드 리뷰는 버그 찾기 외 지식 공유와 소유권 구축이 목적이다.
- 풀 리퀘스트 중심의 개발 프로세스 자체에 의문을 제기해야 한다.
- 지식 전수나 학습은 페어 프로그래밍이나 디자인 세션으로 대체 가능하다.
- 피드백 루프를 가능한 한 '판단 시점 왼쪽'으로 이동시켜야 한다.
요약(TL;DR) 혹은, 문제는 AI가 코드 리뷰를 망가뜨렸다는 것이 아니라, 우리가 잘못된 문제를 해결하기 위해 코드 리뷰를 사용해 왔을 수도 있습니다.
최근 저는 Moderne이 주최한 Code Remix에서 DX의 Brian Houck과 패널에 참여했습니다. 제가 진행했던 패널 중 가장 흥미로웠던 것 중 하나였는데, 그 이유는 저희가 의견이 달랐기 때문입니다. 동료인 Martin Fowler가 말했듯이, 사람들의 의견이 다르고 양쪽 모두 좋은 주장을 할 때 패널은 훨씬 더 흥미롭습니다. Brian과 저는 확실히 그랬습니다.
Brian은 이후 *What are code reviews even for?*라는 사려 깊은 글을 작성했습니다. 그는 자신의 입장에 대해 분명한 열정을 가지고 있으며, 저 역시 제 입장에 충분한 열정이 있어서 이 답변을 쓰고 있습니다. 명확히 하자면, 저는 우리가 대부분 같은 것을 원한다고 생각합니다. 단지 코드 리뷰가 그것들을 얻는 가장 좋은 방법이라고 생각하지 않을 뿐입니다. 그건 그렇고, Brian은 정말 좋았고 제가 이것을 쓰도록 격려했습니다. 하지만 끝날 때까지 제가 옳다고 생각하게 만들고 싶지 않다면 거짓말일 겁니다 :)
그렇다면 우리는 무엇에 대해 의견이 달랐던 걸까요?
AI는 인간이 현실적으로 검토할 수 있는 것보다 더 많은 코드를 생산하고 있습니다. Brian은 몇 가지 매우 인상적인 숫자를 언급합니다: Meta에서는 한 해 동안 인간이 도착시킨 diff당 상당한 코드 라인 수가 106% 증가했다고 보고되었고, DX 자체 데이터는 중앙값 풀 리퀘스트 크기가 64% 증가했음을 보여줍니다.
제가 공감하는 그의 우려는 단순히 코드 리뷰를 자동화하여 제거하는 것이 우리가 그것을 위해 사용하는 다른 모든 것들을 잃을 위험이 있다는 것입니다. 코드 리뷰는 단지 버그를 찾는 것에 관한 것이 아닙니다. 팀이 지식을 공유하고, 주니어 엔지니어를 가르치고, 집단적인 소유권을 구축하며, 아키텍처 이해도를 확산하는 방법입니다.
제 질문은 이것입니다: 우리는 왜 이 모든 것들을 하기 위해 코드 리뷰를 기다리고 있는 걸까요?
저는 소프트웨어 개발 프로세스의 중심에 풀 리퀘스트(pull request)를 두는 것을 별로 좋아한 적이 없습니다. 엔지니어들이 서로의 코드를 검토하지 말라는 뜻은 아니지만, 우리가 무언가를 구축하고, 그것을 완성하고, 패키징해서 다른 사람에게 던져준 다음 비로소 제대로 된 것(right thing)을 올바른 방식(right way)으로 만들었는지에 대해 중요한 대화를 나누어야 한다는 생각에 항상 어려움을 느꼈기 때문입니다.
그리고 머지 충돌(merge conflicts) 이야기는 꺼내지도 마세요. 제 인생의 너무 많은 시간을 잃었습니다.
판단 시점을 왼쪽으로 이동시키기 (Shift the judgment left)
Thoughtworks에서 일찍 배운 원칙 중 하나는 피드백 루프(feedback loops)를 단축하는 것이었습니다. 피드백이 가치 있다면, 그것을 제거하지 마세요. 의사결정에 영향을 미치는 지점 가까이로 옮기세요.
코드 리뷰가 우리에게 주는 것들을 생각해 보세요.
만약 우리가 대안적인 솔루션을 탐색하고 싶다면, 그중 하나를 구현하기 전에 그렇게 하는 것이 낫습니다.
만약 우리가 **지식 전수(knowledge transfer)**를 원한다면, 페어 프로그래밍(pair)을 하세요. 누군가와 옆에 앉아(물리적이든 가상적이든), 그 사람이 문제를 해결하는 과정을 지켜보는 것은 나중에 완성된 솔루션을 읽는 것보다 훨씬 많은 것을 가르쳐 줍니다.
만약 우리가 주니어 엔지니어가 숙련된 엔지니어가 생각하는 방식을 배우게 하고 싶다면, 그들이 생각하는 동안 숙련된 엔지니어와 함께 일하게 하세요. 여기서 다시 페어링이 떠오르지만, 팀은 또한 무언가를 작성하기 전에(또는 에이전트에게 작성하도록 지시하기 전에) 화이트보드를 이용한 디자인 세션을 공동으로 진행할 수도 있습니다.
만약 우리가 **집단적 소유권(collective ownership)**을 원한다면, 사람들이 단순히 누군가가 이미 구축했다고 풀 리퀘스트에 의존하는 대신 실제로 소프트웨어를 함께 구축하고 운영하도록 팀을 구성하세요. 이 경우에도 페어링, 모브 프로그래밍(mob programming), 또는 화이트보드를 중심으로 한 팀 디자인 세션을 사용하세요.
만약 우리가 **아키텍처 정렬(architectural alignment)**을 원한다면, 함께 설계하고(페어링과 팀 디자인 세션에 대해 반복하지 않겠습니다. 아, 잠깐…) 중요한 제약 조건들을 적합성 함수(fitness functions)로 인코딩하세요.
그리고 만약 우리가 코드의 형식(formatting), 린팅(linting), 알려진 보안 문제 또는 결정론적으로 테스트할 수 있는 것들을 검토하고 있다면, 그것들은 자동화해야 합니다. 우리는 정말로 2026년에도 공백(whitespace)에 대해 논쟁해서는 안 됩니다.
페어 프로그래밍(Pair programming), 트렁크 기반 개발(trunk-based development), 자동화된 테스트(automated testing), 정적 분석(static analysis), 적합성 함수(fitness functions), 보안 스캐닝(security scanning) 모두 피드백을 더 일찍 제공합니다. 점점 더 많은 에이전트(agents)가 이러한 루프에 참여하여 디자인에 이의를 제기하고, 가정을 테스트하며, 구축되는 것을 지속적으로 검증할 수 있지만, 진정한 사고는 숙련된 인간에게서 나옵니다. 그리고 우리가 그 경험을 팀 전체에 혜택으로 얻고 싶다면, 우리는 코드 리뷰보다 훨씬 더 일찍 그렇게 행동해야 합니다.
예외를 통한 검토(Review by exception)
이 모든 것이 아무도 코드를 검토하지 않는다는 의미는 아닙니다. 다른 숙련된 인간의 시선이 필요한 변화가 분명히 있습니다. 한 예로는 근본적인 아키텍처 변경입니다. 만약 우리가 더 넓은 팀으로 디자인 세션을 진행했다고 가정하면, 우리는 팀으로서 코드를 검토하거나, 그것이 올바르게 구현되었다고 동의하거나, 아니면 무언가를 변경하고 싶은지 논의할 수 있습니다. 다른 예로는 민감한 보안 경계를 넘나드는 것, 엄청난 파급 효과(blast radius)를 가진 변경, 생소한 중요 시스템 부분, 또는 단순히 팀이 “이것에 대해 확신하지 못한다”고 말하는 경우입니다.
바로 그러한 곳에서 인간의 판단력이 가치 있지만, 그것은 역사적으로 신뢰를 구축하기 위해 사용해 온 의식(ceremony) 때문에 모든 변경 사항을 사람이 검사하도록 요구하는 것과는 매우 다릅니다.
그리고 우리는 이 경로를 계속하는 것이 실행 가능하지 않다는 것을 알고 있습니다. 이것이 바로 코드 리뷰가 문제나 병목 지점으로 계속 언급되는 이유입니다. 만약 에이전트가 코드를 10배 더 많이 생산할 수 있지만, 모든 줄이 결국 선임 엔지니어의 검사를 기다리는 대기열에 들어간다면, 우리는 10배 규모의 엔지니어링 조직을 만든 것이 아니라, 거대한 백로그와 새로운 병목 지점을 만든 것입니다.
저는 그 답이 인간 검토자 행세를 하는 AI 에이전트가 되어 우리가 더 높은 속도로 정확히 동일한 프로세스를 유지하게 만드는 것이라고 생각하지 않습니다. 그것은 의식(ceremony) 자체를 자동화하는 것이지, 왜 그 의식이 존재하는지 근본적으로 질문하는 것은 아닙니다.
하지만 브라이언의 주장 중 한 가지는 걱정됩니다. 그는 팀이 인지 부채(cognitive debt)와 의도 부채(intent debt)를 축적한다고 이야기합니다. 즉, 소프트웨어는 성장하는데 그것을 책임지는 인간들은 그것이 왜 작동하는지에 대해 점점 덜 이해하게 된다는 것입니다. 저는 이것이 매우 현실적인 문제라고 생각합니다. 다만, 의무적인 풀 리퀘스트(pull requests)가 이에 대한 특별히 강력한 방어책이라고는 생각하지 않습니다.
만약 에이전트들이 실질적으로 더 많은 구현을 만들어낼 것이라면, 우리는 협업적 설계(collaborative design), 페어링(pairing), 좋은 경계 설정(boundaries), 실행 가능한 아키텍처(executable architecture), 공유 운영 책임(shared operational responsibility) 등을 통해 인간의 이해도를 유지하는 것에 훨씬 더 신중해야 합니다. 그리고 아마도 우리가 아직 발명하지 못한 몇 가지 관행들이 필요할 것입니다.
우리는 디프(diffs)가 아니라 시스템을 이해하는 엔지니어가 필요합니다.
어쩌면 AI가 드러내고 있는 것이 바로 이것일지도 모릅니다. 우리는 코드 리뷰라는 소박한 과정에 너무나 많은 책임들, 즉 품질 게이트(quality gate), 보안 검사(security check), 아키텍처 검토(architecture review), 멘토링 메커니즘(mentoring mechanism), 지식 공유 시스템(knowledge-sharing system), 오너십 모델(ownership model) 등을 부과하는 데 수년을 보냈습니다.
이것은 인간들이 코드를 생산할 수 있는 속도가 제한적이었을 때는 어느 정도 효과가 있었습니다. 하지만 그 제약이 사라지고 있습니다. 따라서 어쩌면 질문은 우리가 어떻게 코드를 더 빨리 검토받느냐가 아닐지도 모릅니다. 오히려 애초에 중요한 논의들을 코드 리뷰까지 미루고 있는 이유일지도 모릅니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 HN OpenAI Codex의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기