명세(Specification)는 컴파일 대상이다
요약
AI 에이전트 시대에는 구현보다 명세(Specification)의 중요성이 커지며, 명세는 단순한 산문이 아닌 컴파일 가능한 소스 아티팩트가 되어야 합니다. 명세가 코드베이스의 실제 상태와 일치하도록 타입 체크와 린팅 같은 검증 과정을 거쳐야 오류 없는 자동 구현이 가능합니다.
핵심 포인트
- 에이전트의 등장으로 구현의 병목이 해소되고 명세의 가치가 상승함
- 명세는 판단력을 보완하는 문서가 아닌, 시스템으로 컴파일되는 소스 아티팩트여야 함
- 명세 단계에서 타입 체크와 린팅을 통해 실제 코드와의 정합성을 검증해야 함
- 검증되지 않은 명세는 에이전트에 의해 잘못된 시스템을 빠르게 구축하게 만듦
제 커리어의 대부분 동안, 명세(Specification)는 저렴한 부분이었습니다. 문단 하나, 혹은 티켓 하나를 작성하면, 그 뒤의 비싸고 숙련되며 대체 불가능한 작업이 뒤따랐습니다. 바로 그 문단을 정확한 코드로 바꾸는 작업 말입니다. 명세는 제안이었고, 구현(Implementation)이 진실이었습니다.
이제 그 비율이 역전되었지만, 거의 아무도 자신의 업무 가치를 이에 맞춰 재산정하지 않고 있습니다.
에이전트(Agent)가 변경 사항에 대한 정밀한 설명을 받아 몇 분 만에 작동하고 테스트까지 완료된 구현을 만들어낼 수 있게 되면서, 구현은 더 이상 병목 구간이 아닙니다. 구현은 더 이상 기술이 머무는 곳이 아닙니다. 기술은 기계가 대신해 줄 수 없는 유일한 곳, 즉 무엇을 만들지 결정하고 나머지가 기계적으로 처리될 수 있도록 충분히 정밀하게 기술하는 단계로 상향 이동합니다. 시니어 엔지니어는 사라지지 않습니다. 그들은 사다리의 한 단계 위, 즉 명세(Specification) 단계로 밀려 올라갑니다.
그리고 도구(Tooling)가 아직 따라잡지 못한 부분이 여기 있습니다. 만약 구현이 이제 컴파일 단계라면, 명세(Specification)는 컴파일 대상(Compile Target)입니다. 명세는 더 이상 판단력으로 빈틈을 채워줄 사람에게 전달하는 산문(Prose)이 아닙니다. 그것은 시스템으로 컴파일되는 소스 아티팩트(Source Artifact)입니다. 그리고 컴파일러에 입력되는 모든 소스 아티팩트와 마찬가지로, 명세 역시 타입 체커(Type Checker), 린터(Linter), 그리고 입력이 잘못되었을 때 *실패(Fail)*하는 빌드 과정을 거칠 자격이 있습니다.
이것이 전체 논지입니다. 이 시리즈의 나머지 내용은 이를 문자 그대로 받아들였을 때 어떤 모습인지에 대해 다룹니다.
"컴파일"이 실제로 요구하는 것
컴파일러는 특정한 방식으로, 유용할 만큼 냉혹합니다. 컴파일러는 당신의 프로그램이 멋진 아이디어인지 묻지 않습니다. 대신 프로그램이 *근거(Grounded)*가 있는지 묻습니다. 이 심볼(Symbol)들이 존재하는지, 타입(Type)들이 일치하는지, 이 호출이 실제 시그니처(Signature)와 일치하는지를 묻습니다. 답이 '아니오'라면 컴파일러는 진행을 거부합니다. 이 거부야말로 핵심 기능입니다. 정중하게 경고만 하고 어쨌든 바이너리(Binary)를 내뱉는 컴파일러라면 아무런 쓸모가 없을 것입니다.
그 표준을 제품 명세(Product Specification)에 적용하면 대부분의 명세가 즉시 실패합니다. 전형적인 명세는 현실에 대한 주장들로 가득 차 있습니다: "API가 이미 이 필드를 반환합니다", "이것은 단순한 UI 변경 사항입니다", "소비자(Consumer)가 추가 파라미터를 처리할 수 있습니다"와 같은 것들 말입니다. 이러한 주장 각각은 실제 코드베이스(Codebase)에 비추어 보았을 때 참이거나 거짓인 주장이며, 그중 거의 어느 것도 검증되지 않습니다. 이들은 기획 문서(Planning doc)에서 단언되고, 그럴듯하다는(Plausible) 이유로 리뷰를 통과하며, 3주 후 구현 단계에서 누군가가 해당 필드가 전혀 존재하지 않는다는 사실을 발견했을 때 폭발합니다.
사람이 구현을 작성할 때는 이 상황을 견뎌낼 수 있었습니다. 사람은 코딩하는 동안 그 거짓말을 포착하고, 욕설을 내뱉으며, 머릿속에서 명세를 수정했습니다. 하지만 에이전트(Agent)가 구현을 작성할 때는 그 거짓말이 그대로 통과됩니다. 에이전트는 명세를 신뢰합니다. 명세가 틀렸던 것입니다. 이제 당신은 빠르게 구축되었지만, 자신 있게 틀린 시스템을 갖게 됩니다.
제가 끊임없이 목격하는 실패의 형태를 예로 들어보겠습니다. 초안 명세에는 당신이 구축하려는 기능에 대해 시스템이 이미 휴면 상태의 메커니즘을 포함하고 있다고 주장합니다(플래그가 있거나, 주석 처리된 블록이 있거나, 이름이 정확히 일치하는 함수가 있는 식입니다). 그리고 제안의 핵심은 본질적으로 "이미 거기에 있으니, 그냥 켜기만 하면 됩니다"라는 것입니다. 그럴듯해 보입니다. 심볼(Symbol)은 존재하며, 게으른 검사(코드에 해당 이름이 나타나는가?)를 통과합니다. 하지만 이름 일치를 증거로 받아들이기를 거부하는 게이트(Gate)를 열어보면, 올바른 이름을 가진 코드가 전혀 관련 없는 일을 하고 있음을 발견하게 됩니다. 즉, 그 코드는 주장된 내용과는 다른 레이어(Layer)에서 다른 리소스(Resource)를 보호하고 있는 것입니다. 이름은 맞지만 대상은 틀렸으며, 전체 작업 흐름(Workstream)이 그것을 기반으로 구축될 뻔한 상황입니다. 모든 주장에 대해 인용(Citation)을 강제하고 문맥 속에서 다시 읽어보면, 실패하는 것들은 거의 황당한 발명품이 아닙니다. 그것들은 '시스템의 다른 부분'에 대해서는 우연히 사실인, 그럴듯한 주장들입니다.
따라서 컴파일 대상으로서의 명세(spec-as-compile-target)가 갖춰야 할 첫 번째 요소는 컴파일러의 핵심 동작, 즉 **검증되지 않은 주장의 입입을 거부하는 차단 게이트(blocking gate)**입니다. 단순히 알아차릴 수도 있는 리뷰어가 아닙니다. 증거를 요구하는 게이트입니다. grep으로 찾아내거나, 파일과 줄 번호를 인용하지 않으면 그 주장은 명세에 들어올 수 없습니다. 저는 이에 대해 별도의 글을 할애할 예정입니다. 여기에는 미검증 주장의 *누출률(leak rate)*을 실제로 측정했을 때 어떤 모습인지, 그리고 왜 흥미로운 실패들이 거짓말이 아니라 계층 혼동(layer confusion) — 즉, 사실이긴 하지만 시스템의 잘못된 계층에 대한 사실인 경우인지에 대해서도 다룰 것입니다.
아무도 서 있지 않은 방
여기 불편하지만, 제 생각에는 방어 가능한 주장이 하나 있습니다. 제가 살펴보니, 거의 모든 이들이 컴파일러를 한 층 낮은 곳에 구축하고 있다는 점입니다.
명세 주도 개발(spec-driven-development) 운동은 이제 실재합니다. GitHub의 Spec Kit, AWS의 Kiro, Tessl — 누가 무엇을 점유하고 있는지에 대한 신뢰할 만한 지도가 있으며, 이는 읽어볼 가치가 있습니다. 그들 중 일부는 심지어 *명세 계층(spec layer)*에 게이트를 두고 있는데, 이는 제가 조사하러 갔을 때 기대했던 것보다 더 높은 수준입니다. Kiro는 요구사항에서 설계, 작업으로 이어지는 과정을 안내하며 진행 과정에서 요구사항 문서를 체크합니다. Spec Kit은 생성하기 전에 검증해야 하는 '검토 및 수락 체크리스트(Review & Acceptance Checklist)'를 제공합니다.
따라서 방이 비어 있는 것은 아닙니다. 하지만 그 게이트들이 무엇을 체크하는지를 보십시오. 그것이 핵심이기 때문입니다. Kiro의 명세 게이트는 모호성, 내부 불일치, 불완전성, 잘못된 상세 수준을 표시합니다. Spec Kit의 체크리스트는 명세가 완전하고 형식이 잘 갖춰져 있는지 묻습니다. 이것들은 실제적이고 유용한 체크 사항들이며, 그들 모두는 일관성(coherence) 체크입니다. 문서가 자기 일관성을 유지하는가? 완전한가? 스스로 모순되지는 않는가? 를 묻는 것입니다.
그 중 어느 것도 다른 질문, 즉 **'이것이 사실인가?(is it true?)'**를 묻지 않습니다. "API가 이미 이 필드를 반환한다"라는 명제가 실제 API와 접촉했을 때도 유효할까요? 이 도구들 중 그 어떤 것도 명세(spec)가 주장하는 현실에 대한 내용이 생성되기 *전(before)*에 실제 코드베이스와 대조하여 근거를 확인(grounding)하지 않습니다. Spec Kit의 현실 검증(reality check)은 구현 *후(after)*에 실행됩니다. 즉, 구축된 코드를 다시 명세와 비교하는 것인데, 이는 좋은 방법이지만 제가 설명하고 있는 것과는 정반대의 작업입니다. 소스 코드와 대조하여 검증하는 근거 확인(grounding) 연구(차단 게이트, 타입화된 증거, 기계적 인용 확인 등을 포함한 2026년 논문들)는 요구사항(requirements)이 아니라, 코드와 검색된 청크(retrieved chunks) 단계에서 한 단계 아래 층에서 작동합니다. 디자인 시스템(design-system) 도구는 *구현(implementation)*을 실제 컴포넌트에 근거하게 만듭니다. 렌더 오라클(render oracles)은 *출력(output)*을 판단합니다.
그곳이 바로 실제로 비어 있는 영역이며, 이는 "아무도 명세 게이트(spec gate)를 가지고 있지 않다"라는 말보다 더 날카로운 지적입니다. 명세 계층(spec layer)에 도달한 모든 이들은 **일관성 오라클(coherence oracle)**을 구축했습니다. 하지만 명세를 위한 **진실 오라클(truth oracle)**을 구축한 사람은 거의 없습니다. 즉, 기존 시스템에 대한 명세의 주장이 거짓이기 때문에 요구사항을 거부하는 게이트 말입니다. "모호할 때"가 아니라 "거짓말을 할 때" 나의 명세를 거부하는 것입니다. 일관성(coherence)과 진실(truth) 사이의 이 구분은 이 시리즈 전체의 중추가 될 것이며, 다음 글에서 이를 명시적으로 다루겠습니다.
왜 그 영역이 비어 있는지에 대해 솔직해지고 싶습니다. 왜냐하면 듣기 좋은 설명은 틀린 설명이기도 하기 때문입니다. 그 영역이 비어 있는 이유는 저만이 발견한 영리한 틈새시장이라서가 아닙니다. 그 영역이 비어 있는 이유는 아직 **초기 단계(early)**이기 때문입니다. 그것이 요구하는 하이브리드 인재, 즉 무엇을 만들지 결정하면서 동시에 그 결정에 대한 검증을 설계할 수 있는 사람은 희귀하며, 업계 전체의 관심은 방금 쉬워진 영역인 구현(implementation)의 자동화에 쏠려 있습니다. 제 생각에 이것은 일시적인 현상일 것입니다. 제 논리 또한 이를 예측합니다. 구현이 자동화됨에 따라 모든 시니어(senior)들은 명세 계층으로 밀려 올라갈 것이며, 그들은 정확히 이러한 도구들을 필요로 하며 도착하게 될 것입니다. 이 시리즈는 대중이 도착하기 전, 그 방 안에서 작성된 플레이북(playbook)입니다.
그것은 확신이 아니라 하나의 내기입니다. "초기(Early)"는 "리스크(risk)"의 동의어입니다. 오늘날 명세 컴파일러(spec compiler)가 필요한 청중은 적으며, 공정한 독자라면 이것이 그저 거창한 프레임(framing)을 씌운 훌륭한 엔지니어링 위생(engineering hygiene)일 뿐이라고 말할 것입니다. 그럴지도 모릅니다. 저는 지금 당신이 곧 올라서게 될 디딤돌 위에 서 있을, 6개월 뒤의 당신을 위해 이 글을 쓰고 있습니다.
시리즈: 지도가 아닌 영토
제가 구축한 것은 실제로 다음과 같은 일을 수행하는 파이프라인입니다: 프로덕션 코드베이스(production codebase)에서 매일 사용되는 명세(specification)를 위한 컴파일러입니다. 저는 **지도(map)**를 공유할 것입니다: 프레임워크(frameworks), 어휘(vocabulary), 패턴(patterns), 추론(reasoning), 그리고 정직한 수치들 말입니다. 하지만 **영토(territory)**는 제가 간직하겠습니다: 실제 프롬프트(prompts), 하네스 배선(harness wiring), 축적된 규칙들, 그리고 데이터셋(datasets)입니다. 지도는 당신을 이 아이디어로 끌어들이는 역할을 합니다. 영토는 어차피 블로그 포스트를 복사해 간다고 해서 얻을 수 없는 부분입니다.
앞으로 다룰 내용은 다음과 같습니다:
-
오라클 렌즈 (The Oracle Lens). 게이트(gate)를 구축하기 전에, 그것이 어떤 종류의 진실을 검증할 수 있는지 알아야 합니다. 저는 검증 오라클(verification oracles)을 세 가지 축으로 나눕니다: 진실성 (Truth) (이것이 현실에 근거하고 있는가), 일관성 (Coherence) (이것이 내부적으로 일관된가), 그리고 의도 (Intent) (이것이 실제로 원했던 것인가). 이들은 서로 직교(orthogonal)하며, 그렇기에 명세가 근거(grounding)를 통과하더라도 여전히 잘못된 결과일 수 있는 것입니다.
-
명세의 근거 설정 (Grounding the spec). 위에서 언급한 차단 게이트(blocking gate)에 대한 상세 내용: 증거가 없으면 인정하지 않음(evidence-or-it-doesn't-count), 누출률(leak-rate) 지표, 그리고 진짜 적으로서의 레이어 혼동(layer confusion).
-
태스크가 아닌 계약 (Contracts, Not Tasks). 어떤 에이전트(agent)를 사용하느냐보다 어떻게 에이전트에게 일을 전달하느냐가 더 중요하며, 그 밑바탕에 깔린 원칙은 다음과 같습니다: 분해 입도(decomposition granularity)는 수락 게이트(acceptance gate)의 강도와 반비례하여 확장되어야 합니다.
이 이면에는 더 많은 내용이 있습니다. 왜 이 모든 것이 시간이 지남에 따라 복합적으로 작용하는지, 어떤 기계도 검증할 수 없는 단 하나의 축에 대해서는 어떻게 해야 하는지, 그리고 제 자신의 파이프라인 (pipeline)을 측정하며 얻은 솔직한 수치들에 대한 이야기입니다. 시리즈를 통해 이를 다룰 예정입니다. 하지만 그 시작은 프레임 재구성 (reframe)에서 시작될 것입니다. 왜냐하면 그것이 다른 모든 것을 재조직하기 때문입니다: 구현 (implementation)은 결코 어려운 부분이 아니었습니다. 그것을 컴파일 (compile)할 수 있을 만큼 충분히 정밀하게 진실을 기술하는 것 — 그것이 이제 우리의 과업입니다. 그것을 위한 컴파일러 (compiler)를 구축하십시오.
다음: The Oracle Lens — 게이트 (gate)가 검증할 수 있는 세 가지 종류의 진실과, 검증할 수 없는 단 하나의 진실.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기