27P by GN⁺ 12시간전 | ★ favorite | 댓글 4개
  • 에이전틱 코딩이면 "명세 문서로 코드를 대체할 수 있다"는 주장에 대해, 명세가 충분히 정밀해지면 결국 코드와 동일한 형태로 수렴할 수밖에 없다는 근본적 한계 지적
  • OpenAI의 Symphony 프로젝트를 보면, 해당 SPEC.md가 명세가 아니라 사실상 마크다운 형식의 의사코드
  • 실제로 Symphony 명세를 기반으로 Haskell 구현을 시도한 결과, 다수의 버그와 에이전트 무한 대기 등 신뢰성 문제 발생
  • 명세 작업은 원래 코딩보다 더 깊은 사고를 요구하지만, 현재 업계의 속도 최적화 풍조 속에서 AI가 생성한 저품질 명세가 양산되는 구조
  • "garbage in, garbage out" 원칙은 코딩 에이전트에도 그대로 적용되며, 명확성과 디테일이 결여된 문서로는 신뢰할 수 있는 코드 생성이 불가능

에이전틱 코딩의 두 가지 오해

  • 에이전틱 코딩 옹호자들이 기대는 두 가지 핵심 오해 존재
    • 오해 1: 명세 문서는 대응하는 코드보다 단순하다 — 엔지니어를 명세 문서를 작성하는 관리자로 전환하고, 에이전트 팀에 작업을 위임할 수 있다는 아웃소싱적 시각
    • 오해 2: 명세 작업은 코딩 작업보다 반드시 더 사려 깊다 — 명세 문서를 거치면 품질이 향상되고 더 나은 엔지니어링 관행이 촉진된다는 주장

명세인 척하는 코드: Symphony 사례 분석

  • OpenAI의 Symphony 프로젝트는 명세 문서(SPEC.md)로부터 생성된 에이전트 오케스트레이터로 소개되지만, 실제 SPEC.md의 내용은 명세보다 마크다운 형식의 의사코드에 가까움
  • SPEC.md에 포함된 내용 유형:
    • 데이터베이스 스키마의 산문체 덤프session_id, thread_id, codex_input_tokens 등 필드 나열
    • 코드의 산문체 변환 — 동시성 제어의 available_slots = max(max_concurrent_agents - running_count, 0) 같은 수식, 재시도 백오프 공식(delay = min(10000 * 2^(attempt-1), agent.max_retry_backoff_ms)) 등
    • 모델의 코드 생성을 돕기 위해 명시적으로 추가된 "Config Fields Summary (Cheat Sheet)" 같은 중복 섹션
    • start_service() 함수처럼 사실상 코드 그 자체인 "Reference Algorithms" 섹션
  • 명세 문서가 코드의 대체물이라고 주장하면서 정작 그 문서가 코드처럼 읽히는 것은 기만적
  • 명세 문서를 충분히 정밀하게 만들려면 필연적으로 코드 형태로 변형시키거나, 고도로 구조화된 형식적 영어로 작성해야 함

Dijkstra의 "좁은 인터페이스" 논거

  • Dijkstra의 글을 인용, 인터페이스 선택이 단순한 노동 분배가 아니며 인터페이스를 넘는 협업과 소통의 비용이 추가됨
  • 그리스 수학이 언어적·시각적 활동에 머물러 정체되었고, 이슬람 대수학이 수사학적 스타일로 회귀하며 쇠퇴했으며, 서양 유럽이 중세 스콜라주의의 "헛된 언어적 정밀성 시도"에서 벗어나 Vieta, Descartes, Leibniz, Boole 등의 형식적 기호 체계 덕분에 발전한 역사적 사례 제시
  • 에이전틱 코더들은 엔지니어링 노동이 요구하는 "좁은 인터페이스"(= 코드) 를 피할 수 없으며, 그 노동을 표면적으로 다르게 보이지만 동일한 정밀성을 요구하는 형태로 변환할 수 있을 뿐

