본문으로 건너뛰기

© 2026 Molayo

Zenn헤드라인2026. 06. 01. 22:54

AI 코드 리뷰의 효과를 5가지 메트릭으로 측정하는 방법 (GitHub API)

요약

AI 코드 리뷰 도입 효과를 정량적으로 측정하기 위한 5가지 핵심 메트릭과 GitHub API를 활용한 구현 방법을 소개합니다. 단순한 설계 중심의 접근에서 벗어나 데이터 기반의 리뷰 프로세스 개선 방안을 제시합니다.

핵심 포인트

  • AI 코드 리뷰 효과 측정을 위한 5가지 핵심 지표 제시
  • GitHub API와 PyGithub을 활용한 데이터 추출 방법
  • AI 도입 후 리뷰 속도 저하 및 인간 리뷰어의 태만 방지 필요성
  • DORA 프레임워크와 연계된 리뷰 속도 측정의 중요성

결론부터 말씀드리겠습니다. AI 코드 리뷰를 도입했다면, 그 효과는 5가지 숫자로 측정할 수 있습니다. 첫 리뷰까지의 속도, 머지(Merge)까지의 속도, 리뷰의 깊이, 수정 사이클 수, AI 지적 해결률. 이 5가지입니다.

게다가 이 숫자들은 전부 GitHub API를 통해 가져올 수 있습니다. 전용 SaaS를 계약하지 않아도, PyGithub와 30줄의 스크립트만 있으면 자신만의 측정 기반을 가질 수 있습니다. 이 기사에서는 그 코드를 통째로 공개하겠습니다.

저는 엔지니어 겸 투자자로서 여러 개발 현장에서 리뷰 플로우(Flow)를 설계해 왔습니다. 그 과정에서 뼈저리게 느낀 점은, 리뷰 관련 글의 대부분이 '설계'와 '분류'에 너무 치우쳐 있다는 것입니다.

"6단계로 나누자", "3계층 모델로 생각하자". 설계는 중요합니다. 하지만 설계한 플로우가 실제로 효과가 있는지는 별개의 문제입니다. 이 기사는 분류를 하지 않습니다. 오로지 측정에만 집중합니다.

설계도가 아무리 아름다워도 지어진 집이 살기 불편하면 의미가 없습니다. 리뷰도 마찬가지입니다. 구축한 플로우가 빠르고 깊이 있는 리뷰를 만들어내고 있는지 숫자로 확인하는 과정이 빠지기 쉽습니다. 그 부분을 채우는 것이 이 기사의 목적입니다.

왜 「느낌」만으로는 개선할 수 없는가

"최근 리뷰가 늦어지는 것 같다", "AI의 지적이 왠지 많은 것 같다".

"느낌"만으로 살을 뺄 수 있다면 세상에 다이어트 서적은 필요 없을 것입니다. 우선 체중계에 올라가야 합니다. 리뷰도 마찬가지입니다. 우선 숫자를 내는 것부터 시작해야 합니다.

저는 '신장의 야망'이라는 시뮬레이션 게임을 15년째 하고 있습니다. 그 게임에서 강한 사람은 감으로 병사를 움직이는 사람이 아닙니다. 병력 차이와 군량, 지형을 숫자로 보고 포석을 두는 사람입니다. 리뷰 개선도 포석입니다. 숫자가 없으면 포석을 둘 수 없습니다.

여기서 한 가지, 2025년 이후의 현장에서 일어나고 있는 변화를 언급해 두겠습니다. AI에 의한 코드 생성(Code Generation)이 확산되어 코드 생산량이 30% 증가한 반면, 리뷰 처리 능력은 제자리걸음이라는 보고가 있습니다(출처: LinearB).

즉, 쓰는 쪽만 AI로 가속화되고, 보는 쪽은 뒤처지고 있다는 뜻입니다. 이 불균형은 측정하지 않으면 보이지 않습니다. 깨달았을 때는 이미 PR(Pull Request)이 정체되어 있을 것입니다.

