본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 17. 19:34

리뷰는 증상이고, 명세(Specification)가 해결책이다

요약

AI로 인한 코드 생성량 급증이 리뷰 병목 현상과 결함률 상승을 초래하고 있습니다. 단순히 리뷰 프로세스를 개선하는 것을 넘어, 명세(Specification)를 통해 생성 단계부터 검증 가능한 코드를 만드는 근본적인 해결책이 필요합니다.

핵심 포인트

  • AI 코드 생성으로 인해 코드 변동량은 급증했으나 가치 전달은 미미함
  • 리뷰 소요 시간 및 결함률이 급격히 상승하며 검증 단계의 병목 발생
  • 인간 규모의 리뷰 방식으로는 기계 규모의 코드 생성 속도를 감당할 수 없음
  • 리뷰 개선보다 명세(Specification)를 통한 사전 검증이 근본적 해결책임

Addy Osmani는 Agentic Code Review를 통해 현재까지 AI 코드 리뷰 위기에 대해 가장 데이터가 풍부하고 가장 정직한 평가를 발표했습니다. Faros의 수치만 보더라도 읽어볼 가치가 충분합니다. 코드 변동(Code churn) 861% 증가, 결함률(Defect rates) 9%에서 54%로 상승, 리뷰 소요 시간(Review duration) 441% 증가, 그리고 리뷰 없는 병합(Zero-review merges) 31% 증가 — 이는 누군가 리뷰를 건너뛰기로 선택했기 때문이 아니라, 리뷰어들이 단순히 속도를 맞출 수 없었기 때문입니다. GitClear의 조사 결과는 이 모든 문제를 하나의 비율로 요약합니다: 10%의 가치 전달 증가를 위해 4배의 코드가 생성됨.

진단은 정확합니다. 작성(Writing)은 저렴해졌습니다. 하지만 이해(Understanding)는 그렇지 않았습니다. 병목 현상(Bottleneck)은 검증(Verification) 단계로 이동했습니다. 모든 수치가 이를 확인해 줍니다.

처방전 — 더 잘 리뷰하고, 더 똑똑하게 리뷰하며, 위험도에 따라 계층화하고, 이기종(Heterogeneous) AI 리뷰어를 실행하며, 병합(Merge) 버튼은 인간이 계속 쥐고 있는 것 — 은 현재 존재하는 세상을 위한 타당한 운영상의 조언입니다. 팀들은 이를 따라야 하며, 이는 도움이 될 것입니다.

하지만 이것은 기계 규모(Machine-scale)의 문제에 대한 인간 규모(Human-scale)의 해결책이기도 합니다. 생성(Generation)은 기계의 속도로 실행됩니다. 리뷰(Review)는 인간의 속도로 실행됩니다. 한쪽은 가속화되고 다른 한쪽은 고정되어 있는 격차를 인간의 리뷰를 개선하는 것만으로는 메울 수 없습니다. 기사 자체의 데이터가 이를 증명합니다: 인간이 더 빨리 읽을 수 없기 때문에 리뷰 소요 시간이 441% 증가했고, 인간이 포기했기 때문에 리뷰 없는 병합이 31% 증가했습니다. 이것들은 리뷰를 개선해야 한다는 신호가 아닙니다. 주요 검증 메커니즘으로서의 리뷰가 더 나은 프로세스로도 높일 수 없는 한계점에 도달했다는 신호입니다. 기계 규모의 문제를 인간 규모의 접근 방식으로 해결할 수는 없습니다.

이 기사가 결코 묻지 않는 질문

이 기사는 에이전트(Agents)가 4배의 볼륨으로 코드를 생성한다는 점을 수용하고 다음과 같이 묻습니다: 어떻게 그것을 리뷰할 것인가? 모든 해결책은 그 질문에서 파생됩니다 — 분류(Triage), 계층화(Tiering), AI 지원 리뷰(AI-assisted review), 더 작은 PR(Pull Request), 유지보수가 많이 필요한 변경 사항에 대한 차단기(Circuit breakers).

이 기사가 결코 묻지 않는 질문은 이것입니다: 무엇이 올바른 것인지 아무도 정의하기 전에, 왜 4배나 많은 코드가 생성되고 있는가?

