AI 코드 리뷰는 이제 라우팅(Routing) 문제다
요약
단순한 프롬프트 기반의 AI 코드 리뷰는 노이즈가 많아 실효성이 낮습니다. 진정한 AI 코드 리뷰 시스템은 리뷰 관심사를 분할하고, 전문화된 에이전트에게 명확한 경계와 책임을 부여하는 '라우팅' 구조를 갖춰야 합니다.
핵심 포인트
- 단순 프롬프트는 모호한 댓글 생성기에 불과함
- 리뷰 관심사를 범위가 지정된 리뷰어로 분할 필요
- 전문 에이전트에게 명시적 책임과 비목표 부여
- 발견 사항을 구조화된 출력으로 정규화
- 심각도 분류를 통한 효율적인 라우팅 구현
AI 코드 리뷰의 가장 취약한 버전은 데모하기에도 가장 쉽습니다.
Diff(차이점)를 가져옵니다. 모델에 붙여넣습니다. 리뷰를 요청합니다. 그러면 그럴듯하게 들리는 댓글의 벽이 돌아오지만, 그중 절반은 실행에 옮기기에는 너무 모호하고, 몇 개는 모두의 시간을 낭비할 정도로 틀려 있습니다.
그것은 리뷰 시스템이 아닙니다. 그것은 댓글 생성기(Comment generator)입니다.
유용한 버전은 훨씬 덜 마법처럼 보입니다. 그것은 라우팅(Routing)처럼 보입니다. 변경 사항의 어느 부분이 주의를 기울일 가치가 있는지, 어떤 리뷰어가 이를 검사해야 하는지, 심각도(Severity)가 무엇을 의미하는지, 언제 사람이 결과를 승인해야 하는지, 그리고 언제 봇이 침묵해야 하는지를 결정합니다.
마지막 부분이 사람들이 인정하는 것보다 더 중요합니다. 개발자들이 리뷰 봇을 무시하는 이유는 자동화를 싫어해서가 아닙니다. 리뷰 봇이 그들에게 노이즈(Noise)를 무시하도록 훈련시키기 때문에 무시하는 것입니다.
하나의 프롬프트(Prompt)가 리뷰 프로세스가 될 수는 없다
단순한 프롬프트는 운영 계약(Operating contract)이 없기 때문에 실패합니다.
"이 PR을 리뷰해줘"라는 말은 어떤 종류의 리뷰를 의미하는지 묻기 전까지는 명확하게 들립니다. 보안(Security)? 데이터 마이그레이션 위험(Data migration risk)? 프론트엔드 접근성(Frontend accessibility)? 의존성 정책(Dependency policy)? 성능 저하 요인(Performance footguns)? API 호환성(API compatibility)? 테스트 커버리지(Test coverage)? 오용 사례(Abuse cases)? 데드 코드(Dead code)? 명명 규칙(Naming)?
시니어 엔지니어는 모든 Diff를 똑같은 방식으로 리뷰하지 않습니다. 작은 CSS 정리와 인증(Auth) 변경은 동일한 리뷰 경로를 가질 가치가 없습니다. 생성된 테스트 업데이트와 결제 마이그레이션(Billing migration)은 모델의 주의를 동일한 양으로 가져가서는 안 됩니다.
그런데 왜 우리는 하나의 범용 모델(General-purpose model)에게 모든 리뷰어처럼 동시에 행동하라고 계속 요구하는 걸까요?
더 나은 패턴은 일단 보고 나면 지루하고 당연합니다:
- 리뷰 관심사(Concerns)를 범위가 지정된 리뷰어(Scoped reviewers)로 분할합니다.
- 각 리뷰어에게 명시적인 책임과 비목표(Non-goals)를 부여합니다.
- 발견 사항을 구조화된 출력(Structured output)으로 정규화합니다.
- 사람을 번거롭게 하기 전에 심각도(Severity)를 분류합니다.
- 위험한 변경 사항을 저렴한 변경 사항과 다르게 라우팅합니다.
이것이 "모델이 생각을 했다"와 "시스템이 리뷰 결정을 내렸다"의 차이입니다.
전문 리뷰어에게는 분위기(Vibes)가 아닌 경계(Boundaries)가 필요하다
전문 에이전트(Specialist agents)는 전문화가 실제일 때만 유용합니다.
접근성 리뷰어(Accessibility reviewer)는 무엇을 지적해도 되는지, 그리고 무엇을 그대로 두어야 하는지를 알아야 합니다. 보안 리뷰어(Security reviewer)는 컴포넌트 이름에 대해 사소한 논쟁(bike-shedding)을 벌이며 시간을 낭비해서는 안 됩니다. 마이그레이션 리뷰어(Migration reviewer)는 롤백 경로(rollback paths), 데이터 형태(data shape), 그리고 폭발 반경(blast radius)에 관심을 가져야 합니다. 의존성 리뷰어(Dependency reviewer)는 락파일 변동(lockfile churn), 라이선스 정책(license policy), 그리고 전이적 위험(transitive risk)을 이해해야 합니다.
핵심은 귀여운 AI 동료 패널을 만드는 것이 아닙니다. 핵심은 모호함(ambiguity)을 줄이는 것입니다.
모든 리뷰어는 코디네이터(coordinator)가 그 결과물을 판단할 수 있을 만큼 충분히 엄격한 직무 기술서(job description)를 가져야 합니다. 만약 두 에이전트가 서로 다른 단어로 동일한 코멘트를 생성할 수 있다면, 그 시스템은 아마도 충분히 전문화(specialized)되지 않은 것입니다. 만약 리뷰어가 사과를 덧붙이지 않고는 "문제를 찾지 못했습니다"라고 말할 수 없다면, 그 시스템은 PR(Pull Request)을 불필요한 내용(filler)으로 가득 채워 침몰시킬 것입니다.
이 지점에서 AI 리뷰는 다시 일반적인 엔지니어링처럼 느껴지기 시작합니다. 당신은 인터페이스(interfaces)를 정의하고 있는 것입니다. 입력(Inputs), 출력(outputs), 소유권(ownership), 실패 동작(failure behavior)을 정의하는 것이죠. 에이전트는 단지 하나의 인터페이스 뒤에 있는 작업자일 뿐입니다.
코디네이터는 신뢰가 생존하거나 사멸하는 곳이다
5명의 리뷰어를 병렬로 실행하는 것은 강력해 보이지만, 5명 모두가 평범한 결과(mediocre findings)를 반환하는 순간 상황이 달라집니다.
이제 문제는 더 악화되었습니다. 개발자는 시끄러운 봇 하나를 상대하는 것이 아니라, 시끄러운 봇 위원회(bot committee)를 상대하게 된 것입니다.
코디네이터 계층(coordinator layer)은 시스템을 생존 가능하게 만드는 요소입니다. 코디네이터는 결과물을 중복 제거(dedupe)하고, 약한 주장(weak claims)의 등급을 낮추며, 중복되는 우려 사항을 병합하고, 무엇이 PR을 차단(block)할 가치가 있는지 결정해야 합니다. 또한 모든 추측을 확신에 찬 리뷰 언어로 세탁(laundering)하는 대신, 불확실성(uncertainty)을 보존해야 합니다.
이 부분은 팀들이 과소평가하는 지점입니다. AI 리뷰의 가치는 생성된 코멘트의 개수가 아닙니다. 개발자가 봇에 대한 정밀 조사(forensic audit)를 수행하지 않고도 즉시 실행에 옮길 수 있는 코멘트의 개수입니다.
훌륭한 리뷰 시스템에는 구조화된 결과(structured findings)가 필요합니다. 파일 경로, 가능한 경우 라인 범위, 카테고리, 심각도(Severity), 신뢰도(Confidence), 제안된 수정 사항(Suggested fix), 읽기에 충분히 짧은 근거(Reasoning), 그리고 "반드시 수정해야 함(must fix)"과 "고려할 가치가 있음(worth considering)" 사이의 명확한 구분 등이 포함되어야 합니다.
그러한 구조가 없다면, 리뷰는 하나의 연극(theater)이 되어버립니다. 봇은 말을 하고, 사람은 눈을 가늘게 뜨고 지켜봅니다. 그 발견이 정책(policy)에 따른 것인지, 개인적 선호(preference)인지, 아니면 패닉(panic)에 의한 것인지 아무도 알 수 없게 됩니다.
일괄적인 자동화보다 위험 계층(Risk tiers)이 효과적이다
모든 diff(차이점)가 동일한 메커니즘을 필요로 하는 것은 아닙니다.
실질적인 방법은 에이전트(agent)가 개입하기 전에 위험 계층(risk tiers)을 정의하는 것입니다.
저위험(Low-risk) 변경 사항은 저렴한 린트(lint) 스타일의 체크와 빠른 스캔을 거칠 수 있습니다. 중위험(Medium-risk) 변경 사항은 특정 리뷰어를 호출할 수 있습니다. 고위험(High-risk) 변경 사항은 더 엄격한 게이트(gates), 인간의 승인, 감사 로그(audit logs), 그리고 봇은 제안만 할 수 있고 승인은 할 수 없다는 규칙 등을 도입해야 합니다.
이는 에이전트가 프로덕션 인접 도구(production-adjacent tools)를 다루기 시작할 때 특히 중요합니다. 실패 모드(failure mode)는 더 이상 단순히 "잘못된 코드가 반영되었다"에 그치지 않습니다. "에이전트가 잘못된 내부 API를 호출했다", "에이전트가 필요하지 않은 쓰기 권한(write access)을 가졌다", 또는 "에이전트가 프롬프트(prompt)가 암시한 것보다 더 큰 폭발 반경(blast radius)을 가진 경로를 자신 있게 건드렸다"와 같은 상황이 발생할 수 있습니다.
인간 참여(Human-in-the-loop)는 퇴보가 아닙니다. 그것은 제어 평면(control plane)입니다.
올바른 질문은 "AI가 이것을 스스로 승인할 수 있는가?"가 아닙니다. 올바른 질문은 "이것은 어떤 유형의 변경 사항이며, 해당 위험에 대해 어떤 종류의 승인이 타당한가?"입니다.
이러한 프레임워크(framing)는 모든 변경 사항이 작다고 가장하지 않으면서도, 작은 변경 사항은 빠르게 처리할 수 있도록 유지해 줍니다.
도구 필터링(Tool filtering)은 코드 리뷰의 일부다
여기에는 또 다른, 화려하지 않은 요소가 있습니다. 바로 에이전트가 무엇을 보고 호출할 수 있는지에 대한 문제입니다.
도구의 무분별한 확산(Tool sprawl)은 에이전트 시스템을 조용히 망가뜨립니다. 리뷰어에게 모든 MCP 서버, 모든 리포지토리(repo) 도구, 모든 내부 명령, 그리고 모든 문서 인터페이스를 제공한다고 해서 에이전트가 더 똑똑해지는 것은 아닙니다. 오히려 결정 공간(decision space)을 더 혼란스럽게 만들 뿐입니다. 또한 권한(permission) 체계를 설명하기도 더 어렵게 만듭니다.
리뷰 에이전트는 가장 작고 유용한 도구 표면(tool surface)만을 제공받아야 합니다.
만약 작업이 프론트엔드 접근성(accessibility) 리뷰라면, 아마도 diff, 관련 컴포넌트 파일, 렌더링된 출력물, 그리고 접근성 체크리스트가 필요할 것입니다. 배포 자격 증명(deploy credentials)은 아마 필요하지 않을 것입니다. 만약 작업이 의존성(dependency) 리뷰라면, 패키지 메타데이터와 정책 컨텍스트(policy context)가 필요합니다. 리포지토리에 대한 광범위한 쓰기 권한은 필요하지 않습니다.
이는 비용 문제 해결에도 도움이 됩니다. 컨텍스트 (Context)는 공짜가 아닙니다. 병렬 에이전트 (Parallel agents)를 사용하면 이 사실이 뼈아프게 드러납니다. 디프 (diffs)를 필터링하고, 공통 컨텍스트를 공유하며, 각 리뷰어에게 유용한 부분만을 라우팅 (routing)하는 시스템은 모든 정보를 모든 호출에 쏟아붓는 시스템보다 비용이 저렴하고 디버깅 (debug)하기도 쉽습니다.
필터링은 마지막 단계에서 수행하는 최적화 단계가 아닙니다. 그것은 아키텍처 (architecture)의 일부입니다.
소규모 팀이 가져가야 할 전략
대부분의 팀은 Cloudflare 규모의 리뷰 플랫폼을 필요로 하지 않습니다. 그 형태 전체를 그대로 복제하는 것은 어리석은 일일 것입니다.
하지만 소규모 팀은 중요한 전략들을 가져올 수 있습니다.
하나의 범용적인 봇 (bot) 대신 두세 개의 리뷰 레인 (review lanes)으로 시작하십시오. 예를 들면 다음과 같습니다:
- 보안 및 비밀 정보 (security and secrets)
- 위험한 마이그레이션 (migrations) 또는 데이터 변경
- 프론트엔드 동작 및 접근성 (accessibility)
각 레인이 어떤 내용에 대해 코멘트를 남길 수 있는지 작성하십시오. 무엇이 PR (Pull Request)을 차단해야 하는지 작성하십시오. 무엇이 정보 제공용 (informational)이어야 하는지 작성하십시오. 그런 다음 사람이 빠르게 훑어볼 수 있도록 출력을 충분히 구조화하십시오.
간단한 리스크 라우터 (risk router)를 추가하십시오. 처음에는 파일 경로 (file paths)만으로도 놀라울 정도로 효과를 볼 수 있습니다. 인증 (auth), 결제 (billing), 마이그레이션 (migrations), 인프라 (infrastructure), 또는 권한에 민감한 코드 하위의 변경 사항은 더 엄격한 리뷰를 트리거 (trigger)할 수 있습니다. 문서 (docs) 및 테스트 전용 변경 사항은 더 저렴한 경로를 택할 수 있습니다.
감사 추적 (audit trail)을 유지하십시오. 어떤 리뷰어들이 실행되었습니까? 어떤 도구들을 사용했습니까? 어떤 결과들이 기각되었습니까? 어떤 것들이 차단했습니까? 시스템이 자신의 동작을 설명할 수 없다면, 리스크가 커졌을 때 사람들은 시스템을 신뢰하지 않을 것입니다.
그리고 반드시 탈출구 (escape hatch)를 마련하십시오. 고장 난 AI 리뷰 게이트 (gate)는 가시적이어야 하고, 로그가 남아야 하며, 적절한 권한을 가진 사람이 우회 (bypass)할 수 있어야 합니다. 그렇지 않다면 당신은 양질의 인프라를 구축한 것이 아닙니다. 당신은 CI (Continuous Integration)가 팀을 인질로 잡는 새로운 방법을 만든 것뿐입니다.
동적 워크플로우가 이를 시급하게 만든다
병렬 서브에이전트 (Parallel subagents)는 점점 일반적인 제품 동작이 되고 있습니다. 이것이 도구들이 나아가는 방향입니다. 하나의 에이전트가 계획을 세우고, 여러 에이전트가 조사하며, 또 다른 에이전트가 검증하고, 사용자는 최종 결과를 확인하게 됩니다.
이는 리뷰에 있어 진정으로 유용할 수 있습니다. 버그 탐색 (Bug hunts), 보안 점검 (Security checks), 마이그레이션 감사 (Migration audits), 그리고 회귀 검증 (Regression verification) 모두 제한된 병렬 작업 (Bounded parallel work)의 이점을 얻을 수 있습니다.
하지만 병렬성 (Parallelism)이 판단 (Judgment)의 필요성을 없애지는 않습니다. 오히려 그 필요성을 배가시킵니다.
더 많은 에이전트 (Agents)는 조율해야 할 더 많은 출력값, 정당화해야 할 더 많은 토큰 비용 (Token spend), 정의해야 할 더 많은 권한 경계 (Permission boundaries), 그리고 관찰해야 할 더 많은 실패 모드 (Failure modes)를 의미합니다. 만약 오케스트레이션 계층 (Orchestration layer)이 취약하다면, 병렬 리뷰는 그저 틀린 답을 더 빠르고 더 많은 곳에서 만들어낼 뿐입니다.
승리하는 설정은 "가능한 한 많은 에이전트를 실행하는 것"이 아닙니다.
승리하는 설정은 "적절한 에이전트는 실행되고, 부적절한 에이전트는 유휴 상태로 유지되며, 인간은 실제 필터를 통과한 결과물만을 보게끔 작업을 라우팅 (Route)하는 것"입니다.
마지막 생각
AI 코드 리뷰는 더 나은 코멘트 박스 (Comment box)가 되어가는 것이 아닙니다. 그것은 인프라스트럭처 (Infrastructure)가 되어가고 있습니다.
여기서 가치를 얻는 팀들은 리뷰를 좁은 범위의 작업자 (Workers), 심각도 규칙 (Severity rules), 권한 경계 (Permission boundaries), 텔레메트리 (Telemetry), 그리고 영향 범위 (Blast radius)가 실질적인 곳에서의 인간 승인 (Human approval)을 갖춘 라우팅된 시스템 (Routed system)처럼 다룰 것입니다.
그렇지 못한 팀들은 계속해서 모델에 디프 (Diffs)를 붙여넣으며, 왜 개발자들이 출력을 읽지 않게 되었는지 의아해할 것입니다.
AI 리뷰의 미래는 더 많은 코멘트가 아닙니다.
어떤 코멘트가 남길 가치가 있는지를 아는 것입니다.
출처 노트
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기