본문으로 건너뛰기
Tech Blog

좋은 팀, 리뷰를 나누는 방법

글 복사 완료!

PR 코멘트 한 줄에 방어부터 하게 되는 이유와, 같은 말을 다르게 적는 법이에요.

·9분·

이거 왜 이렇게 했어요? PR에 이 한 줄이 달리면 마음이 살짝 쪼그라들어요. 틀린 지적이 아닌데도 방어부터 하게 되죠. 저도 리뷰어로서 비슷한 코멘트를 무심코 남긴 적이 많고요. 진실된 피드백이 성장의 계기가 되느냐 방어의 벽이 되느냐는, 솔직함의 양이 아니라 그 말이 향하는 대상과 구조에서 갈려요.

코드에 대해 말하고, 사람을 지키기

Google의 코드 리뷰 가이드는 첫 원칙으로 의외로 단순한 걸 들어요. 코멘트는 항상 코드에 대해서만 하고, 개발자 개인에 대해서는 절대 하지 말라는 거예요. 당신은 왜로 시작하는 문장은 사람을 겨냥하고, 이 코드가로 시작하는 문장은 코드를 겨냥해요. 주어 하나 바꿨을 뿐인데 받는 사람의 방어 본능이 확 줄어들죠.

// 사람을 겨냥한 코멘트
당신은 왜 여기서 useEffect를 또 썼나요?

// 코드를 겨냥한 코멘트
이 useEffect가 위쪽 effect와 같은 값을 구독해서, 한 번 렌더할 때 둘이 같이 실행돼요.

이게 통하려면 토대가 하나 필요해요. 바로 심리적 안전감이에요. 구글이 수백 개 팀을 분석한 Project Aristotle에서, 효과적인 팀을 가르는 가장 중요한 요인으로 꼽힌 게 심리적 안전감이었거든요. 누가 팀에 있느냐보다 팀이 어떻게 함께 일하느냐가 더 중요했다는 결론이죠. 코멘트를 코드에 겨냥하는 작은 습관이 쌓이면, 서로 솔직하게 말해도 안전한 분위기가 만들어져요.

건설적이면서 진실되려면 두 축이 필요해요

건설적인 피드백과 진실된 피드백은 자주 충돌하는 것처럼 보여요. 좋게 말하려다 정작 할 말을 못 하기도 하고, 솔직하려다 상처를 주기도 하죠. Radical Candor는 이 둘을 별개의 두 축으로 봐요. 상대를 개인적으로 신경 쓰는 축과, 직접적으로 도전하는 축이에요.

"Caring Personally while Challenging Directly." - Radical Candor

상대를 진심으로 신경 쓰면서, 동시에 할 말은 직접 한다는 거예요. 두 축을 다 잡아야 비로소 진실된 피드백이 돼요.

여기서 놓치기 쉬운 게 있어요. 신경은 쓰는데 직접 말하지 못하는 것도 실패라는 점이에요. Radical Candor는 이걸 파괴적 공감이라고 불러요. 좋은 게 좋은 거라며 필요한 지적을 삼키면, 당장은 평화롭지만 상대는 성장할 기회를 잃어요. 반대로 신경 쓴다는 걸 안 보여주면서 직접적이기만 하면 그냥 공격이 되고요. LGTM만 누르고 넘어가는 리뷰가 친절해 보여도, 사실은 동료를 그 자리에 멈춰 세우는 일일 수 있어요.

추상적인 지적 대신 본 것을 말하기

진실되게 말하기로 마음먹어도, 네이밍이 별로예요 같은 코멘트는 상대를 막막하게 만들어요. 뭐가 왜 별로인지가 없으니까요. 이럴 때 쓰는 틀이 SBI예요. 상황(Situation), 행동(Behavior), 영향(Impact) 순으로, 관찰한 사실에만 집중하고 의견이나 판단을 끼워넣지 않는 방식이에요.

// 추상적인 지적
네이밍이 별로예요.

// SBI를 적용한 코멘트
fetchData라는 이름인데(상황) 실제로는 캐시만 읽고 네트워크 요청은 안 해서(행동),
호출하는 쪽이 매번 진짜 요청이 나가는 줄 오해할 것 같아요(영향).

같은 맥락에서 구글 가이드도 제안의 이유를 함께 적으라고 해요. 왜 그렇게 바꾸면 좋은지를 설명하면, 상대가 의도를 이해하고 더 나은 해법을 스스로 찾거든요. 정답을 바로 던지는 대신 문제를 짚고 방향만 알려줄 때, 리뷰가 받아쓰기가 아니라 함께 푸는 일이 돼요.

