LLM 시대에 더 중요해진 코드 리뷰에서 자주 발생하는 실수와 이를 피하는 방법: diff만 보지 않기, 코멘트를 남발하지 않기, ‘내 방식’ 필터를 버리기, 필요하면 차단 리뷰 남기기, 웬만하면 승인하기에 대한 실전 조언과 맥락.
지난 2년 동안 코드 리뷰는 훨씬 더 중요해졌습니다. 이제 LLM으로 코드를 쉽게 생성할 수 있지만, 리뷰하는 일은 여전히 똑같이 어렵습니다1. 많은 소프트웨어 엔지니어가 이제 동료의 코드보다 자신의 AI 도구가 만든 결과물을 리뷰하는 데 똑같거나 더 많은 시간을 씁니다.
나는 많은 엔지니어들이 코드 리뷰를 제대로 하지 않는다고 생각합니다. 물론 코드 리뷰에는 여러 방식이 있으니, 이는 대체로 나의 엔지니어링 취향에 관한 이야기입니다.
내가 보는 가장 큰 실수는 diff에만 전적으로 집중하는 리뷰입니다2. 가장 영향력이 큰 코드 리뷰 코멘트 대부분은 diff 자체와는 별로 관련이 없고, 대신 시스템의 나머지 부분에 대한 이해에서 나옵니다.
예를 들어, 가장 직관적으로 유용한 코멘트 중 하나는 “여기에 이 메서드를 추가할 필요가 없습니다. 이미 다른 곳에 존재합니다” 같은 것입니다. 이런 코멘트는 diff만 봐서는 나오기 어렵습니다. diff 작성자가 모를 수 있는 코드베이스의 다른 부분에 이미 익숙해야 합니다.
마찬가지로 “이 코드는 아마 다른 파일에 있어야 할 것 같아요” 같은 코멘트는 장기적으로 코드베이스의 품질을 유지하는 데 매우 도움이 됩니다. 큰 코드베이스에서 작업할 때 가장 중요한 가치는 일관성입니다(이에 대해서는 큰·기존 코드베이스에서 엔지니어들이 저지르는 실수에서 더 자세히 썼습니다). 물론 일관성은 diff만으로는 판단할 수 없습니다.
diff만 따로 떼어 리뷰하는 일은, 그것이 전체 코드베이스 속에서 어떻게 맞물리는지를 고려하는 것보다 훨씬 쉽습니다. diff를 빠르게 훑고 라인 코멘트를 남길 수 있습니다(“이 변수 이름 바꾸세요”나 “이 함수의 제어 흐름은 이렇게 흘러야 합니다” 같은). 그런 코멘트도 유용할 수는 있습니다! 하지만 그런 식의 리뷰만 남기면 얻을 수 있는 가치의 상당 부분을 놓치게 됩니다.
아마 코드 리뷰에 관해 내가 가진 가장 논쟁적인 믿음은 좋은 코드 리뷰는 다섯~여섯 개를 넘는 코멘트를 담지 않아야 한다는 것입니다. 대부분의 엔지니어는 코멘트를 너무 많이 답니다. 코멘트가 백 개나 달린 리뷰를 받으면, 사소한 수준을 넘어 그 리뷰에 제대로 응하기가 매우 어렵습니다. 정말 중요한 코멘트는 소음 속에 묻혀버립니다2.5.
diff에서 고치고 싶은 곳이 스무 군데나 있을 때는 어떻게 해야 할까요? 예를 들어 snake_case 대신 camelCase 변수가 스무 번 등장한다면요? 스무 개의 코멘트를 남기는 대신, 나는 스타일상 바꾸고 싶은 내용을 하나의 코멘트로 설명하고, 리뷰 대상 엔지니어가 줄 단위 수정은 스스로 하도록 요청할 것을 권합니다.
이 규칙에도 적어도 한 가지 예외가 있습니다. 새 엔지니어가 팀에 온보딩될 때, 그 코드베이스에서 팀이 사용하는 특정 ‘방언’을 이해하도록 돕기 위해 스타일 코멘트를 한동안 잔뜩 남기는 것이 도움이 될 수 있습니다. 하지만 이 경우에도 당신이 남기는 “진짜” 코멘트는 다른 코멘트들에 묻히기 쉽다는 점을 명심해야 합니다. diff의 모든 early return에 줄 코멘트를 다는 것보다, “이 코드베이스에서는 early return을 사용하지 않습니다” 같은 일반 코멘트를 남기는 편이 여전히 더 나을 수 있습니다.
엔지니어가 코멘트를 너무 많이 다는 이유 중 하나는 다음과 같이 코드를 리뷰하기 때문입니다.
이 방식은 PR에 수백 개의 코멘트를 남기게 되는 지름길입니다. “나는 이 두 연산의 순서를 다르게 했을 것 같다”거나 “나는 이 함수를 조금 다르게 분해했을 것 같다” 같은 끝없는 코멘트의 흐름이 생깁니다.
나는 이런 사소한 코멘트가 항상 나쁘다고 말하는 것은 아닙니다. 때로는 연산 순서가 정말로 중요하거나, 함수가 정말로 나쁘게 분해되어 있을 수도 있습니다. 하지만 소프트웨어 엔지니어링에 관해 내가 가장 강하게 믿는 것 중 하나는 어떤 소프트웨어 문제에도 허용 가능한 접근법이 여럿 존재하며, 그중 무엇을 선택하느냐는 종종 취향의 문제라는 것입니다.
리뷰어로서, 당신이 다르게 했을 경우를 마주쳤더라도, 어느 쪽이든 괜찮다면 그런 경우는 코멘트 없이 승인할 수 있어야 합니다. 그렇지 않으면 동료를 난처하게 만듭니다. 그들은 갈등을 피하려고 당신의 모든 코멘트를 수용해 불필요한 시간을 쓰고, 당신을 코드베이스 변경의 사실상(de facto) 문지기로 만들어버리거나, 혹은 매 사소한 점마다 반박하며 더 많은 시간을 쓰게 됩니다. 코드 리뷰는 당신의 개인적 취향을 동료에게 강요할 시간이 아닙니다.
지금까지는 코멘트 내용만 이야기했습니다. 하지만 코드 리뷰의 “최상위 비트”는 코멘트의 내용이 아니라 리뷰의 _상태_입니다. 즉 승인인지, 코멘트만 남긴 것인지, 차단(blocking) 리뷰인지 말이죠. 리뷰의 상태는 리뷰의 모든 코멘트에 색을 입힙니다. 승인의 코멘트는 “아주 좋은데, 원하면 몇 가지 손봐도 좋아요”처럼 읽힙니다. 차단 리뷰의 코멘트는 “이걸 머지하지 않았으면 하는 이유가 여기 있어요”처럼 읽힙니다.
막고 싶다면, 차단 리뷰를 남기십시오. 많은 엔지니어가 큰 문제가 보이더라도 차단 리뷰를 남기는 건 예의가 아니라고 생각하는 듯합니다. 그래서 문제를 설명하는 코멘트만 남기고 말죠. 그러지 마세요. 그렇게 하면 아무도 자신의 변경을 머지해도 되는지 확신할 수 없는 문화가 만들어집니다. 승인은 “내 코멘트를 무시해도 당신이 머지하는 데 나는 찬성합니다”를 의미해야 합니다. 코멘트만 남기는 것은 “내 코멘트를 무시해도, 다른 누군가가 승인한다면 머지해도 좋습니다”를 의미해야 합니다. 만약 어떤 변경이 머지되면 당신이 불편하거나 화가 날 것 같다면, 그 변경에는 차단 리뷰를 남겨야 합니다. 그래야 변경을 작성한 사람이 머지해도 되는지 확실히 알 수 있고, 코멘트를 남긴 모든 사람에게 일일이 비공식 승인을 받으러 다니지 않아도 됩니다.
단서를 먼저 달겠습니다. 이는 어떤 종류의 코드베이스인지에 크게 좌우됩니다. 예컨대 SQLite 같은 프로젝트에 대한 PR은 대부분 차단 리뷰여도 괜찮다고 생각합니다. 하지만 표준적인 SaaS 코드베이스, 즉 팀이 적극적으로 새로운 기능을 개발하는 곳이라면 대부분의 리뷰가 승인이어야 합니다. 이 두 종류의 코드베이스를 구분하는 이야기는 Pure and Impure Engineering에서 훨씬 자세히 다뤘습니다.
PR이 잔뜩 막히는 상황은 보통 게이트키핑이 과도하게 일어나는 신호입니다. 내가 자주 본 역학은, 한 팀이 다른 많은 팀의 기능에 대한 병목을 쥐고 있는 경우입니다. 예를 들어 새 공개 라우트를 정의해야 하는 에지 네트워크 구성이나, 새 기능이 수정해야 하는 데이터베이스 구조를 그 팀이 소유하고 있는 경우죠. 그런 팀은 보통 일반 기능 팀보다 안정성에 더 초점을 맞춥니다. 그 팀의 엔지니어는 SRE처럼 다른 직함을 갖거나, 아예 다른 조직에 속해 있을 수도 있습니다. 그들의 인센티브는 명목상 지원하는 기능 팀과 어긋나게 됩니다.
가령 기능 팀이 중요한 프로젝트를 출시하기 위해 공개 인그레스 라우트를 업데이트하고 싶다고 합시다. 하지만 에지 네트워킹 팀은 그 프로젝트에 관심이 없습니다. 그들의 리뷰 주기나 상사의 평가에 영향을 주지 않으니까요. 그들의 리뷰에 영향을 주는 것은 변경으로 인해 생길 수 있는 어떤 프로덕션 문제뿐입니다. 즉 그들은 잠재적으로 위험한 모든 변경을 가능한 한 오래 차단하려는 동기를 갖게 됩니다. 이는 새로운 기능을 제공하기 위해 어느 정도의 리스크를 감수할 의향이 있는 기능 팀에게 매우 좌절스러운 일입니다3.
물론 많은 PR이 차단 리뷰를 받는 다른 이유가 있을 수도 있습니다. 회사가 무능한 엔지니어를 한꺼번에 많이 채용해서, 그들의 변경을 머지하지 못하게 막아야 할 수도 있습니다. 회사가 최근 대형 사고를 겪어, 사용자들의 기억에서 사라질 때까지 몇 주 동안 모든 위험한 변경을 차단해야 할 수도 있습니다. 하지만 정상적인 상황에서는, 차단 리뷰가 높은 비율로 나오는 것은 구조적 문제를 나타냅니다.
많은 엔지니어(나를 포함해)에게는 차단 리뷰를 남기는 일이 기분 좋게 느껴집니다. 일반적으로 게이트키핑이 기분 좋은 이유와 같습니다. 마치 혼자서 코드베이스의 품질을 지키거나, 프로덕션 사고를 막고 있는 것처럼 느껴지죠. 또 엔지니어가 흔히 가진 악덕을 충족하는 방식이기도 합니다. 즉, 자신보다 덜 유능한 엔지니어 앞에서 기술 지식을 뽐내는 겁니다. 오, 당신 코드는 N+1 쿼리를 일으킨다는 걸 몰랐군요! 하지만 나는 알고 있었죠. 내가 당신 코드를 읽을 시간을 내 줘서 참 다행이네요?
이 원칙, 즉 변경 승인에 편향을 두어라라는 점은 너무나 중요해서 구글의 코드 리뷰 가이드도 이 내용으로 시작합니다. 그들은 이를 “모든 코드 리뷰 가이드라인 중 가장 상위의 원칙(the senior principle)”이라고 부릅니다4.
이 글의 대부분 혹은 전부에 대해 많은 유능한 엔지니어들이 동의하지 않을 것이라고 꽤 확신합니다. 괜찮습니다! 나도 코드 리뷰에 대해 분명한 사실이라 믿는 것들이 많지만, 여기에는 포함하지 않았습니다.
내 경험상, 다음을 지키는 것이 좋습니다.
이 모든 원칙은 대체로 에이전트형 LLM 시스템이 만든 코드 리뷰에도 적용됩니다. 이들은 작성했어야 할 코드를 누락하기 쉽고, 한꺼번에 백 개 코멘트를 먹이면 길을 잃기 쉽고, 그들만의 스타일을 갖고 있습니다. LLM에 적용되지 않는 한 가지는 “승인에 편향을 두라”는 점입니다. AI가 만든 PR에 대해서는 원하는 만큼 게이트키핑을 해도 됩니다.
마지막으로 말하고 싶은 것은 코드 리뷰에는 정말 다양한 방식이 있다는 점입니다. 코드 리뷰 관행이 충족하고자 할 수 있는 가치들을(완전하지 않은 목록으로) 적어보면: 팀의 여러 사람이 코드베이스의 모든 부분에 익숙해지도록 돕기, 각 변경의 소프트웨어 설계를 팀 차원에서 토론하기, 한 사람이 놓치기 쉬운 미묘한 버그를 잡기, 팀 내에서 지식을 수평으로 전파하기, 각 변경에 대한 인지된 소유감을 높이기, 코드 스타일과 포맷 규칙을 코드베이스 전반에서 강제하기, “한 사람만으로는 시스템을 바꿀 수 없다”는 SOC2 제약을 만족하기 등이 있습니다. 나는 이것들을 내가 신경 쓰는 순서대로 나열했지만, 이를 다른 순서로 중요시하는 엔지니어는 코드 리뷰 접근 자체가 크게 달라질 것입니다.
추가: 이 글은 lobste.rs와 Hacker News에서 대체로 긍정적인 코멘트를 받았습니다. “카멜 케이스 vs 스네이크 케이스” 예시는 툴링으로 잡아야 한다며 싫어한 사람도 있었는데—그 지적은 타당하지만, “쓰기 연산 전에는 특정 태그로 로그를 남긴다”처럼 툴링으로 쉽게 잡기 어려운 변경에도 동일한 원칙이 적용됩니다. 이 댓글 스레드는 차단 리뷰를 남기는 규범에 대한 흥미로운 논의입니다. 마지막으로, lobste.rs의 최상위 코멘트는 내가 구글 가이드를 “승인에 편향을 두라”로 의역하는 것이 오해를 낳는다고 봅니다. 내게는 구글의 원칙이 똑똑하고 꼼꼼한 엔지니어들에게 더 많이 승인해야 한다고 설득하려는 것으로 매우 명확히 보이지만—이는 분명 내 해석이 맞습니다.
↩ 2. 소프트웨어 엔지니어가 아닌 독자를 위해 덧붙이면, 여기서 “diff”란 기존 코드와 제안된 새 코드의 차이를 뜻하며, 삭제·추가·수정된 줄을 보여줍니다.
↩ 3. 이것은 커뮤니케이션에 대한 일반적 진실의 특수한 사례입니다. 한 가지를 말하면 사람들은 보통 기억하지만, 스무 가지를 말하면 아마 전부 잊어버릴 것입니다.
↩ 4. 결국 이런 교착 상태는 보통 기능 팀이 자신의 디렉터나 VP에게 불평하고, 그가 에지 네트워킹 팀의 디렉터나 VP에게 불평하고, 그들이 “그냥 그 변경 좀 풀어주라”고 지시하는 방식으로 해결됩니다. 하지만 이는 인센티브 불일치를 해결하는 꽤 조악한 방법이며, 매우 고위 관리자의 엄호를 받을 만큼 높은 우선순위의 기능에만 실제로 통합니다.
↩ 5. 구글의 원칙은 더 명시적입니다. 완벽할 때가 아니라, 아주 작은 개선이라도 있으면 변경을 승인하라고 말하죠. 하지만 내가 여기서 읽는 근본적인 메시지는 “기분 좋은 건 알지만, 쓸데없이 시시콜콜한 문지기 노릇은 하지 말고—PR을 승인하라!”입니다.
이 글이 마음에 드셨다면, 내 새 글에 대한 이메일 업데이트를 구독하거나, Hacker News에 공유해 주세요.
2025년 10월 25일│ 태그: good engineers, software design, explainers, ai