저 자신도 이 문제로 실패한 적이 있습니다. AI 리뷰를 도입하고 "이걸로 빨라졌을 거야"라며 만족하고 있었습니다. 반년 뒤에 숫자를 뽑아보니, 첫 리뷰까지 걸리는 시간이 오히려 늘어나 있었습니다.

이유는 단순했습니다. AI가 대량으로 지적을 내놓으니, 인간 리뷰어가 "AI가 봐주고 있으니까 괜찮겠지"라며 태만해졌던 것입니다. 도입한 본인이 가장 방심하고 있었습니다. 숫자를 보고 있었다면 더 빨리 알아차릴 수 있었던 문제입니다.

측정해야 할 5가지 메트릭 (Metrics)

먼저 전체상입니다. 아래 그림이 이 기사에서 다룰 5가지 시그널(Signal)입니다.

GitHub APIで取れる5つのレビューメトリクス: 初回レビューまでの速さ、マージまでの速さ、レビューの深さ、修正サイクル数、AI指摘の解決率

5가지 숫자는 모두 PR 생성일·리뷰일·댓글 수로부터 계산할 수 있음

각각의 정의와 무엇을 나타내는지 표로 정리합니다.

메트릭정의무엇의 위험 신호인가
첫 리뷰까지의 속도PR 생성부터 첫 리뷰까지의 시간길어지면 브랜치가 오래되어 컨플릭트(Conflict)가 증가함
...

조금 보충하겠습니다. "첫 리뷰까지의 속도"와 "머지까지의 속도"는 DORA 프레임워크와 맞닿아 있습니다.

DORA의 변경 리드 타임(Change Lead Time)은 코딩 시간, 픽업(Pick-up) 시간, 리뷰 시간으로 분해할 수 있습니다(출처: LinearB, Swarmia). 이 중 픽업 시간과 리뷰 시간이 바로 위의 두 가지에 대응합니다.

LinearB는 코드 리뷰의 지연이 변경 리드 타임의 최대 병목(Bottleneck)이라고 지적합니다. 리뷰를 빠르게 하는 것은 배포를 빠르게 하는 것과 직결됩니다.

"리뷰의 깊이" 또한 막연한 감각적 용어가 아닙니다. LinearB는 이를 Review Depth로 정의하며, 머지된 PR당 리뷰 댓글 수로 나타냅니다. 계산식은 간단합니다. 머지된 PR의 총 댓글 수를 머지된 PR 수로 나누기만 하면 됩니다.

이 5가지를 선택한 데에는 이유가 있습니다. 리뷰에는 "속도"와 "깊이"라는 두 가지 축이 있기 때문입니다. 속도만 쫓으면 아무도 읽지 않고 지나치는 리뷰가 늘어납니다. 깊이만 쫓으면 꼬투리 잡기로 인해 머지가 막힙니다.

양쪽을 균형 있게 보기 위해, 속도 계열을 2개(첫 리뷰·머지), 깊이 계열을 2개(댓글 수·수정 사이클), 그리고 AI가 효과적인지를 보는 것을 1개(해결률)로 배분했습니다. 투자에서 말하는 위험 자산과 안전 자산의 배분과 마찬가지로, 한쪽으로 치우치지 않는 것이 요령입니다.

GitHub API로 메트릭 수집하기

이제부터가 본론입니다. 위의 5가지를 GitHub API에서 가져옵니다.

먼저 인증과 데이터 취득의 토대를 만듭니다. PyGithub를 사용하여 지난 30일간의 머지된 (merged) PR을 수집합니다.

# review_metrics.py
# 지난 30일간의 머지된 PR로부터 리뷰 메트릭을 집계한다
import os
...

get_reviews()에서 COMMENTED를 제외하는 이유는, 단순한 잡담 댓글을 "리뷰"로 카운트하지 않기 위해서입니다. 승인(approval)이나 변경 요청(changes requested)이 붙어야 비로소 리뷰가 성립된 것으로 간주합니다.