만약 4배 많은 코드가 단 10%의 가치만을 더 창출한다면, 생성된 코드의 약 75% — 그리고 리뷰어가 이제 처리해야 하는 코드의 75% — 는 전혀 가치를 창출하지 못했다는 뜻입니다. 이것은 리뷰의 문제가 아닙니다. 생성의 문제입니다. 리뷰는 원래 정원용 호스(garden hose)여야 했던 것을 소방용 호스(firehose)처럼 쏟아지는 데이터 속에서 걸러내라는 요구를 받고 있으며, 이 기사는 왜 호스가 그렇게 넓은지 묻는 대신 더 나은 필터를 제안하고 있습니다.

명세(Specification) — 출력이 충족해야 하는 사항을 인간이 작성하고 기계적으로 검증하는 선언 — 는 리뷰 중심 모델이 할 수 없는 두 가지를 수행합니다:

'명세'라는 개념을 추상적이라고 느끼는 개발자들을 위해 설명하자면: 여러분은 이미 타입 시그니처(type signature), 속성 기반 테스트(property-based test), 스키마(schema), 계약 테스트(contract test), 또는 인터페이스 정의(interface definition)를 작성할 때 이 작업을 수행하고 있습니다. 형식 기법(Formal methods), 타입 주도 개발(type-driven development), 계약에 의한 설계(design-by-contract) — 이것들은 명세를 구체화하고 강제할 수 있게 만드는 확립된 규율들입니다. 이 아이디어는 새로운 것이 아닙니다. 이를 에이전트가 생성한 코드의 주요(primary) 검증 메커니즘으로 적용하는 것이 새로운 것입니다.

이것은 코드를 한 줄도 쓰기 전에 이미 쓸모없어진 폭포수(waterfall) 시대의 200페이지짜리 요구사항 문서가 아닙니다. 그 문서들이 실패한 데에는 타당한 이유가 있었습니다. 그것들은 기계가 강제하지 않는 인간 가독용 문서였고, 한 번 작성된 후 업데이트되지 않았으며, 설명하려는 코드와 분리되어 있었습니다. 여기서 우리가 말하는 명세는 모든 차원에서 그 반대입니다: 코드 내에 존재하며 모든 커밋(commit)마다 실행되는, 작고 기계적이며 강제 가능한 선언들입니다. 타입 시그니처는 명세입니다. 계약 테스트는 명세입니다. 속성 단언(property assertion)은 명세입니다. 인터페이스 정의는 명세입니다.

이것들은 저장소(repo)에 있으며, 버전 관리되고 CI에서 실행됩니다. 위반될 경우 빌드를 실패시킵니다. 실행되기 때문에 노후화되지 않습니다. 기계가 이를 강제하기 때문에 무시되지 않습니다. 폭포수 방식의 명세는 인간이 읽어야 하는 문서였습니다. 이 명세는 기계가 반드시 확인해야 하는 제약 조건(constraint)입니다. 단어는 같지만, 메커니즘과 실패 양상은 정반대입니다.

Agile의 핵심 기여는 빠른 피드백 루프(feedback loop)였습니다. 작은 증분(increment)을 구축하고, 즉시 피드백을 받고, 조정하는 것입니다. 커밋 시 실패하는 타입 체크(type check)는 응답하는 데 441% 더 오래 걸리는 인간 리뷰어보다 더 빠른 피드백 루프입니다. 모든 푸시(push) 시 CI에서 실행되는 계약 테스트(contract test)는 31%의 확률로 건너뛰어지는 코드 리뷰보다 더 빠른 피드백 루프입니다. 기계에 의해 강제되는 명세(specification)는 Agile의 빠른 피드백 원칙을 아키텍처 수준에서 적용한 것입니다. 즉, 더 타이트한 루프, 더 빠른 신호, 모든 커밋에 대해 예외 없이 적용되는 것입니다. 폭포수(waterfall) 방식의 명세가 실패한 이유는 피드백이 느렸기 때문입니다(문서를 작성하고, 몇 달을 기다린 뒤, 그것이 틀렸음을 발견함). 이 명세가 성공하는 이유는 시스템 내에서 가장 빠른 피드백이기 때문입니다.

  1. 코드가 존재하기 _전_에 생성을 제약합니다. 따라서 에이전트(agent)는 인간이 나중에 의도(intent)를 평가해야 하는 그럴듯해 보이는 출력을 생성하는 대신, 선언된 목표를 향해 구축합니다.

  2. 기계의 속도로 기계적 검증(mechanical verification)을 가능하게 합니다. 따라서 연역 가능한 질문("이것이 계약을 충족하는가?")에 대해 차이점(diff)을 읽는 인간이 아니라 결정론적 게이트(deterministic gate)가 답을 내놓습니다.