불안정성: 명세 기반 코드 생성의 신뢰성 문제

  • Symphony README가 권장하는 대로 Claude Code에 Haskell로 구현을 요청한 결과, 작동하지 않음
    • 다수의 버그 발생, 프롬프트를 통한 수정 필요 (커밋 히스토리에서 확인 가능)
    • 에러 메시지 없이 "작동"하는 경우에도 codex 에이전트가 간단한 Linear 티켓("빈 git 리포지토리 생성")에 대해 아무 진전 없이 무한 대기
  • Dijkstra의 표현을 빌려 Symphony의 "헛된 언어적 정밀성 시도"가 여전히 신뢰할 수 있는 구현 생성에 실패함을 확인
  • 이 문제는 Symphony에 국한되지 않음 — YAML 명세처럼 극도로 상세하고 널리 사용되며 적합성 테스트 스위트까지 갖춘 명세도, 대다수 YAML 구현이 스펙을 완전히 준수하지 못함
  • Symphony의 명세는 이미 포함된 Elixir 구현의 1/6 크기에 달하며, 더 확장하면 Borges의 "과학의 정확성에 관하여" — 제국과 동일한 크기의 지도를 만들어 결국 쓸모없게 된다는 우화 — 와 같은 상황에 도달
  • "더 주류 언어로 생성하면 결과가 좋을 것"이라는 반론에 대해, 에이전트가 Haskell 코드 생성에 어려움을 겪는다면 이는 훈련 데이터 너머로의 일반화 능력 부족을 시사

슬롭(Slop): AI 생성 명세의 품질 문제

  • 명세 작업은 원래 코딩보다 더 어려워야 하며, 코딩 시작 전 프로젝트를 숙고적·비판적 관점에서 바라보도록 유도하는 것이 목적
  • 하지만 기술 기업에서 노동을 축소·평가절하하려는 업계 흐름 속에서, "명세 작업이 코딩보다 쉽다"는 전제로 출발하면 실패가 예정됨
  • 납품 속도 최적화를 추구하면서 명세 작성이 요구하는 어렵고 불편한 작업을 수행하는 것은 불가능
  • Symphony SPEC.md의 Section 10.5(linear_graphql extension contract)가 대표적 슬롭 사례 — "명세처럼 보이는" 문장들의 일관성·목적·큰 그림 이해가 결여된 에이전트 산출물 형태
    • query는 비어있지 않은 문자열이어야 한다, 정확히 하나의 GraphQL 연산을 포함해야 한다 등 개별 규칙이 나열되지만 전체적 맥락이 부재
  • 이런 명세 문서는 인간이 작성했더라도 필연적으로 슬롭일 수밖에 없음 — 일관성이나 명확성이 아닌 납품 시간에 최적화했기 때문
  • 코드 스니펫이 구문 하이라이팅 없이 text로 주석 처리된 점도 AI 생성 문서의 징후 — 모델이 요청의 취지가 아닌 문자 그대로를 따른 결과로 추정

결론

  • 명세는 원래 시간 절약 장치로 설계된 것이 아님
  • 납품 시간 최적화가 목적이라면, 중간 명세 문서를 거치는 것보다 코드를 직접 작성하는 것이 유리
  • "garbage in, garbage out" 원칙이 그대로 적용 — 명확성과 디테일이 부족한 문서를 입력하면, 코딩 에이전트가 그 부족분을 신뢰성 있게 채워줄 수 있는 세계는 존재하지 않음
  • 코딩 에이전트는 마음을 읽는 존재가 아니며, 설령 그렇다 하더라도 사고 자체가 혼란스러우면 할 수 있는 것이 없음

모델 주도 개발 때랑 똑같은 거 같네요.

C 임베디드 개발자로서 Feature/Subfeature에 대해서 거의 모든 흐름을 chart로 확인하게 명세를 만든다음

명세를 길게 검토하고 최종확정뒤
명세와 완전히 1대1 대응되는 코드를 생성해서 사용하네요.
명세로 검토하면 코드검토보다 가독성이 월등히 좋아서요.

파이썬 or 자바스크립트 기반 솔루션은 세부 명세 문서 만으로 만족스런 구현이 가능한가 보네요. C/C++ 기반 게임/의료 쪽인데 FULL AI AGENT 위임은 커녕, 세부 명세 문서 만으로 자동화 시키는것은 너무 모험이라는 생각이 많이 드는 요즘.