여기서 한 가지 주의할 점, 즉 측정의 함정이 있습니다. GitHub의 GraphQL API에도 REST API에도 "첫 번째 리뷰까지 걸린 시간"을 반환하는 전용 엔드포인트는 존재하지 않습니다 (출처: GitHub Docs).

PR의 생성 일시와 첫 번째 리뷰의 일시를 가져와서 직접 뺄셈을 하는 수밖에 없습니다. 위의 코드가 하고 있는 것이 바로 그것입니다. SaaS가 백엔드에서 수행하는 것도 결국 이 뺄셈입니다.

집계하여 평균 산출하기

PR별 로우 데이터(raw data)를 얻었다면 평균을 구합니다.

# --- 집계 ---
# 첫 번째 리뷰가 달린 PR만으로 평균을 구한다
ttfr_values = [m["ttfr_hours"] for m in metrics if m["ttfr_hours"] is not None]
...

이것으로 상위 3가지 메트릭이 나왔습니다. 출력은 다음과 같은 형태가 됩니다.

집계 대상 PR 수: 42
첫 번째 리뷰까지의 평균: 28.3시간
머지까지의 평균: 51.7시간
...

숫자가 나오는 순간, 논의가 달라집니다. "왠지 느리다"가 "28시간이 걸리고 있다"로 바뀝니다. 이것이 측정의 힘입니다.

참고로, API를 너무 과도하게 호출하지 않도록 주의하십시오. 인증된 요청은 1시간에 5,000회까지입니다 (출처: GitHub Docs). 규모가 큰 리포지토리에서 모든 PR을 훑으면, 댓글을 가져올 때마다 요청이 발생하여 제한에 걸릴 수 있습니다. 30일로 기간을 한정하거나, 페이지네이션 (pagination)을 의식하는 등의 배려가 필요합니다.

나온 숫자를 어떻게 해석할 것인가

숫자가 나왔다면, 다음은 "그래서 이게 좋은 건가 나쁜 건가"라는 이야기로 넘어갑니다. 절대적인 정답은 없지만, 제가 기준으로 삼는 수준을 공유합니다.

메트릭건전한 기준황신호 (주의)
첫 번째 리뷰까지의 속도24시간 이내48시간 초과
...

주의해야 할 점은, 이 숫자를 개인의 평가에 사용하지 않는 것입니다. "첫 번째 리뷰가 느린 사람 랭킹"을 만드는 순간, 팀은 숫자를 꾸며내기 시작합니다.

내용을 읽지 않고 "LGTM"만 누르면, 첫 번째 리뷰 시간은 단축됩니다. 하지만 그것은 리뷰의 방기입니다. 숫자는 사람을 심판하기 위해서가 아니라, 시스템의 부조화를 찾아내기 위해 사용해야 합니다. 이 점을 놓치면 측정은 역효과를 낳습니다.

또 하나는, 평균값만 보지 않는 것입니다. 평균이 28시간이라도, 내역이 "절반은 2시간, 절반은 54시간"이라면, 그것은 일부 PR만 극단적으로 느리다는 뜻입니다. 전체가 일률적으로 느린 것이 아닙니다. 중앙값 (median)과 분포 (distribution)를 함께 보면, 대응해야 할 대상을 명확히 볼 수 있습니다.

나머지 2개: 수정 사이클 수와 AI 해결률

네 번째인 "수정 사이클 수"는 몇 번을 왕복했는가입니다. COMMITS 이벤트와 REVIEW 이벤트가 교대로 몇 번 나타났는지를 통해 근사치를 구할 수 있습니다.

간단하게는, 변경 요청(CHANGES_REQUESTED) 횟수를 사이클 수의 대리 지표 (proxy metric)로 삼을 수 있습니다.