리뷰는 명세가 없을 때 필요합니다. 리뷰는 기록되지 않은 의도를 수동으로, 비용을 들여, 피로하게 재구성하는 과정입니다. 이 기사의 가장 훌륭한 통찰 — 즉, 에이전트의 코드는 의도가 결여되어 있으며 리뷰어가 이를 재구성해야 한다는 점 — 은 해결책까지 단 한 문장만을 남겨두고 있습니다: 의도를 먼저 명세로서 작성하고, 이를 바탕으로 기계적으로 검증하십시오. 이 기사는 PR(Pull Request)에서의 의사결정 로그(decision logs)를 지향합니다. 해결책은 생성 전의 명세입니다.

4배의 코드는 뺄셈 규율(subtraction discipline)의 부재를 측정한 것이다

GitClear의 수치 — 4배의 출력, 10% 더 높은 가치 — 는 이 기사에서 가장 중요한 수치이지만, 기사는 이를 과소평가하고 있습니다.

만약 당신이 4배 더 많은 코드를 생성하지만 그중 10%만이 추가적인 가치를 창출한다면, 그것은 리뷰의 문제가 아니라 축적(accumulation)의 문제입니다. 생성된 모든 불필요한 라인은 다음과 같은 결과를 초래합니다: 소모된 토큰(추론 비용 (inference cost)), 소비된 리뷰 시간 (441% 증가), 발생한 변경 사항 (churn, 861% 증가), 그리고 확장된 결함 범위 (9%에서 54%로 급증). 리뷰 위기는 생성 위기의 하류(downstream) 현상입니다. 입력량 자체가 원인이기 때문에 더 나은 리뷰로는 이를 해결할 수 없습니다.

대안은 뺄셈의 규율(subtraction discipline)입니다: 생성되지 않는 작업을 극대화하십시오. 무엇이 올바른 것인지 선언하는 명세(specification)는 에이전트(agent)가 인간이 평가해야 하는 그럴듯해 보이는 코드의 네 가지 변형이 아니라, 꼭 필요한 것만을 생성하도록 제약합니다. 생성되는 라인이 적을수록 리뷰할 라인이 적어지고, 포착해야 할 결함이 줄어들며, 관리해야 할 변경 사항(churn)이 감소하고, 추론 비용(inference cost)이 낮아집니다. 이 기사의 수치들은 더 나은 리뷰의 필요성보다 명세 우선 개발(specification-first development)의 정당성을 더 강력하게 입증합니다.

리뷰는 검증(verification)이 아니다

이 기사는 리뷰를 검증(verification) 계층으로 취급하고 있습니다. 이러한 혼동이 문제의 핵심입니다.

리뷰는 인간이 코드를 읽고 판단을 내리는 과정입니다. 이는 주관적이며, 피로를 느끼고, 인간의 읽기 속도에 맞춰 확장됩니다. 기사에서도 정확히 지적했듯이, 인간의 읽기 속도는 우리가 화면을 응시하기 시작한 이래로 변하지 않았습니다. 리뷰는 판결이 아닌 의견을 만들어냅니다. 반면 검증(verification)은 선언된 속성에 대해 출력을 결정론적으로 확인하는 것입니다. 검증은 피로를 느끼지 않으며, 기계의 속도로 확장되고, 통과 또는 실패라는 판결을 내립니다. 매번 동일한 답변을 내놓으며, 필요할 때 언제든 재현 가능합니다.

