3개의 Claude Code 서브 에이전트에게 동일한 PR 리뷰를 요청했습니다. 그들은 댓글의 41%에서 의견이 일치하지 않았습니다.
요약
동일한 PR에 대해 세 개의 서로 다른 Claude Code 서브 에이전트를 활용하여 멀티 에이전트 코드 리뷰 실험을 진행한 결과, 댓글의 41%에서 의견 불일치가 발생했습니다. 에이전트의 역할(코드 고고학자, 보안 리뷰어, 아키텍트)을 분리했음에도 불구하고, 에이전트 간의 의견 차이가 오히려 인간 리뷰어의 검토 시간을 늘리는 결과를 초래했습니다.
핵심 포인트
- 멀티 에이전트 리뷰 시 에이전트 간 의견 불일치율이 41%에 달함
- 에이전트의 역할을 전문화(보안, 아키텍처, 탐색)하여 설정 가능
- 에이전트의 수가 늘어날수록 리뷰 결과의 정합성을 맞추는 데 더 많은 시간이 소요될 수 있음 (브룩스의 법칙 적용)
- Anthropic의 내부 통계와 달리 일반 리포지토리 환경에서는 에이전트 간의 일관성 유지가 어려움
멀티 에이전트 (multi-agent) 코드 리뷰가 공짜 업그레이드라고 생각했습니다. 세 명의 서브 에이전트가 동일한 PR (Pull Request)을 살펴보는 것은 엔지니어 한 명의 커피값으로 세 쌍의 눈을 얻는 것처럼 들렸습니다. 그러다 저는 동일한 500라인 규모의 리팩터링 (refactor) PR에 세 개의 Claude Code 서브 에이전트를 실행했고, 그들이 댓글의 41%에 대해 서로 의견이 다르다는 것을 목격했습니다. 머지 (merge) 작업은 제가 15분으로 계획했던 것보다 더 긴 한 시간이 걸렸습니다. 브룩스의 법칙 (Brooks's Law)은 2026년에도 살아있으며, 분명히 에이전트 단위로도 축소 적용됩니다. Anthropic은 지난 3월, 내부 코드 리뷰 결과 중 엔지니어에 의해 부정확하다고 표시되는 비율이 1% 미만이라고 발표했습니다. 그 수치는 실제이며, 또한 자신의 코드베이스에서 정밀하게 조정된 하나의 파이프라인 (pipeline)을 실행하는 사람들의 통계이기도 합니다. 제가 제 리포지토리 (repo)에 직접 세 명의 서브 에이전트를 세우자마자, "동의"라는 말은 제가 생각했던 의미와 달라졌습니다. 이것은 실험입니다. 제가 무엇을 설정했는지, 무엇을 측정했는지, 그리고 병렬 서브 에이전트 리뷰 (parallel sub-agent review)에 대해 현재 실제로 무엇을 믿고 있는지에 대한 이야기입니다.
설정 (The setup)
PR은 제 사이드 프로젝트 중 하나인 WebRTC 시그널링 레이어 (signaling layer)의 500라인 리팩터링이었습니다. 8개의 파일, 대부분 TypeScript, 몇 가지 설정 변경, 하나의 새로운 에러 타입. 과시용 PR이 아니라고 할 만큼 지루하면서도, 단일 리뷰어가 놓칠 수 있을 만큼 복잡했습니다. 세 명의 서브 에이전트는 모두 .claude/agents/ 아래에 정의되었으며, 모두 Sonnet 4.6을 사용하고, 각자 읽기 전용 도구 (read-only tools)로 제한되었습니다:
name : explore-reviewer
description : "호출자(callers), 의존성(dependents), 그리고 데드 코드 경로(dead code paths)를 추적합니다."
model : sonnet
allowed-tools : Read Grep Glob
당신은 코드 고고학자입니다. 변경된 각 파일에 대해 모든 호출자, 이를 참조하는 모든 테스트, 그리고 변경 후 침묵하게 되는 모든 경로를 찾으십시오. 구체적인 file:line 인용을 보고하십시오. 스타일 의견은 배제합니다.
name : security-reviewer
description : 인증(auth), 검증(validation), 그리고 비밀 정보 처리(secret-handling) 회귀를 찾습니다.
model : sonnet
allowed-tools : Read Grep Glob WebSearch
당신은 보안 리뷰어입니다. 인증 흐름(auth flows), 입력 검증(input validation), 비밀 정보 처리(secret handling), 그리고 의존성 리스크(dependency risks)에만 집중하십시오. 각 발견 사항에 대해 CVSS를 추정하십시오. 스타일과 아키텍처는 무시하십시오.
--- name : plan-architect
description : 기존 컨벤션(conventions)에 따라 설계 결정을 평가합니다.
model : sonnet
allowed-tools : Read Grep Glob
당신은 소프트웨어 아키텍트(software architect)입니다. 이 코드베이스의 기존 컨벤션(conventions)과 PR의 설계 선택 사항을 비교하십시오. 드리프트(drift), 누락된 심(seams), 그리고 다음 작업자에게 해를 끼칠 추상화(abstractions)를 표시하십시오.
각 서브 에이전트(sub-agent)는 동일한 프롬프트(prompt)를 받았습니다: "PR #482를 라인별로 리뷰하고, 발견 사항을 file:line 인용과 함께 불렛 포인트로 나열하십시오." 각 에이전트는 자신만의 컨텍스트(context)에서 실행되었습니다. 그들 중 누구도 서로의 출력물을 보지 못했습니다. 마지막에 결과를 하나로 엮은 것은 저뿐이었습니다.
41%의 불일치가 실제로 어떤 모습이었나
세 에이전트가 모두 작업을 마친 후, 총 78개의 가공되지 않은(raw) 댓글이 생성되었습니다. 저는 스프레드시트를 펴고 각 댓글을 "3명에 의해 제기됨", "2명에 의해 제기됨", 또는 "1명에 의해 제기됨"으로 태깅(tagging)했습니다.
| 커버리지(Coverage) | 개수(Count) | 점유율(Share) |
|---|---|---|
| 3개의 에이전트 모두가 표시함 | 14 | 18% |
| 3개 중 2개의 에이전트가 표시함 | 32 | 41% |
| 오직 1개의 에이전트만 표시함 | 32 | 41% |
"1명에 의해 제기됨" 그룹이 제가 불일치(disagreement)라고 부르는 부분입니다. 다른 두 서브 에이전트에게는 동일한 툴(tools)을 사용하여 동일한 디프(diff) 상의 동일한 라인을 표시할 모든 기회가 있었습니다. 하지만 그들은 그냥 지나쳤습니다. 이는 개별적인 발견 사항이 특정 서브 에이전트만의 개인적인 의견일 확률이 41%라는 것을 의미합니다.
Anthropic이 발표한 수치 — 오답으로 표시된 것이 1% 미만 — 는 측정 방식이 다릅니다. 그들은 엔지니어가 수정 없이 명시적으로 닫은(closes) 발견 사항을 집계합니다. 반면 저는 동일한 코드를 보고 있는 세 명의 에이전트 중 두 명이 언급조차 하지 않은 발견 사항을 집계하고 있습니다. 이는 서로 다른 질문이며, 두 번째 질문이 제가 키보드 앞에서 시간을 허비하게 만드는 문제입니다.
네 가지 불일치 패턴
모든 불일치를 분류한 결과, 네 가지 패턴이 거의 모든 사례를 차지했습니다.
심각도 드리프트(Severity drift). plan-architect는 누락된 널 체크(null check)를 "심각(critical)"으로 표시했습니다. security-reviewer는 동일한 라인을 주목하며 "낮음(low) — 호출자(caller)가 이미 상위(upstream)에서 검증함"이라고 언급했습니다. 둘 다 어느 정도는 맞았습니다. 아키텍트는 함수를 고립된 상태에서 읽었습니다. 보안 리뷰어(security reviewer)는 grep-walk를 통해 호출자들을 확인했고 상위 검증을 확인한 상태였습니다. 동일한 라인, 정반대의 판결이었습니다.
범위 드리프트 (Scope drift). PR 리뷰를 요청하자, explore-reviewer는 PR이 건드리지 않은 파일들에서 발견된 세 개의 기존 버그에 대해 즐겁게 이야기했습니다. 반면 plan-architect는 디프 (diff) 범위를 벗어나는 것에 대해서는 의견을 남기기를 거부했습니다. 저는 어떤 동작이 나타날지 미리 알 방법이 없었습니다. 엄밀히 말하면 두 해석 모두 방어 가능합니다. 하지만 실질적으로는, 그중 하나가 제 댓글 수를 폭발시켰습니다. 구체성 드리프트 (Concreteness drift). plan-architect는 "재시도 로직 (retry logic)을 공유 헬퍼 (shared helper)로 추출하는 것을 고려하십시오."라고 작성했습니다. security-reviewer는 "184-201행을 retry(opts, () => fetchToken(opts.url))로 교체하고 30초 상한선을 추가하십시오. 그렇지 않으면 인증 갱신 (auth-refresh) 경로가 워커 (worker)를 중단시킬 수 있습니다."라고 작성했습니다. 같은 아이디어였습니다. 하나는 30초 만에 적용할 수 있었지만, 다른 하나는 회의를 소집해야 할 정도였습니다. 구체성은 제가 예상했던 것보다 훨씬 더 큰 변동 축이었습니다. 도구 예산 드리프트 (Tool-budget drift). explore-reviewer는 grep과 glob을 사용하여, 이름이 변경된 함수가 아무도 업데이트하지 않은 CI 스크립트에서 여전히 참조되고 있다는 점을 알아차렸습니다. 동일한 도구를 가진 plan-architect는 그곳을 전혀 보지 않았습니다. 허용된 도구 목록도 같았고, "의존성을 찾으라"는 프롬프트도 동일했습니다. 한 명은 표면을 걸었고, 한 명은 건물 내부를 걸었습니다. 여기서의 드리프트는 각 시스템 프롬프트 (system prompt)가 에이전트에게 얼마나 공격적으로 돌아다니라고 지시했느냐에 달려 있었습니다. 만약 여러분이 일회성 Explore 호출 이상의 용도로 Claude Code 서브 에이전트를 사용해 보았다면, 이 중 어떤 것도 놀라운 일은 아닙니다. 저에게 놀라웠던 점은, 제가 태그를 달았던 거의 모든 의견 불일치가 이 네 가지 범주로 매우 깔끔하게 나뉘었다는 사실입니다. 아무도 잡지 못한 버그. 제가 머지 (merge)한 지 이틀 후, 동료가 새로운 에러 핸들링 (error-handling) 경로에서 레이스 컨디션 (race condition)을 발견했습니다. PR은 동일한 소켓에서 두 번의 재연결 시도가 발생할 수 있는 한 프레임의 윈도우 (window)를 도입했습니다. 세 명의 서브 에이전트 중 누구도 이를 언급하지 않았습니다. 제가 직접 작성한 풀 리퀘스트 (pull-request) 설명에는 "재연결 로직 이동됨"이라고 적혀 있었고, 그것이 동료가 찾아보게 만든 계기가 되었습니다. "충분한 눈이 있다면, 모든 버그는 얕다." 에릭 레이먼드 (Eric Raymond)가 1999년에 쓴 말입니다. 그는 눈(eyeballs)에 대해서는 옳았습니다.
그는 그 세 명의 눈이 모두 같은 창을 향할 필요는 없다고 명시하지 않았습니다. 제가 사용한 에이전트들은 모두 디프 (diff)를 찌푸려 보고 있었습니다. 그들 중 누구도 한 걸음 물러나 '타이밍에 무엇이 변했는가?'라고 묻지 않았습니다. 머지 (merging)를 위해 허비한 한 시간은, 세 개의 보고서를 실제로 통합하는 과정에서 발생했습니다. 이 부분이 제가 예산(budget)에 잡지 못했던 부분이었습니다. '3개 중 2개' 또는 '3개 중 1개'의 결과가 나올 때마다 저는 결정해야 했습니다. '이것이 실제 문제인가, 아니면 grep 한 번으로 메울 수 있는 컨텍스트 격차 (context gap)인가?' 만약 실제 문제라면, 에이전트 A가 판단한 심각도 (severity)가 맞는가, 아니면 에이전트 B의 심각도가 맞는가? 수정 사항이 제안되었다면, 구체적인 수정안을 적용해도 안전한가, 아니면 추상적인 버전으로 되돌려야 하는가? 마지막 질문 하나만으로도 커피를 세 잔이나 더 마셔야 했습니다. 두 개의 서브 에이전트는 '공통 헬퍼 (shared helper)를 추출하라'고 말했습니다. 한 명은 구체적인 헬퍼를 제공했습니다. 저는 그 구체적인 헬퍼가 실제로 적절한 형태인지 확인하기 위해 디프 (diff)를 세 번째로 직접 읽어야 했습니다. 적절하지 않았습니다. 결국 저는 네 번째 버전을 작성하게 되었습니다. 브룩스의 법칙 (Brooks's Law)은 프로젝트가 지연될 때 인간 사이의 커뮤니케이션 오버헤드 (communication overhead)에 관한 것이었습니다. 저는 이제 이것이 '동일한 산출물에 N개의 독립적인 관점을 투입할 때마다, N+1번째 리뷰어는 통합자 (integrator)가 되며, 통합자의 시간은 대략 N에 비례하여 선형적으로 증가한다'로 일반화된다고 확신합니다. 세 개의 서브 에이전트는 3배의 눈이 있는 것처럼 느껴졌지만, 동시에 3배의 통합 비용 (integration cost)이기도 했습니다.
적절한 서브 에이전트의 수는 몇 개인가
정답이 1개는 아니라고 생각합니다. N=3으로 실험을 진행한 똑같은 주가 지난 후, 저는 더 작은 PR에 대해 N=1로 시도해 보았습니다. 단 한 번의 일반적인 리뷰 패스 (review pass)였습니다. 그것은 탐색형 리뷰어 (explore-reviewer)가 잡아냈을 법한 파일 간 의존성 (cross-file dependency)을 놓쳤습니다. 한 쌍의 눈은 진정으로 두 쌍보다 못합니다. 약 12번의 PR을 거친 후 제가 세운 현재의 휴리스틱 (heuristic)은 다음과 같습니다:
- 작은 PR (<100 라인, 새 파일 없음): 서브 에이전트 1개. 그 이상은 오버헤드입니다.
- 중간 규모 PR (100-500 라인, 하나의 서브시스템 수정): 서로 다른 관점을 가진 두 개의 서브 에이전트. 보통 '탐색 + 보안' 또는 '탐색 + 아키텍트'. PR이 실제로 초래할 수 있는 위험에 맞춰 두 번째 에이전트를 선택하십시오.
- 대규모 또는 교차 기능 PR (500+ 라인, 여러 서브시스템): 3개.
통합 시간을 미리 계획하십시오. 이는 공짜가 아닙니다. 세 개를 초과하는 경우에는 그 가치를 보지 못했습니다. HAMY의 9개 에이전트 설정은 흥미롭지만, 저는 보고서를 병합하기 위한 두 번째 도구가 필요할 것이며, 그 도구는 저보다 저렴해야 할 것입니다. 또 다른 조절 가능한 변수는 구체성 (concreteness)입니다. 저는 이제 각 서브 에이전트에게 "해당 문제를 해결하는 가장 작은 구체적인 변경 사항과 함께 결과를 제시하거나, 모를 경우 수정 불가(no-fix)로 표시하십시오"라고 요청합니다. 시스템 프롬프트 (system prompt)에 추가한 이 한 줄이 저의 구체성 드리프트 (concreteness drift)를 약 절반 정도 줄여주었습니다. 제가 실제로 믿는 바는 멀티 에이전트 (Multi-agent) 코드 리뷰가 공짜가 아니라는 점입니다. 그것은 "서로 다른 방에서 읽고 있는 세 명의 주니어 리뷰어와, 그들의 노트를 병합해야 하는 시니어인 당신"에 더 가깝습니다. 눈(eye count)의 수는 늘어나지만, 통합 비용 (integration cost)도 함께 늘어나며, 이 통합 비용은 당신의 일정 (calendar)에 머무는 부분입니다. 아무도 잡아내지 못한 버그는 저를 가장 겸허하게 만든 부분이었습니다. 세 명의 에이전트, 세 가지 관점, 모두 읽기 전용 (read-only)이며, 모두 동일한 디프 (diff)를 목표로 했습니다. 하지만 그들 중 누구도 타이밍 변경 (timing change)을 알아차리지 못했는데, 그 누구에게도 그것을 요청하지 않았기 때문입니다. 서브 에이전트 (Sub-agents)는 시스템 프롬프트에 넣은 질문에는 매우 뛰어나지만, 당신이 묻는 것을 잊어버린 질문에는 평범합니다. 그것이 모델의 한계가 아니라 실제 한계입니다. 이 글에서 한 가지만 얻어 가신다면: "what-am-i-not-asking(내가 무엇을 묻지 않고 있는가)"이라는 이름의 네 번째 서브 에이전트 프롬프트를 작성하고, 디프를 전달한 뒤, 다른 에이전트들이 놓칠 카테고리들을 지목해 달라고 요청하십시오. 그런 다음 그 답변을 읽으십시오. 그러고 나서 실제 리뷰 프롬프트를 작성하십시오. 저는 이 포스트의 실험에서 이 과정을 수행하지 않았고, 바로 그 때문에 병합 (merge) 시점에 한 시간을 허비했으며 동료가 저의 레이스 컨디션 (race condition)을 발견했습니다. Anthropic의 1% 미만이라는 수치는 실재합니다. 그것은 또한 누군가가 몇 달 동안 튜닝 (tuning)한 파이프라인 (pipeline)에서 측정된 것이지, 회의 사이에 당신이 작성한 세 개의 서브 에이전트에서 측정된 것이 아닙니다. 당신의 에이전트를 튜닝하십시오. 그때까지는 40%를 예상하십시오. 서브 에이전트 설계, 커스텀 에이전트 패턴, 그리고 전체 Claude Code 워크플로우 (workflow)를 다루는 더 심도 있는 버전은 Harness Engineering: From Using AI to Controlling AI 에 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기