# 수정 사이클 수의 근사: 변경 요청 횟수를 센다
changes_requested = sum(
1 for r in reviews if r.state == "CHANGES_REQUESTED"
...

변경 요청이 3번 달린 PR은 3번 왕복했다고 생각하는 방식입니다. 거칠지만, 경향을 파악하기에는 충분합니다. 사이클이 많은 PR은 리뷰어가 첫 번째 리뷰에서 모든 지적 사항을 내놓지 못했다는 신호입니다.

여기서 AI 리뷰가 효과를 발휘합니다. AI에게 "첫 번째 리뷰에서 포괄적으로 지적하는" 역할을 맡기면, 인간의 왕복 횟수가 줄어듭니다. AI가 사소한 오류를 한꺼번에 찾아내고, 인간은 설계의 타당성만 검토합니다. 역할을 분담하면 수정 사이클 수가 눈에 띄게 줄어듭니다. 이 숫자야말로 AI 리뷰의 효과가 가장 깔끔하게 드러나는 부분입니다.

다섯 번째인 "AI 지적 해결률"은 AI 리뷰 봇의 댓글을 대상으로 합니다. 봇의 댓글 중 resolved 상태가 된 스레드의 비율을 산출합니다.

AI 해결률 (GraphQL의 reviewThreads 사용)

bot의 로그인 이름으로 필터링하여 resolved 비율을 계산한다

(REST만으로는 스레드의 resolved 상태를 가져오기 어렵기 때문에 GraphQL 권장)

...

해결률이 50%를 밑돈다면, 팀은 AI의 지적을 그냥 흘려듣고 있는 것입니다. AI를 도입한 의미가 퇴색되고 있으므로, 지적의 질을 재검토하거나 무시되는 이유를 찾아야 할 차례입니다.

무시되는 이유는 대개 두 가지입니다. 지적이 빗나갔거나, 지적이 너무 많아서 지쳤거나. 전자라면 AI에 대한 지시서(Prompt)를 수정합니다. 후자라면 지적의 우선순위를 설정합니다. 어느 쪽이든, 해결률이라는 숫자가 없다면 "왠지 AI의 지적이 방해되네"라는 분위기만 남게 됩니다. 분위기는 바꿀 수 없지만, 숫자는 바꿀 수 있습니다.

메트릭을 AGENTS.md 개선에 활용하기

숫자를 내는 것으로 끝낸다면, 그것은 체중계에 올라가기만 한 것과 같습니다. 살은 빠지지 않습니다. 다음 단계는 숫자를 사용하여 리뷰 설정 자체를 바로잡는 것입니다.

저는 매월 리포트를 발행하고, 거기서부터 구체적인 액션을 결정하도록 하고 있습니다. 예를 들어 다음과 같은 리포트입니다.

지난달 리뷰 퍼포먼스:
첫 리뷰까지의 평균: 28시간 (목표 24시간 대비 초과)
PR당 코멘트 수: 12건 (목표 8건 대비 과다)
...

포인트는 숫자로부터 원인에 대한 가설을 세우고, 그 가설을 규칙으로 구현하는 것입니다. AI 리뷰어에 대한 지시서(AGENTS.md)에 "첫 리뷰에서 모든 지적을 출력한다"라고 적습니다. 다음 달에 수정 사이클 수가 줄었는지 다시 측정합니다.

가설이 틀릴 때도 있습니다. PR 사이즈를 줄였는데도 코멘트 수가 줄지 않는 경우도 있었습니다. 조사해 보니, 코멘트 내용이 명명 규칙(Naming)에 대한 선호도뿐이었고, 설계에 대한 논의는 거의 없었습니다. 그래서 AGENTS.md에 "명명은 linter에 맡기고, 리뷰는 설계에 집중한다"라고 덧붙였습니다. 숫자를 보고 가설을 세우고, 틀리면 다시 세웁니다. 이 왕복 과정 자체가 개선입니다.

이는 투자 리밸런싱(Rebalancing)과 같은 사고방식입니다. 포트폴리오를 구성해 놓고 방치하지 않습니다. 분기마다 배분을 확인하고, 어긋나면 수정합니다. 리뷰도 구성해 놓고 방치하는 것이 아니라, 매월 숫자를 보고 지시서를 수정합니다.

숫자를 볼 때는 평균뿐만 아니라 주 단위의 추이를 보는 것이 효과적입니다. "코멘트가 급증한 주", "머지(Merge)가 정체된 주"를 시각적으로 파악할 수 있으면 원인을 찾기가 쉬워집니다.

저는 이 월간 루프를 '신장의 야망'의 내정(內政) 단계에 비유하곤 합니다. 매달 수확량을 보고 다음 달에 어디로 군량을 보낼지 결정합니다. 단번에 공격하더라도 병참(Logistics)이 늘어지면 패배합니다. 리뷰도 매달 숫자를 보며 조금씩 규칙을 정비합니다. 지루한 작업이지만, 반년 뒤에는 효과를 발휘합니다.

측정 자동화하기

매달 수동으로 스크립트를 실행하는 것은 지속 가능하지 않습니다. 지속되지 않는 메커니즘은 메커니즘이 아니므로, GitHub Actions로 자동화합니다.

# .github/workflows/weekly-metrics.yml
name: Weekly Review Metrics
on:
...

매주 월요일 아침, 자동으로 숫자가 나옵니다. 나머지는 그 숫자를 보고 매월 AGENTS.md를 수정하는 것뿐입니다. 이것이 데이터 드리븐(Data-driven)한 리뷰 개선 루프입니다.

전용 도구는 언제 필요한가

지금까지 자체 스크립트로 5가지 메트릭을 확보했습니다. 그렇다면 LinearB나 Code Climate 같은 전용 도구는 언제 필요할까요?

저의 정리 방식은 다음과 같습니다.

관점자체 스크립트전용 도구
초기 비용거의 0월간 구독료
...

한 가지만 보충하겠습니다. LinearB에는 Rework Rate라는 지표가 있습니다. 머지한 코드 중 7일에서 21일 사이에 다시 수정된 비율입니다 (출처: LinearB).

이는 "고쳤다고 생각했는데 고쳐지지 않은" 코드의 비율입니다. 이를 자체적으로 구현하려면 커밋 추적이 상당히 무겁습니다. 이 정도 수준까지 깊게 파고들고 싶다면 전용 도구가 등장할 차례라고 생각합니다.

역으로 말하면, 5가지 메트릭의 가시화까지는 자체 구현으로 충분합니다. 우선 체중계에 올라가세요. 계속 올라가다 부족함을 느끼면 고기능 체성분 분석기를 사면 됩니다. 처음부터 비싼 장비를 갖출 필요는 없습니다.

자체적으로 작성함으로써 얻는 부수적인 이점도 있습니다. 스크립트를 쓰다 보면 우리 팀의 리뷰가 어떤 구조로 돌아가고 있는지 싫어도 이해하게 됩니다. "첫 리뷰는 승인(Approve)과 코멘트 중 무엇으로 셀 것인가"라고 고민하는 과정 자체가 리뷰의 해상도를 높여줍니다. SaaS의 대시보드를 바라보기만 해서는 이러한 이해를 얻을 수 없습니다.

요약

요점을 정리하겠습니다.

  • AI 코드 리뷰의 효과는 5가지 수치로 측정할 수 있습니다. 첫 번째 리뷰까지의 속도, 머지 (Merge)까지의 속도, 리뷰의 깊이, 수정 사이클 횟수, AI 지적 해결률입니다.
  • 이 5가지는 모두 GitHub API를 통해 가져올 수 있습니다. 전용 엔드포인트는 없으므로, PR (Pull Request)의 일시를 가져와 직접 계산해야 합니다.
  • 첫 번째 리뷰와 머지까지의 속도는 DORA의 변경 리드 타임 (Change Lead Time)과 맞닿아 있습니다. 리뷰를 빠르게 하면 배포도 빨라집니다.
  • 단순히 수치를 내는 것에 그치지 말고, 원인에 대한 가설을 세워 AGENTS.md에 반영하고 다음 달에 다시 측정하십시오.
  • GitHub Actions로 자동화하면 매주 자동으로 수치가 산출됩니다.
  • 재작업 (Rework)률까지 파고들려면 전용 도구가 필요하고, 시각화 수준이라면 자체 제작으로도 충분합니다.

"느낌

AI 자동 생성 콘텐츠

본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0