AI 코드 리뷰 반복, 몇 번이 충분할까
같은 코드에 400회의 LLM 호출을 돌린 실측 연구 결과, 리뷰 한 번은 실제 결함의 34%만 본다. 리뷰는 반복할수록 커버리지가 늘지만(34→61→76%) 리뷰-수정 루프를 반복하면 코드만 +24%~+152% 부풀어 오른다. 실무 처방 '리뷰는 여러 번, 수정은 한 번'과 종료 조건 설계의 핵심을 정리한다.
개요: 이 연구가 묻는 것
코드 작성 → AI 리뷰 → 수정 → 다시 리뷰 → 다시 수정… 리뷰/수정 루프는 에이전트나 CI에 넣기 쉽다. 문제는 언제 멈출지에 근거가 없다는 점이다. EdgeLog(에크로)의 저자는 "리뷰를 더 하면 코드가 더 좋아진다"는 당연해 보이는 가정을 실제로 재보지 않았다는 데서 출발해, 리뷰어와 수정자를 분리한 하네스로 약 400회의 LLM 호출을 돌려 직접 측정했다. 이 글은 그 연구(2026년 8월 22일 발표)의 결론을 실무 관점에서 정리한다.
연구의 뼈대는 역할 구분 하나다.
리뷰어(reviewer) 코드를 읽고 문제를 보고한다. 코드는 건드리지 않는다
수정자(fixer) 그 보고를 받아 실제로 코드를 고친다. 거절할 수도 있다
대상은 실제 C 펌웨어 링버퍼 모듈(359줄, 테스트 18개)과 지수 백오프·full jitter·circuit breaker를 담은 Python 재시도 정책 모듈이다. 결과는 기대와 달랐다. 그리고 연구가 진행되는 동안 저자의 결론은 계속 뒤집혔다.
리뷰만 반복하면 커버리지가 늘었다
코드를 전혀 바꾸지 않고 같은 입력을 10번 독립 리뷰시켰다(매번 새 프로세스로 실행해 이전 답변의 오염을 차단). 같은 코드인데 실행마다 지적 수가 4건에서 9건까지 2.25배로 흔들렸다. 61개 지적을 같은 결함끼리 묶으니 14개 그룹이 나왔고, 실제 코드 전체와 대조해 판정한 결과 진짜 결함 10개, 오탐 4개였다.
리뷰 횟수와 실제 결함 커버리지의 관계는 이렇다.
| 리뷰 횟수 | 실제 결함 커버리지 |
|---|---|
| 1회 | 34% |
| 3회 | 61% |
| 5회 | 76% |
리뷰 한 번은 실제 결함의 약 3분의 1만 본다. 같은 코드, 같은 모델이어도 매번 보는 문제가 달랐고 어떤 실제 결함은 10번 중 한 번만 발견됐다. "AI 리뷰 한 번이면 충분하다"는 데이터로 지지되지 않는다.
그런데 가장 자주 나온 지적은 오히려 오탐이었다
합의가 진실의 증거는 아니었다. 오탐 4건의 평균 발견 빈도는 10번 중 6.8회, 진짜 결함 10건은 3.4회였다. 가장 많이 보고된 상위 5개 지적 중 4개가 오탐이었다. 예를 들어 리뷰어들은 "재초기화 시 큐에 남은 디스크립터가 오염된다", "ring_total == 0에서 언더플로가 난다" 같은 지적을 반복했는데, 실제로는 다른 파일에 있는 초기화 경로·호출 순서·실행 스레드를 보면 모두 반박 가능한 것이었다.
이유는 단순하다. 모든 리뷰어에게 대상 파일 하나만 주어졌기 때문에 모두 같은 정보를 몰랐고, 같은 잘못된 가정에서 출발해 같은 방향으로 틀렸다는 것이다. 여러 AI가 독립적으로 리뷰해도 모두 같은 컨텍스트를 잃고 있다면, 합의가 오히려 반-예측적일 수 있다. "여러 번 지적됐으니 진짜겠지"라고 가중치를 매기면 안 되는 이유다.
리뷰-수정 루프는 리뷰 반복과 다른 문제였다
리뷰만 반복할 때와 달리 리뷰 → 수정 루프를 반복하면 계약 준수율은 그대로인데 코드만 조건에 따라 +24% ~ +152% 커졌다. 발견의 이득은 리뷰 쪽에서 나오는 반면, 수정할 때마다 새로운 변경과 새로운 위험이 따라온다. 둘을 한 사이클로 묶어 계속 돌리면 "이득당 수정 위험"이 가장 커진다.
연구에서 유난히 인상적인 교훈 하나가 2부에 나온다. 첫 auto-fix 실험에서 15개 라운드 중 12개가 RED였고, 네 번의 독립 실행이 정확히 같은 4개 테스트에서 실패했다. 처음에는 "AI가 같은 버그를 반복해서 만든다"고 보였다. 하지만 원인은 달랐다. AI가 추가한 방어 코드 if (ring_total == 0) return;는 한 파일만 보면 합리적이었지만, 실제 프로덕션에서는 ring_push()가 항상 먼저 실행돼 그 상태에 도달할 수 없었다. 깨진 것은 코드가 아니라, 프로덕션에 존재하지 않는 상태를 고정하던 테스트의 가정이었다. 테스트 실패를 무조건 코드 탓으로 볼 수 없다는, 되돌아가야 할 지점을 보여준다.
종료 조건은 왜 모두 부실했나
네 가지 정지 기준을 후보로 올렸는데 셋은 문제가 있었다.
| 기준 | 문제점 |
|---|---|
| churn → 0 | 일부 조건에서만 작동. 계약이 약한 C 모듈에서는 오히려 194 → 262 → 395로 증가 |
| 지적 → 0 | 모델마다 의미가 다름. 침묵한 쪽이 덜 봤을 수 있음 |
| 라운드 상한 | 수렴이 아니라 단순한 절단 |
| 수정 루프 자체를 반복하지 않기 | 남은 현실적 전략 |
특히 "AI가 조용해졌다 = 리뷰 종료"는 위험하다. 한 모델은 bare 프롬프트에서 3라운드부터 "지적 없음"을 냈지만, 같은 코드에 구조화된 프롬프트를 주자 clock failure, half-open wedge, stale cooldown 같은 다른 실패 모드를 계속 찾았다. 침묵은 완주의 증거가 아니다.
테스트 통과도 마찬가지다. 47개 라운드에서 계약 준수율은 전부 같았지만 코드 크기(LOC)와 인지 복잡도(Cognitive Complexity)는 조건별로 크게 갈렸다. 테스트를 계속 통과한다고 코드가 계속 좋아지고 있다고 볼 수 없다.
가장 강한 레버는 "저장소를 읽게 하는 것"이었다
컨텍스트가 오탐의 핵심 원인이었으니, 조건을 하나만 바꿨다. 리뷰어에게 대상 파일 대신 호출자·헤더·초기화 경로·스레딩을 확인할 수 있게 src/를 읽기 전용으로 열어줬다(정답이 담긴 폴더는 차단).
| 조건 | 원시 지적 | 고유 그룹 | 진짜 결함 | 오탐 |
|---|---|---|---|---|
| 파일만 | 61 | 14 | 10 | 4 |
| 저장소 접근 | 30 | 7 | 7 | 0 |
오탐 4개가 서로 다른 회사의 두 모델 모두에서 사라졌다. 이 연구에서 가장 강한 cross-model 재현 결과다. 파일 하나로는 찾기 어려웠던 실제 결함(FIFO overflow 후 링 히스토리 시간 구멍, pre-roll과 debounce 상호작용, 저전력 50Hz 샘플의 1000Hz 라벨링)도 새로 발견했다.
다만 저장소 접근은 공짜가 아니다. 정밀도는 71% → 100%로 오르지만 재현율은 77% → 54%로 떨어졌다. 호출 경로를 확인하면서 "실제로는 거의 도달하지 않는다"고 판단해 지적을 덜 내고, 그 과정에서 오탐뿐 아니라 저빈도 실제 결함도 일부 버린다. 오탐을 줄이는 대신 희미한 결함도 버리는 트레이드오프다.
실무 처방: "리뷰는 여러 번, 수정은 한 번"
연구가 남긴 결론은 단순하다. 리뷰를 여러 번 반복해(가능하면 서로 다른 모델을 섞어) 지적을 먼저 모은 뒤, 사람이 한 번 선별해 수정자에게 한꺼번에 넘긴다.
수정자에게 줄 것은 세 가지다.
- 합쳐진 이슈 목록
- SPEC 또는 최소한 "공개 표면(함수명·시그니처·문서화된 동작)은 고정"이라는 범위 지시
- 읽기 전용 테스트(읽게 하되 수정 금지)
그리고 모든 지적에 대해 accept / decline / defer 중 하나를 명시적으로 고르게 한다. 지적을 받았다고 무조건 수정하게 해서는 안 된다. 범위 고정은 코드 팽창을 막고(LOC 254 → 237), SPEC은 수정자의 판단을 교정한다.
재리뷰 여부는 "몇 번째 라운드인가"가 아니라 수정량으로 정한다. 작은 수정이면 끝내고, 파일 절반을 다시 썼다면 그건 재리뷰가 아니라 새로 만들어진 코드에 대한 첫 리뷰로 보는 편이 맞다. 연구에서는 수정량과 실제 신규 지적 비율의 상관이 r = 0.837이었다.
마지막으로, 테스트만 보면 안 된다. 테스트 통과와 함께 LOC·복잡도·churn을 기록하고, 테스트는 모두 통과하는데 코드가 계속 커지고 복잡해지면 루프가 품질을 개선하고 있다고 보기 어렵다.
읽을 때 주의할 점
저자 스스로 한계를 명확히 적었다. 재현된 결론은 셋뿐이다(리뷰 반복과 수정 루프가 다른 활동, 단일 파일 조건에서 자신 있는 지적이 오히려 의심스러움, 계약 준수율은 아무것도 판별하지 못함). 나머지는 각각 한 번씩 관측된 결과다. 표본은 Python 과제 2개와 C 펌웨어 모듈 1개, 모델 2개에 불과하다.
이 연구를 어느 모델이 더 코딩을 잘하는 순위표로 읽으면 오독이다. 재는 대상은 모델 자체가 아니라 모델을 감싸는 루프·프롬프트·컨텍스트·도구 권한·정지 조건이다. "AI 리뷰를 몇 번 돌릴까"보다 더 좋은 질문은 "무엇을 반복하고, 무엇은 한 번만 해야 하는가"다.
참고 자료
- 원문 글: AI 코드 리뷰는 몇 번 돌려야 할까 (EdgeLog, 2026-08-22)
- 연구·벤치마크 공개 저장소: Ecro/harness-bench
- GeekNews 토론: news.hada.io/topic?id=32842
관련 글
AI 에이전트 평가의 새로운 틀: Agent Behavior 표준이 말하는 것
AI 에이전트의 반복 행동을 문서화해 평가 기준으로 삼는 Agent Behavior 표준이 공개됐어요. 단일 성과 지표로는 파악하기 어려운 장기 실행 에이전트의 행동을, 확인·판단·실행·복구 흐름으로 나눠 평가할 수 있도록 돕는 개방형 포맷이 특징이에요.
GLM-5.3 오픈웨이트, 단일 모델로 코딩·에이전트·보안을 한 번에 바꾼다
Z.ai가 GLM-5.3 오픈웨이트를 공개했다. 같은 기반 모델에 후속 학습만으로 코딩·장기 에이전트·사이버 보안 성능이 크게 올랐고, 직접 배포·미세 조정도 가능하다. 오픈 소스 LLM 사용처를 다시 고민하게 만드는 발표다.
Git을 어떤 규모에서도 확장하는 법 — Cursor의 Continuity 저장 구조
Git 서버 확장이 어려운 이유는 Git 자체 설계에 있다. Cursor는 S3 WAL을 진실의 원천으로 두는 Continuity로 이 문제를 다시 쓴다. 합의에 의존하지 않고도 일관성을 보장하고, 작은 저장소부터 거대 monorepo까지 복제본 수를 자유롭게 조절하는 구조를 소개한다.
발행 전 운영자가 직접 큐레이션·검수·편집합니다.