해당 기사의 데이터는 그 차이를 증명합니다. 인간은 더 빨리 읽을 수 없기 때문에 리뷰 시간(review duration)은 441% 증가했습니다. 인간이 시도하기를 포기했기 때문에 리뷰 없는 병합(Zero-review merges)은 31% 증가했습니다. 검증 게이트(verification gate) — 즉, 타입 체커(type checker), 속성 기반 테스트 스위트(property-based test suite), 계약 강제기(contract enforcer) — 가 있었다면 속도가 느려지지 않았을 것입니다. 그것은 모든 PR을 선언된 속성(properties)에 따라 기계의 속도로 검사했을 것이며, 441%의 증가도, 피로도도, 그리고 기계는 피곤하다고 해서 검사를 건너뛰지 않기에 발생하는 "검증 없는 병합(zero-verification merges)"도 없었을 것입니다.

기사에서는 CI와 테스트를 언급하지만, 이를 리뷰를 위한 보조 수단 — 즉, 인간이 실제 작업을 수행하는 동안 버텨주는 벽 — 으로 취급합니다. 데이터가 요구하는 역전(inversion)은 다음과 같습니다: 검증(verification)이 일차적인 게이트이다. 리뷰는 검증이 답할 수 없는 질문들을 위한 것이다. 연역 가능한 질문들(이것이 계약을 충족하는가, 이것이 타입과 일치하는가, 이것이 불변량(invariant)을 위반하는가)은 결정론적 게이트(deterministic gate)를 통과합니다. 오직 인간의 판단이 필요한 질문들(이것이 구축하기에 적절한 변경인가, 이 아키텍처적 선택이 타당한가, 이것이 올바른 추상화인가)만이 사람에게 전달됩니다.

그러한 분리는 그 규모(volume)에서 살아남기 위해 필수적입니다. 코드를 4배 더 많이, 441% 더 느리게 리뷰함으로써 살아남는 것이 아닙니다. 연역 가능한 질문들은 기계의 속도로 처리할 수 있는 기계로 라우팅하고, 인간의 주의력은 그것이 진정으로 필요한, 확실하지 않은 질문들을 위해 남겨둠으로써 살아남는 것입니다.

근본적인 설계 원칙은 분리입니다. 시스템에는 인간의 판단력(human judgment)과 기계의 속도(machine speed)가 모두 필요하지만, 동일한 단계에서 이루어져서는 안 됩니다. 집행 루프(enforcement loop)에 있는 인간은 가장 취약한 연결 고리입니다. 그들은 피로를 느끼며, 단계를 건너뛰고, 기준치 대비 441%나 느려집니다. 판단 루프(judgment loop)에 있는 기계는 가장 취약한 연결 고리입니다. 기계는 비즈니스 맥락(business context)이 부족하고, 의도(intent)를 선언할 수 없으며, 자신의 오류에 대해 자신 있게 동의합니다. 해결책은 이들을 공간적으로 분리하는 것입니다. 인간은 상류(upstream)에서 의도를 선언하고 어떤 모델도 맥락을 파악하여 내릴 수 없는 판단을 제공합니다. 기계는 하류(downstream)에서 피로 없이, 건너뛰기 없이, 31%의 리뷰 제로 붕괴(zero-review collapse) 없이, 모든 변경 사항에 대해 선언된 의도를 기계의 속도로 집행합니다. 느린 것과 빠른 것, 각각이 있어야 할 곳에 두는 것입니다. 인간의 가치는 diff를 읽는 것이 아니라, 무엇이 '정확함(correct)'인지를 결정하는 데 있습니다. 기계의 가치는 의견을 형성하는 것이 아니라, 생성(generation)이 요구하는 속도에 맞춰 모든 커밋(commit)에 대해 선언된 속성(properties)을 기계적으로 집행하는 데 있습니다. 이 둘을 동일한 단계에서 혼합하는 것, 즉 인간이 기계 속도의 출력을 한 줄씩 읽는 것은 441%라는 수치가 측정하고 있는 모순입니다.

