리뷰는 확장되지 않지만, 검증은 확장됩니다
요약
에이전트 기반 소프트웨어 개발 시대에는 기존의 코드 리뷰 방식이 한계에 직면합니다. 에이전트가 생성하는 방대한 코드 양을 인간이 검토하는 대신, 명세(Specification), 검증(Verification), 봉쇄(Containment)를 통해 시스템적으로 정확성을 확보해야 합니다.
핵심 포인트
- 에이전트 시대에는 코드 리뷰보다 자동화된 검증이 필수적임
- 명세(Specification)를 통해 정확성의 기준을 사전에 정의해야 함
- TDD, CI 등 자동화된 검증 계층을 구축하여 인간의 개입을 최소화함
- 실패 시 영향 범위를 제한하는 봉쇄(Containment) 전략이 필요함
제4장 심층 분석: 계획 리뷰(Plan Review)에서 검증(Validation)으로
“에이전트 시대의 소프트웨어 개발(Software Development in the Agentic Era)”의 보충 문서
작성자: Mike, Claude (Anthropic)와의 협업
메인 가이드의 제4장에서는 계획 리뷰(Plan Review)를 에이전트 시대의 핵심 기술이라고 부릅니다. 이는 그 자체로 맞는 말입니다. 에이전트가 실행하기 전에 의도를 리뷰하는 것은 규모가 작고, 다루기 쉬우며, 아직 충분히 활용되지 않고 있습니다. 하지만 그것만으로는 충분하지 않으며, 대부분의 팀이 “AI 코드 리뷰(AI code review)”에 대해 이야기하는 방식은 그들이 왜 충분하지 않은지를 깨닫지 못했음을 시사합니다.
깔끔한 200줄짜리 계획을 생성하는 동일한 에이전트가 그 계획으로부터 2,000줄의 코드를 생성합니다. 계획은 리뷰할 수 있습니다. 하지만 코드는 리뷰할 수 없습니다. 에이전트가 생성하는 그 엄청난 양을 고려하면, 정말로 말이죠. 그 정도 규모에서 리뷰처럼 보이는 것은 대부분 훑어보기, 패턴 매칭(Pattern-matching), 그리고 신뢰에 불과합니다.
이 장에서는 제4장의 주장을 증거가 뒷받침하는 방향으로 좁혀서 정의합니다:
계획 리뷰(Plan Review)는 필요하지만 불충분합니다. 에이전트의 규모에서는 코드 리뷰(Code review)가 확장되지 않으며, 검증(Validation)은 확장됩니다. 중요한 기술은 누군가가 모든 줄을 읽지 않고도 정확성(Correctness)을 확인할 수 있도록 시스템을 설계하는 것입니다.
이는 엔지니어의 주의를 전환시킵니다. “에이전트가 올바른 코드를 작성했는가?”(이는 당신이 그것을 구별할 수 있다고 가정하는 것입니다)라는 질문보다는, “정확성(Correctness)이 충분히 날카롭게 정의되어 있고, 무언가 감지하지 못하면 에이전트가 경로를 이탈할 수 없을 정도로 충분히 광범위하게 체크되고 있는가?”라는 질문으로 옮겨갑니다. 계획 리뷰는 여전히 수행됩니다. 다만 그것이 하중을 견디는 핵심 안전장치(Load-bearing safeguard) 역할을 하는 것은 멈추게 됩니다.
대안들은 제3장의 심층 분석에서 보여준 구조적 변화를 반영하여, 환경이 제공해야 할 세 가지 속성으로 구성됩니다:
- Specification (명세) — 에이전트가 실행되기 전에 무엇이 "정확한" 것인지 정의하는 것 (Kiro spec mode, GitHub Spec Kit, BDD, 계약으로서의 수락 기준).
- Verification (검증) — 지속적으로 실행되며 인간의 읽기를 요구하지 않는 자동화된 체크 (TDD, CI, 속성 기반 테스트 (property-based tests), 섀도 모드 (shadow mode), 외부 오라클 (external oracles)).
- Containment (봉쇄) — 앞선 두 단계의 실패가 복구 가능하도록 영향 범위 (blast radius)를 제한하는 것 (소규모 배치, 피처 플래그 (feature flags), 환경 분리, 가역적 작업).
각각은 코드를 읽는 것에 의존하지 않는 검증의 계층입니다. 각각은 개별적으로는 불충분합니다. 심층 방어 (defense-in-depth)는 이 세 가지를 결합함으로써, 그리고 계획 리뷰 (plan review)를 각 계층이 무엇을 기준으로 검사할지를 정의하는 상류 게이트 (upstream gate)로 유지함으로써 완성됩니다.
제1부: 코드 장벽 문제 (The Code Wall Problem)
코드 리뷰가 작동했던 이유는 인간이 인간의 속도로 코드를 작성했기 때문입니다. 200줄짜리 PR (Pull Request)은 몇 시간의 고민이 담긴 결과물이었고, 이를 읽는 데는 몇 분이 걸렸습니다. 즉, 비율상 리뷰어에게 유리했습니다. 또한 리뷰어는 단순히 구문을 확인하는 것이 아니라, 재구성이 가능할 만큼 충분한 논리를 담고 있는 코드를 통해 작성자의 추론 과정을 재구성하고 있었습니다.
에이전트는 이 비율을 깨뜨렸습니다. 제2장의 증거를 보면 다음과 같습니다: Faros AI는 AI 도입 후 리뷰 시간은 91% 증가하고 PR 크기는 154% 증가한 것을 측정했습니다; Jellyfish는 완전 도입 후 PR 처리량이 약 2배 증가하는 것을 확인했습니다; GitClear의 2026년 코호트(cohort) 분석에 따르면 파워 유저들은 4~10배 더 많은 코드를 작성하고 있었습니다. 이 규모는 이론적인 것이 아니라 측정된 수치입니다.
그 정도의 규모에서는 단순히 시간만 변하는 것이 아니라 인지적 과업 (cognitive task) 자체가 변합니다. 에이전트가 출력한 2,000줄의 코드를 마주한 리뷰어는 에이전트의 추론을 재구성할 수 없습니다. 에이전트는 인간처럼 추론하지 않았기 때문이며, 복구할 수 있는 직관 자체가 존재하지 않습니다. 따라서 리뷰어는 각 줄을 검증할 수 있을 만큼 충분히 주의 깊게 읽거나 (이는 작성하는 것보다 더 느려지게 되어 전제 조건 자체를 무너뜨립니다), 표면적인 패턴만 훑어보고 나머지는 승인(rubber-stamp)해 버립니다. 규모가 커지면, 실제로 일어나는 일은 후자입니다.
Chapter 1의 Moltbook 사례는 명확한 예시입니다: AI가 생성한 코드는 모든 기능 테스트(functional tests)를 통과했고 앱은 출시되었지만, 행 수준 보안 (Row Level Security)이 활성화되지 않아 150만 개의 API 키가 유출되었습니다. 코드는 제대로 작동했습니다. 리뷰는 '존재하지 않는 것'을 잡아내지 못했습니다.
Karpathy는 이를 _이해 부채 (comprehension debt)_라고 명명했습니다. 이는 아무도 읽지 않는 코드를 에이전트가 단번에(one-shot) 작성할 때 쌓이는 것을 의미합니다. Unmesh Joshi와 Martin Fowler는 2026년 1월의 대화에서 다른 각도로 동일한 결론에 도달하며 이를 _인지 부채 (cognitive debt)_라고 불렀습니다. 즉, 공유된 이해가 없는 LLM 생성 코드는 팀이 이미 출시된 결과물을 발전시킬 수 없게 만듭니다. 두 명의 시니어 전문가, 두 개의 명칭, 하나의 현상 — 인간의 읽기 이외의 무언가가 이를 해소하지 않는 한, 이는 처리량(throughput)과 함께 기계적으로 증가합니다. 이것이 이 장의 핵심인 역전 현상입니다: 리뷰는 누군가가 오류를 잡아낼 수 있을 만큼 주의 깊게 읽는다는 것을 전제로 하지만, 에이전트의 규모가 커지면 그 전제는 깨집니다. 검증(Validation)은 주의 깊은 읽기에 의존하지 않는 메커니즘으로 이를 대체합니다.
계획(plan)은 여전히 중요합니다. 그것은 작고, 에이전트의 의도를 알려줍니다. 하지만 일단 코드가 흐르기 시작하면, 질문은 "내가 이것을 리뷰했는가?"에서 "내가 놓친 것들을 무엇이 잡아내고 있는가?"로 바뀝니다.
파트 2: 명세 (Specification) — 에이전트가 실행되기 전 '정답'을 정의하기
잡기에 가장 저렴한 버그는 에이전트가 아예 작성하지 않은 버그입니다. 명세(Specification)는 "에이전트가 무엇을 생성해야 하는가"를 충분히 정밀하게 만들어, 잘못된 의도가 명세 단계에서 드러나게 하고, 에이전트에게는 모호하지 않은 목표를 제공하며, 수락 기준(acceptance criteria)이 영어로 된 힌트가 아닌 테스트 가능한 제약 조건이 되게 하고, 이탈(drift)할 대상이 구체적으로 존재하기 때문에 이탈을 감지할 수 있게 합니다.
이러한 변화는 “에이전트에게 무엇을 만들라고 말하는 것”(프롬프트, prompt)에서 “'만들어진 것'이 무엇인지 정의한 다음, 에이전트가 만들게 하는 것”(계약, contract)으로의 전환입니다. 2026년 1월, Kiro의 스펙 모드(spec mode)에 대한 한 실무자의 기록은 그 효과를 포착했습니다. 수락 기준(acceptance criteria)은 더 이상 가이드가 아니라 시스템이 강제하는 제약 조건(constraints)이 되었습니다. 이는 작성자가 더 노력했기 때문이 아니라, 이탈(deviation)이 명확해졌기 때문입니다.
학술적 프레임워크도 같은 달에 등장했습니다. Piskala의 “Spec-Driven Development: From Code to Contract”(arXiv, 2026년 1월)는 스펙 스펙트럼 (specification spectrum) — 코드 우선(code-first) → 스펙 우선(spec-first) → 스펙 고정(spec-anchored) → 스펙 기반 소스(spec-as-source) — 을 공식화합니다. 오른쪽으로 이동할수록 코드에 대한 스펙의 권위가 높아지며, 둘을 일치시키기 위해 필요한 규율도 증가합니다. 대부분의 팀은 코드 우선(specs written after, if at all, and drifting; 스펙이 나중에 작성되거나 아예 작성되지 않으며 이탈함) 단계에 머물러 있습니다. 스펙 우선(spec-first)은 진입점입니다(스펙이 초기 구축을 안내하지만, 유지 관리되지는 않을 수 있음). 스펙 고정(spec-anchored)은 스펙을 코드와 동기화되는 살아있는 문서(living documentation)로 유지합니다. 스펙 기반 소스(spec-as-source)는 스펙을 실제 산출물(artifact)로 취급하고 이를 통해 코드를 재생성합니다. 이 논문은 통제된 실험이 아닌 프레임워크 및 사례 연구 가이드이므로, 결과의 개선을 증명하기보다는 관행을 공식화하는 데 중점을 둡니다. 하지만 이 논문의 4단계 워크플로우(명세(Specify), 계획(Plan), 구현(Implement), 검증(Validate))는 이 장의 논지와 거의 정확히 일치합니다. 즉, 계획 검토(plan review)는 상류(upstream)에 위치하고, 검증(validation)이 마무리(close)를 담당합니다.
두 가지 프로덕션급 구현체
Amazon Kiro (2025년 8월 GA)는 명시적인 단계(phases)를 갖춘 명세 주도 개발 (spec-driven development)을 중심으로 구축된 VS Code 포크(fork)입니다. 요구사항 수집 (requirements gathering) 단계에서는 수락 기준 (acceptance criteria)이 포함된 사용자 스토리 (user stories)를 생성하고, 기술 설계 (technical design) 단계에서는 아키텍처와 스키마 (schemas)를 생성하며, 작업 분해 (task breakdown) 단계에서는 순차적인 계획을 생성합니다. 그 이후에야 에이전트 (agent)가 실행을 수행합니다. 각 단계는 Requirements-First 및 Design-First 변형 모두에서 다음 단계가 실행되기 전에 검토 (reviewable)할 수 있으며, 별도의 버그 수정 명세 (Bugfix Spec) 모드도 제공됩니다. 주목할 만한 통찰은 다음과 같습니다: Kiro는 에이전트의 출력물 (output) 을 검토 가능하게 만들려 하지 않습니다. 대신 명세 (spec) 를 검토 가능하게 만듭니다. 명세는 양이 적고 이해관계가 가장 명확한 지점이며, 그 후 에이전트가 해당 명세에 따라 구현하도록 제약을 겁니다.
GitHub Spec Kit (2025년 9월 오픈 소스 공개, MIT 라이선스)는 도구에 구애받지 않는 (tool-agnostic) 버전입니다. 템플릿, CLI, 그리고 명세(specification) → 계획(plan) → 작은 테스트 가능한 작업(small testable tasks) 순으로 작업의 중심을 잡는 프롬프트(prompts)로 구성되며, 에이전트(Copilot, Claude Code, Gemini CLI, Cursor 또는 30개 이상의 통합 도구 중 하나)가 구현을 담당합니다. GitHub의 프레임워크에 따르면: 팀들은 코딩 에이전트를 검색 엔진처럼 취급하고 있지만, 실제로는 모호하지 않은 지침 (unambiguous instructions)이 필요한, 글자 그대로를 따르는 페어 프로그래머 (pair programmers)처럼 취급해야 합니다.
이 두 가지가 동일한 워크플로(workflow) 형태로 수렴하고 있다는 사실 자체가 시사하는 바가 큽니다. Kiro는 한 벤더의 베팅이며, Spec Kit은 하나의 카테고리 관행 (category convention)이 되어가고 있는 것에 대한 GitHub의 오픈 소스 표준화입니다. 둘 다 완벽하지는 않습니다. 둘 다 여전히 명세가 잘 작성되어 있는지에 의존하며, 잘못된 명세가 잘못된 코드를 생성하는 것을 막지는 못합니다. 하지만 두 방식 모두 인간의 검토 (human review)를 가장 비용이 적게 드는 상류 (upstream) 단계로 이동시킵니다.
명세의 공용어로서의 BDD
Behavior-Driven Development (BDD)는 에이전트 시대보다 15년 앞서 등장했지만, 그 핵심 산출물인 Given-When-Then 형식의 실행 가능한 인수 조건 (acceptance criteria)은 이제 설계 당시 의도하지 않았던 역할을 수행하고 있습니다. 바로 인간과 에이전트가 동일한 의미로 읽을 수 있는 명세 (specification) 형식으로서의 역할입니다. 단일 Gherkin 시나리오는 인간이 읽을 수 있는 요구사항인 동시에, 에이전트가 읽을 수 있는 명세이며, (단계 정의 (step-definition) 레이어가 있다면) 실행 가능한 테스트가 됩니다. 동일한 산출물이 번역 손실 없이 세 부류의 청중에게 의도를 전달합니다. 그리고 번역 손실이 발생하는 바로 그 지점에서 모호함으로 인한 버그가 탄생합니다.
새로운 점은 다음과 같습니다. BDD 시나리오는 이제 사후 검증을 위한 도구가 아니라 에이전트의 입력값 (inputs)으로 사용됩니다. 테스트로 실행되는 Gherkin 파일이 에이전트의 컨텍스트 (context)에서 참조되는 계약 (contract)이 될 수 있습니다. 다만, 이는 시나리오가 구현 (implementation)
_전_에 작성되었을 때만 유효하다는 제약이 있습니다. 에이전트가 코드를 작성한
_후_에, 방금 작성한 코드를 바탕으로 생성한 시나리오는 명세가 아니라 기술 (description)에 불과합니다. 그리고 이는 메인 가이드의 7장에서 경고하는 자기 수정 (self-correction)의 사각지대를 수반합니다.
두 가지 안티 패턴 (anti-patterns)
자동 생성된 명세 (Auto-generated specs). 3장에서 심층 분석한 자동 생성된 AGENTS.md 파일과 동일한 실패 모드입니다. 명세를 작성하는 시스템이 그것을 읽는 시스템과 같은 종류라면, 제약 (constraints)을 추가한 것이 아니라 토큰 (tokens)만 추가한 셈이 됩니다. 에이전트가 모호한 프롬프트로부터 생성하고 그에 따라 구현한 명세는 "에이전트가 원하는 대로 수행하고 이를 문서화한 것"이지, 명세 주도 개발 (spec-driven development)이 아닙니다.
구현과 괴리되는 명세 (Specs that drift from implementation). 명세와 코드가 일치하지 않는 상황이 처음 발생하고 팀이 코드를 신뢰하게 되면, 그 시점부터 명세는 장식용에 불과해집니다. 해결책은 살아있는 모든 산출물과 동일합니다. PR (Pull Request)에서 검토하고, 변경 사항을 실질적인 것으로 취급하며, 이상적으로는 명세와 그로부터 파생된 테스트가 일치하지 않을 때 CI (Continuous Integration)를 실패시켜야 합니다.
출처: Kiro Documentation & Specs guide (aws.amazon.com); InfoQ, “Beyond Vibe Coding: Amazon Introduces Kiro” (2025년 8월); GitHub Blog, “Spec-driven development with AI” (2025년 9월); DEV.to, “What I Learned Using SDD with Kiro” (2026년 1월); Piskala, “Spec-Driven Development: From Code to Contract,” arXiv:2602.00180 (2026년 1월).
파트 3: 검증 (Verification) — 읽지 않고도 알 수 있는 방법
명세 (Specification)는 무엇이 참이어야 하는지를 정의합니다. 검증 (Verification)은 누군가가 코드를 읽어 확인하지 않아도, 그것이 실제로 그러한지를 지속적으로 체크합니다. 이것은 에이전트의 출력량에 맞춰 확장되어야 하는 계층입니다. 왜냐하면 이것만이 확장이 가능한 유일한 계층이기 때문입니다. 코드베이스가 커진다고 해서 인간이 더 주의 깊게 읽지는 않지만, 자동화된 체크 (Automated checks)는 규모와 상관없이 실행됩니다.
하중을 견디는 계층으로서의 TDD
챕터 3의 심층 분석에서는 테스트를 에이전트의 피드백 루프 (Feedback loop)로 다루었습니다. 여기서의 프레임워크는 여러분의 요구사항에 관한 것입니다. 여러분이 코드를 읽는 것을 멈출 때, 테스트는 에이전트의 출력물과 프로덕션 (Production) 사이를 신뢰할 수 있게 지켜주는 유일한 수단이 됩니다. 이는 업무의 성격을 변화시킵니다. 인간의 리뷰 (Human-review)가 중심인 세상에서는 리뷰어가 로직과 설계 문제를 잡아내는 동안 테스트는 회귀 (Regressions)를 잡아냅니다. 하지만 리뷰어가 훑어보기만 하는 에이전트 대량 생산의 세상에서는, 테스트가 두 가지 역할을 모두 수행해야 합니다. 즉, 에이전트가 구현해야 할 계약 (Contract)을 정의하는 동시에, 구현이 그 계약에서 벗어나는 지점을 잡아내야 합니다.
따라서 커버리지 (Coverage)는 단순한 위생 지표 (Hygiene metric)를 넘어 하중을 견디는 핵심 요소가 됩니다. 이는 조작 가능한 라인 커버리지 (Line-coverage)의 의미가 아닙 (에이전트는 명세가 말하는 대로 동작하지 않는 코드에 대해서도 100% 라인 커버리지를 달성할 수 있습니다). 대신 행동적 (Behavioral) 의미에서의 확장입니다. 즉, 명세가 정의한 계약들이 실제로 실패할 수 있는 조건 하에서 제대로 실행되고 있는가 하는 점입니다.
이 지점에서 TDD(Test-Driven Development)의 순서가 중요해집니다. 구현 전에 작성된 테스트는 의도(intent)를 설명하며, 구현 후에 작성된 테스트는 동작(behavior)을 설명합니다. 에이전트(agent)의 경우, 이것은 명세(specification)와 사후 합리화(post-hoc rationalization) 사이의 결정적인 차이입니다. 1장의 Reco 재작성이 부분적으로 성공했던 이유는 AI가 관여하기 _전_에 이미 1,778개의 JSONata 테스트 케이스가 존재했기 때문입니다. AI의 역할은 무엇이 "통과"를 의미하는지 발명하는 것이 아니라, 그 테스트를 통과하도록 만드는 것이었습니다. Unmesh Joshi를 인용한 Martin Fowler의 2026년 1월 단편(fragment)은 이를 강제 함수(forcing function)로 규정했습니다. 즉, 수천 줄의 생성된 코드를 제어하려면 무엇이 구축되고 있는지 이해할 수 있게 해주는 무언가가 필요하며, 테스트가 바로 그 무언가라는 것입니다.
조정된 주장(calibrated claim): TDD 스타일의 워크플로우(명세로서의 테스트, 작은 단계, 빠른 Green/Red 사이클)는 에이전트 피드백 루프(agent feedback loops)에 매우 적합하며, 깨끗한 에이전트 생성 코드를 배포하는 팀들은 거의 모두 TDD 계열의 무언가를 사용하고 있습니다. 이것이 인과 관계인지, 아니면 더 넓은 엔지니어링 규율(engineering discipline)과 단순히 상관관계가 있는 것인지는 경험적으로 확정되지 않았습니다. 무작위 대조 시험(RCT)은 없으며, 오직 일관된 실무자들의 경험만이 존재할 뿐입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기