Hacker News 의견들
  • 명확하지 않은 문서를 넣어도 코딩 에이전트가 세부사항을 채워줄 수 없다는 말에는 동의하지 않음
    LLM은 본질적으로 언어 보간/외삽 기계로, 부족한 세부사항을 채워 넣는 데 매우 능함
    짧고 간결한 설명만으로도 작동하는 코드를 만들어내는 사례가 많음
    다만, 이런 세부 보완이 항상 정확한 것은 아니며, 신뢰성을 확보하려면 중요한 부분을 명시적으로 제약해야 함
    현재는 코드 작성 문화는 있지만, 초정밀 명세를 작성하는 문화는 NASA 같은 곳을 제외하면 거의 없음

    • LLM이 짧은 설명으로 코드를 만들 수는 있지만 신뢰성 있게 만드는 건 아님
      코드가 짧고 흔할수록 잘 작동하지만, 복잡한 설명에서는 쉽게 무너짐
      결국 “세부 보완이 틀릴 수 있다”고 인정하는 건, 신뢰성 있는 생성이 어렵다는 뜻임
    • 사실 우리는 이미 그런 정밀 명세 언어를 가지고 있음
      예를 들어 Synquid 같은 프로그램 합성 언어가 있음
      수학적으로 정확한 명세가 프로그램 생성에 어떤 한계를 가지는지 보여줌
      specification gap이라 불리는 문제, 즉 프로그램이 명세를 충실히 구현했는지 증명하는 게 핵심 과제임
      자연어는 너무 모호해서 프로그램을 정의하기엔 부적절함
      LLM이 plausible한 세부를 채운다고 해서 이 간극을 해결하는 건 아님
      수학적 명세 언어는 정밀하지만 학습 곡선이 높고, 단순히 마크다운으로 프롬프트를 쓰는 것보다 훨씬 어렵고 노동집약적임
    • “세부 보완이 틀릴 수 있다”고 말한 건, 스스로의 주장을 부정한 셈임
    • ChatGPT 5.4 Pro를 써보면, 단순히 “이게 가능한가요?”라고 물었을 때 실제로 동작하는 예시를 만들어줌
      모델이 내 관심사를 기억하거나, 자체 지식으로 빈틈을 채워서 완성된 앱이나 게임, 화이트페이퍼를 만들어냄
      어떤 때는 “정확히 내가 원하던 것”이고, 어떤 때는 “내가 말하던 바로 그 느낌”임
      의미, 맥락, 뉘앙스를 다루는 능력은 인간 이상인 부분도 있음
      AI가 점점 더 영리하고 유능해지고 있음
    • LLM이 만들어내는 건 대부분 보일러플레이트나 이미 알려진 알고리즘의 확장임
      즉, 완전히 새로운 세부사항을 창조하는 게 아니라 학습 데이터에서 끌어오는 것에 가까움
  • “충분히 상세한 명세는 곧 코드다”라는 말에 공감함
    이는 Brooks의 No Silver Bullet 논지와 같음
    하지만 대부분의 사람은 그 정도의 세부사항을 원하지 않음
    “AI에게 투두 앱을 만들어줘”라고 하면, 사실상 “내가 상상한 것보다 나은 앱을 만들어줘”라는 뜻임

    • 이건 학습 데이터에 이미 수많은 to-do 앱이 있기 때문임
      하지만 이런 접근은 다른 종류의 소프트웨어에는 잘 확장되지 않음
    • 진짜로 앱을 만들고 싶다면, 기존 앱과 다른 점을 설명해야 함
      결국 그 차별점을 명세로 표현해야 함
    • 웹 프론트엔드처럼 시각적이고 구체적인 영역은 명세가 곧 코드에 가까움
      하지만 데이터베이스, 파일시스템, 병렬 계산처럼 정확성과 성능이 중요한 영역은 명세보다 구현이 훨씬 어려움
      이런 곳에서 AI가 형식 검증을 통과하는 코드를 만드는 건 큰 도전임
    • “더 나은 앱”이란 게 무엇인지 정의하려면 결국 명세(spec) 가 필요함
    • 상업적으로 판매할 앱이라면 명세는 필수임
      돈을 벌거나 경쟁하려면 구체적인 요구사항이 필요함
  • vibe coding을 정보이론 관점에서 보면, 작은 프롬프트 공간에서 유용한 프로그램 공간을 복원하는 디코더가 존재한다는 가정임
    이때 압축비가 바로 vibe coding의 이득임
    “IRC 채널 기반 팀 커뮤니케이션 앱” 같은 프롬프트는 Slack을 모르면 해독 불가능함
    따라서 무엇이 빠져 있는가를 인식하는 게 중요함
    효과적으로 AI 코딩을 하려면, 짧은 단위로 프롬프트를 나누고, 기존 문서나 시도한 코드 등을 함께 제공해야 함

    • 이건 사실상 알고리즘 정보이론과 동일함
      Algorithmic Information Theory에 따르면, 문자열의 정보량은 가장 압축된 자기완결적 표현의 길이와 같음
      다만 “자기완결적”이라는 조건은 모델의 가중치가 코드북 역할을 할 때만 성립함
    • “작은 프롬프트로 프로그램을 복원할 수 있다”는 개념이 너무 마음에 듦
      인간은 LLM보다 훨씬 많은 공유 맥락을 가정하기 때문에, 디코더의 한계를 과대평가함
      하지만 강한 제약과 명확한 강조점을 가진 시스템이라면 vibe coding의 압축비를 폭발적으로 높일 수 있을 것 같음
    • 간결함만의 문제가 아님
      자연어는 프로그래밍 언어보다 접근성이 낮은 사람들에게 새로운 인터페이스를 제공함
      LLM이 대신 생각해주는 건 아니지만, 아이디어를 작동하는 시스템으로 바꾸는 새로운 통로를 열어줌
  • 곧 사람들은 모델 성능과 토큰 효율을 위해 LLMSpeak 같은 기술 영어 방언을 만들 것 같음
    모호성을 줄이고, 토큰을 절약하며, 복잡한 개념을 단어 하나로 압축하는 식임
    문법적으로도 Oxford comma 같은 규칙이 생겨서 명확성을 높일 듯함

    • 그건 결국 프로그래밍 언어를 재발명하는 것과 같음
      그렇게 세밀하게 명세할 거면 굳이 프롬프트를 쓸 이유가 없음
    • 하지만 모델이 그 방언으로 학습되지 않았다면, 매번 그 정의를 함께 보내야 함
      결국 인간 언어로 다시 정의해야 하므로 토큰 절약 효과는 제한적임
    • 차라리 Lojban 같은 비모호 언어를 쓰자는 제안도 있음
      Lojban 위키, Lojban 화자 영상 참고
    • 인간 언어는 이미 대부분의 아이디어를 전달하는 데 충분히 효율적임
      인공 방언 시도는 Esperanto처럼 실패할 가능성이 큼
    • LLM이 이런 방언으로 학습되지 않았다면, 결국 모호한 인간 언어를 해석하는 능력이 더 중요함
      이런 언어는 오히려 LLM끼리 쓸 때 유용할 수 있음
      이미 프로그래밍 언어가 그런 역할을 하고 있음
  • 명세(spec)는 해당 조건을 만족하는 모든 프로그램을 포함하는 봉투(envelope) 같은 것임
    이 봉투를 만드는 게 단일 프로그램을 작성하는 것보다 더 어려움
    LLM이 매번 다른 코드를 생성하듯, 명세는 좋은 구현과 나쁜 구현 모두를 허용함
    실제로는 한 구현이 채택되면 그게 다음 버전의 사실상 명세가 됨
    기존 코드가 있는 환경(brownfield) 에서는 명세가 깨끗하지 않기 때문에 LLM이 잘 대응하기 어려움

    • 20년 경력 후 명세를 쓰기 시작했을 때, 왜 코딩보다 어려운지 깨달음
      명세 한 줄이 다른 줄과 어떻게 상호작용할지 고려해야 하는 조합 폭발이 있음
      하지만 컴파일러 입장에서는 코드도 명세일 뿐임
      결국 “코드가 명세보다 쉽다”는 건 상대적인 이야기임
    • 두 프로그램이 같은 명세를 만족해도 보안 특성은 완전히 다를 수 있음
      “사용자 자격 증명을 저장한다”는 명세는 bcrypt부터 평문 쿠키까지 포함함
      인간은 “그건 하면 안 돼”라는 본능이 있지만, 에이전트는 명시하지 않으면 모름
      따라서 보안을 확보하려면 하지 말아야 할 것까지 명세해야 함
    • 좋은 명세는 “무엇을 할지”만 정의하고 “어떻게 할지”는 정의하지 않음
      성능이나 보안이 중요하다면 그 속성을 명시해야 함
      예를 들어 “이 프로그램은 O(n)이어야 함” 같은 문장은 구현보다 훨씬 간단함
  • 사람마다 spec의 의미를 다르게 쓰는 듯함
    내게 spec은 “무엇을 할지(what)”를 정의하고, plan은 “어떻게(how)”를, build packet은 “세부 단계”를 의미함
    대부분의 경우 중요한 건 “무엇을”임
    데이터가 A에서 B로, C를 거쳐 D에 보존되고 E에서 F 형태로 표현된다는 걸 명세로 쓰는 게, Rust 코드로 구현하는 것보다 훨씬 쉬움

  • “에이전트형 엔지니어링”을 해보면, 명세 문서가 코드보다 길어지는 경우가 많음
    자연어는 불완전하지만 코드는 정확함
    명세의 목적은 여러 차례 반복 개발에서도 기능을 유지하는 것임
    테스트나 주석보다 워터폴식 설계 문서가 더 효과적이었음
    이런 방식으로 완전한 vibe coding 프로젝트를 리팩터링하거나 언어를 바꾸는 작업도 매끄럽게 진행했음
    지금은 마치 70~80년대 개발 흐름으로 돌아간 느낌임

    • 테스트로도 가능하겠지만, 에이전트에게 테스트 수정을 맡기면 테스트 자체를 고쳐버릴 위험이 있음
    • 자연어 명세가 항상 코드보다 길 필요는 없음
      “TCP 인터페이스를 구현하라” 같은 문장은 실제 코드보다 훨씬 짧음
      결국 명확한 스키마로 매핑할 수 있다면 자연어도 충분히 압축적일 수 있음
  • Spec → LLM 방향은 비효율적이고 낭비적임
    오히려 LLM → Spec이 더 현실적임
    명세가 컴파일 가능한 형태로 존재하면, LLM이 그 피드백을 받아 더 나은 코드를 생성할 수 있음
    “검증된 영어(validated English)”를 만들려는 시도는 오히려 복잡성을 늘림
    결국 중요한 건 실제로 동작하는 코드임

  • 코드는 명세보다 훨씬 많은 걸 담고 있음
    대부분의 프로젝트는 90%가 프레임워크나 인프라 코드, 10%만이 비즈니스 로직임
    명세는 언어나 프레임워크 세부사항을 다루지 않기 때문에 훨씬 간결함

    • 하지만 진짜로 문제를 해결하는 코드는 비즈니스 로직만 남기고 나머지를 추상화해야 함
      이렇게 하면 명세와 거의 동일한 수준의 코드가 만들어짐
      도메인 전문가도 읽을 수 있고 테스트도 쉬움
    • 예를 들어 MySQL을 Postgres로 바꿔도 명세는 그대로 유지됨
      하지만 실제 코드는 꽤 많이 바뀜
  • 명세를 관리 도구로 보는 시각과 엔지니어링 도구로 보는 시각의 충돌이 인지 부조화를 만듦
    관리자는 명세를 위임 티켓으로 보지만, 개발자는 사고를 정제하는 생각의 도구로 사용함
    일부 개발자는 편의상 관리자의 사고방식으로 시작하지만, 곧 깨닫게 됨

    • 아무리 관리해도 결국 직접 빌드해야 함
      하이프나 투자 미팅으로는 잠시 버틸 수 있지만, 결국 사용자는 실제 제품을 원함