인간이 리뷰를 수행할 때 — 즉 기계가 아직 확인할 수 없는 무언가에 대해 판단이 필요할 때 — 그 판단이 반드시 인간의 규모(human-scale)에 머물러 있을 필요는 없습니다. 리뷰어가 생성하는 통찰 중 규칙(rule)으로 표현될 수 있는 모든 것은 기계가 향후 모든 커밋에 대해 집행할 명세(specification)가 됩니다. 인간은 그것을 한 번 잡아냅니다. 기계는 그 이후 영원히 잡아냅니다. 각 리뷰 사이클은 인간의 판단을 필요로 하는 항목의 풀(pool)을 영구적으로 줄이고, 기계적으로 집행되는 항목의 풀을 영구적으로 늘립니다. 리뷰는 반복되는 비용이 아니라 복리로 쌓이는 일회성 투자(one-time investment)가 됩니다. 일단 명세로 변환된 각 인간의 판단은 다시는 내릴 필요가 없습니다. 시스템은 느려지지 않으면서 시간이 지남에 따라 더 똑똑해집니다.

이것은 새로운 설계가 아닙니다. 기계의 속도가 검토 및 승인하는 인간의 능력을 초과하는 동일한 벽에 부딪힌 모든 분야는 동일한 분리(separation) 방식에 도달했습니다. 이 패턴은 의견이 아니라 청사진입니다:

분야속도 문제인간의 역할 (느림, 상류/upstream)기계의 역할 (빠름, 하류/downstream)
항공 (Aviation)비행 역학이 인간의 반응 속도를 초과함조종사가 의도(방향, 고도, 접근 방식)를 선언함비행 컴퓨터가 엔벨로프 보호 (envelope protection)를 강제함 — 조종사의 입력과 관계없이 기계의 속도로 불안전한 상태를 방지함
...

모든 경우에서 해결책은 동일합니다. 병목 현상(bottleneck)이 되는 강제(enforcement) 단계에서 인간을 제거하고, 대체 불가능한 판단을 제공하는 선언(declaration) 단계로 인간을 이동시키는 것입니다. 기계는 인간이 선언한 것을 강제합니다. 어떤 항공 규제 기관도 조종사에게 모든 제어면(control-surface) 조정을 읽고 승인하라고 요구하지 않습니다. 어떤 원자력 규제 기관도 운영자에게 모든 센서 판독값을 검토하고 서명하라고 요구하지 않습니다. 그들은 엔벨로프(envelope)를 선언합니다. 기계는 그것을 강제합니다. Fly-by-wire를 안전하게 만들고, 원자로를 생존 가능하게 하며, 트레이딩을 비극적이지 않게 만든 것과 동일한 분리가 소프트웨어에서는 아직 이루어지지 않았으며, 441%의 검토 시간 증가는 이를 실행하지 않은 대가입니다.

누락된 의도는 도구(tooling)의 문제가 아니라 명세(specification)의 문제이다

이 글의 가장 뛰어난 개념적 통찰은 에이전트가 생성한 코드에 의도(intent)가 결여되어 있다는 점입니다. 검토자는 "이 코드를 처음으로 보는 인간"이며, 기록되지 않은 근거(rationale)를 재구성해야만 합니다. 이 글은 이를 도구의 문제로 규정합니다. 즉, 에이전트의 추론을 PR(Pull Request)의 결정 로그(decision log)로 캡처하면 재구성 비용이 사라진다는 것입니다.

그것은 올바른 방향으로 가는 단계이지만, 완전한 해결책에는 한 걸음 모자란 단계입니다.

결정 로그 (Decision log)는 에이전트가 작업을  어떻게 구현했는지에 대한 추론 (reasoning) 과정을 캡처합니다. 하지만 작업이  무엇을 결과물로 내놓았어야 했는지에 대한 인간의 판단 (judgment)은 캡처하지 못합니다. 에이전트의 추론은 자신의 선택, 즉 왜 이 데이터 구조를 사용했는지, 왜 이 API 호출을 했는지에 관한 것입니다. 실제로 중요한 의도 (intent)는 상위 단계 (upstream)에 있습니다. 즉, 인간이 이 변경을 통해 무엇을 달성하고자 했는지, 어떤 속성 (properties)을 충족해야 하는지, 어떤 불변량 (invariants)을 보존해야 하는지에 관한 것입니다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0