코멘트에 무게를 표시하기

리뷰를 받다 보면 어떤 코멘트가 꼭 고쳐야 하는 건지, 그냥 취향인지 헷갈릴 때가 많아요. Conventional Comments는 코멘트 앞에 라벨 하나만 붙여서 이 모호함을 없애요. 라벨만 붙여도 의도가 분명해지고 톤이 확 달라진다는 게 핵심이에요.

라벨로 무게 표시하기

• praise, 잘한 부분을 짚어 칭찬하는 코멘트
• suggestion (non-blocking), 제안이지만 승인을 막지는 않음
• issue (blocking), 고쳐야 승인되는 문제
• nit, 취향에 가까운 사소한 다듬기라 무시해도 됨

구글도 비슷하게 필수가 아닌 다듬기 제안에는 Nit:을 붙여서, 작성자가 선택적으로 넘길 수 있게 해요. 그래야 리뷰어의 모든 코멘트가 명령처럼 읽히지 않거든요. 그 바탕에는 분명한 기준점이 하나 있어요. CL(코드 변경 묶음, Changelist)이 전체 코드 건강도를 확실히 개선하는 상태면, 완벽하지 않아도 승인을 선호하라는 거예요.

"reviewers should favor approving a CL once it is in a state where it definitely improves the overall code health." - Google Engineering Practices

완벽해질 때까지 붙잡지 말고, 코드 건강도를 확실히 올리는 상태가 되면 승인하라는 뜻이에요.

완벽한 코드란 없고 더 나은 코드만 있다는 전제죠. 이 기준이 있으면 리뷰어도 사소한 데 집착하지 않게 되고, 작성자도 무한 수정에 지치지 않아요.

반대 의견을 만났을 때

피드백은 한 방향 통보가 아니에요. 작성자가 반박하는 순간이 오죠. 구글 가이드는 그때 먼저 상대가 맞을 수도 있다를 진지하게 검토하라고 해요. 코드에 가장 가까운 사람은 보통 작성자거든요. 그래도 동의하지 않으면, 정중함을 유지하면서 당신 말을 들었고 다만 생각이 다르다를 분명히 전해요. 고집의 세기보다 어조가 결과를 더 많이 좌우해요.

다만 정중함이 무조건 물러서는 건 아니에요. 품질 개선이 그만한 노력을 정당화한다고 진심으로 믿으면, 나중에 고치자를 쉽게 받아들이면 안 돼요.

"Letting people 'clean things up later' is a common way for codebases to degenerate." - Google Engineering Practices

나중에 정리하자며 넘어가는 게 코드베이스가 서서히 망가지는 가장 흔한 경로라는 거예요.

의견이 계속 엇갈리면 개인 취향으로 싸우지 말고, 팀이 합의한 코드 리뷰 기준을 근거로 풀어요. 내가 이게 좋아서가 아니라 우리 기준이 이래서로 옮겨가면, 충돌이 감정싸움이 아니라 기준 정렬이 돼요.

완벽이 아니라 더 나은 코드

좋은 리뷰는 합격과 불합격을 가르는 심사가 아니라, 팀이 함께 코드 건강도를 한 칸씩 올리는 일이에요. 코드에 대고 말하고, 신경 쓰면서 직접 말하고, 본 것을 구체적으로 적고, 코멘트에 무게를 표시하고, 반박을 기준으로 받아내는 다섯 가지가 그 한 칸을 만들어요.

결국 피드백의 품질은 개인기보다 팀이 함께 세운 약속에서 와요. 팀이 공통 기준을 어떻게 세우는지는 디자인 시스템의 세 축에서 운영 모델로 한 번 다뤘는데, 코드 리뷰 문화도 같은 자리에 있어요. 혼자 잘하는 리뷰어보다, 같은 기준 위에서 솔직할 수 있는 팀이 더 멀리 가거든요.

자주 묻는 질문

답을 펼치기 전에 스스로 답해보세요

네, 잘한 부분을 구체적으로 짚는 것도 중요한 피드백이에요. Conventional Comments의 praise 라벨처럼 무엇이 왜 좋았는지 적으면, 상대가 그 좋은 패턴을 다음에도 의식적으로 반복하게 돼요.
표정이나 목소리가 없으니 같은 문장도 더 날카롭게 닿아요. 사람이 아니라 코드를 주어로 쓰고, 제안에는 이유를 붙이고, 사소한 건 nit 같은 라벨로 무게를 낮추면 차가움이 많이 줄어요.

참고 자료