설계 문서는 왜 2026년에 다시 화제가 되었나 — 「효과적인 소프트웨어 설계 문서 쓰는 법」 완전 해부
6월에 나왔을 때는 아무도 안 봤던 글이 9월 14일 해커뉴스 1면에 올라 334점과 137개의 댓글을 받았다. 구글과 마이크로소프트에서 설계 문서를 배운 한 창업자가 쓴 「효과적인 소프트웨어 설계 문서 쓰는 법」이다. 이 특집은 그 글의 24개 구성 요소를 하나씩 뜯고, 1969년 욕실에서 쓰인 첫 RFC부터 아마존의 6페이지 메모와 구글의 설계 문서까지 이 관습이 어디서 왔는지 찾고, 원문의 캐시 아키텍처 예시를 숫자로 재현하고, 코드가 싸진 2026년에 사람이 여전히 써야 하는 문서가 무엇인지 따진다. 인터랙티브 위젯 5종과 삽화를 함께 싣는다.
2026년 6월 24일, 마이클 린치(Michael Lynch)가 「How to Write an Effective Software Design Document」라는 글을 올렸다. 그가 쓰고 있는 책 『Refactoring English: 소프트웨어 개발자를 위한 효과적인 글쓰기』의 한 장을 발췌한 것이다. 같은 날 해커뉴스에 올라갔지만 4점에 댓글 8개로 끝났다. 이틀 뒤 누가 다시 올렸고, 사흘 뒤 또 올렸고, 7월에도 올렸다. 모두 1~10점 사이에서 사라졌다. Lobsters에서만 39점을 받고 "팀 전체에 공유하겠다"는 댓글이 달렸다.
그리고 9월 14일. 같은 URL이 여덟 번째로 올라갔고 이번에는 1면에 갔다. 하루 만에 334점, 댓글 137개. 저자가 직접 들어와 스무 개 넘는 답글을 달았다.
무엇이 달라졌을까. 글은 한 글자도 바뀌지 않았다. 바뀐 것은 댓글의 첫 질문이었다.
"에이전트 시대에 설계 문서는 어떻게 바뀌고 있나요?"
그 아래에 이 토론 전체를 요약하는 응수가 붙었다. 한 사용자가 "잘 지시만 하면 Fable(앤트로픽의 최신 모델)이 소프트웨어 엔지니어의 80%보다 낫다. 왜 아직도 팀과 설계를 검토해야 하나?"라고 물었고, 저자는 "LLM은 아직 복잡도를 줄이는 데 사람보다 못하다"고 답했다. 코드가 싸진 시대에 사람이 여전히 써야 하는 문서가 있는가. 이 질문이 석 달 묵은 글을 1면에 올렸다.
이 특집은 네 가지를 한다. 첫째, 원문을 처음부터 끝까지 읽고 24개 구성 요소를 하나씩 뜯는다. 둘째, 이 관습이 어디서 왔는지 1969년의 욕실에서 시작해 구글과 아마존까지 57년을 훑는다. 셋째, 원문이 든 캐시 아키텍처 예시를 실제 숫자로 재현하며 인터페이스·SLO·열린 이슈 같은 낯선 용어를 풀어낸다. 넷째, 해커뉴스 137개 댓글의 논쟁과 저자 자신이 올해 3월에 한 실험(사람이 쓴 설계 문서와 AI가 쓴 설계 문서를 독자가 구별할 수 있는가)을 통해 2026년에 이 문서의 역할이 무엇인지 따진다.
🧭
이 글의 지도
1장 — 저자는 누구이고, 원문은 무엇을 주장하나
2장 — 핵심 개념: "틀렸을 때의 벌칙"이라는 단 하나의 기준
3장 — 24개 구성 요소 해부 (탐색기 위젯)
4장 — 아키텍처 읽기: RecencyBank 캐시와 인터페이스 절 (시뮬레이터 위젯)
5장 — 리뷰 편: 역피라미드, 리뷰어 한 명, 댓글 스레드를 죽이는 법
6장 — 실제 문서 한 편: Little Moments
7장 — 역사: 1969년 욕실에서 2020년 구글까지 (연대기 위젯)
8장 — 해커뉴스 137개 댓글의 논쟁
9장 — 2026년: 사양 주도 개발과 "어느 문서를 사람이 썼나"
10장 — 이번 주에 해볼 일
1. 저자와 원문
마이클 린치는 2000년대 후반 마이크로소프트에서 첫 직장을 시작했고, 이후 구글에서 일하다 2018년에 그만두고 1인 창업의 길로 갔다. 라즈베리파이 기반의 원격 KVM 장치 TinyPilot을 만들어 연매출 100만 달러까지 키운 뒤 2024년에 매각했고, 그 과정을 매달 공개 회고로 써서 개발자 사회에서 잘 알려졌다. 지금은 개발자를 위한 글쓰기 책을 킥스타터로 쓰고 있다.
그가 원문 첫머리에서 밝힌 동기는 이렇다.
"설계 문서에 대해 가장 많이 받는 질문은 '좋은 설계 문서를 어디서 볼 수 있느냐'입니다. 저는 공개된 설계 문서 중 수준 높다고 생각하는 것을 본 적이 없습니다. 제가 쓴 것은 전부 저에게 돈을 준 회사들 안에 숨어 있습니다."
해커뉴스 댓글에서 그는 이렇게 덧붙였다. "마이크로소프트와 구글에서 설계 문서를 배웠는데, 두 회사 다 문서 문화가 좋았지만 그 문화가 다른 엔지니어링 관행만큼 바깥으로 퍼지지 못했다고 생각한다. 설계 문서 쓰는 법을 제대로 설명한 글을 본 적이 없어서 내가 배운 것을 밖으로 꺼내 보려 한 것이다."
원문의 주장은 첫 문단에 다 들어 있다.
"좋은 설계 문서는 몇 년의 개발 시간을 아껴 줄 수 있습니다. 설계 문서를 쓰면 잘못된 구현에 시간을 낭비하기 전에 중요한 결정을 깊이 생각하게 됩니다. 팀원과 협력 팀 사이에서 설계 결정을 조율하는 가장 좋은 방법이기도 합니다."
두 문장에 두 가지 기능이 있다. 생각을 강제하는 것과 조율하는 것. 이 두 기능이 뒤에서 벌어질 모든 논쟁의 축이다. AI가 문서를 대신 써 줄 수 있다는 주장은 첫째 기능을 건드리고, 코드가 싸졌으니 문서 대신 여러 구현을 만들어 보자는 주장은 둘째 기능을 건드린다.
언제 쓰나
원문은 여섯 가지 질문을 준다. 여러 사람이 나눠서 구현하나, 풀타임 3개월 넘게 걸리나, 프로덕션에서 몇 년 돌아가나, 다른 팀과 협업하나, 목표가 모호한가, 설계 단계에서 막을 수 있는 치명적 위험이 있나. 하나라도 '예'면 쓸 만하고, 둘 이상이면 "거의 확실히" 쓸 가치가 있다.
그리고 바로 뒤에 이런 문장이 온다. "얼마나 투자할지에 보편적 규칙은 없다. 코드를 얼마나 테스트할지에 규칙이 없는 것과 같다. 가끔은 올바른 투자량이 0이다." 해커뉴스에서 설계 문서를 싫어한다고 말한 사람들 대부분이 이 문장을 읽지 않고 반박했다.
2. 핵심 개념 — "틀렸을 때의 벌칙은 얼마인가"
원문에서 딱 하나만 가져가야 한다면 이것이다. 무엇을 설계 문서에 넣고 무엇을 빼는가를 가르는 질문.
"모든 세부를 설계 문서에 적으면, 설계 단계에서 구현을 다 써 버린 셈입니다. 그러면 설계 문서의 목적 자체가 사라집니다. 어떤 결정이 설계 문서에 들어가야 하는지는 간단한 질문 하나로 정할 수 있습니다. 틀렸을 때의 벌칙이 얼마인가?"
첫째, 웹 애플리케이션을 C++로 만들다가 20만 줄이 쌓인 뒤에야 Ruby on Rails가 나았다는 걸 깨달으면 어떻게 되나. "당신은 갇혔습니다. 처음부터 다시 쓰는 것은 결코 성공하지 못하고, 설령 새 코드를 Rails로 쓴다 해도 완전히 다른 두 언어의 코드를 함께 유지보수해야 합니다." 여기서 그는 조엘 스폴스키가 2000년에 쓴 「절대 하지 말아야 할 것, 1부」를 링크한다. 넷스케이프가 브라우저를 처음부터 다시 쓰기로 한 결정이 회사를 죽였다는 그 유명한 글이다.
둘째, 앱이 글 100개를 보여줄 때 한 번에 다 보여줄지, 25개씩 '더 보기' 버튼으로 나눌지.
"상관없습니다. '더 보기' 버튼은 설계 수준의 관심사가 아닙니다. 하나를 골랐다가 사용자 반응이 나쁘면 몇 시간 안에 고칠 수 있습니다. 당신의 사고 과정을 전부 문서에 적을 필요가 없고, 여기에 리뷰 사이클을 낭비해 논쟁해서는 절대 안 됩니다."
해커뉴스에서 아마존 웹서비스 출신 댓글 작성자가 이 기준에 이름을 붙였다. 아마존에는 결정을 일방향 문과 양방향 문으로 부르는 문화가 있다. 제프 베이조스가 2015년 주주서한에 쓴 말이다.
"어떤 결정은 중대하고 되돌릴 수 없거나 거의 되돌릴 수 없다. 일방향 문이다. 이런 결정은 체계적으로, 신중하게, 천천히, 깊은 숙고와 자문을 거쳐 내려야 한다. 문을 지나 반대편이 마음에 안 들어도 돌아올 수 없기 때문이다. 그러나 대부분의 결정은 그렇지 않다. 바꿀 수 있고 되돌릴 수 있다. 양방향 문이다."
베이조스는 조직이 커질수록 양방향 문에도 일방향 문의 무거운 절차를 쓰는 경향이 생기고, 그 결과가 "느림, 생각 없는 위험 회피, 실험 부족, 그리고 발명의 감소"라고 경고했다. 린치의 "리뷰 사이클을 낭비하지 말라"는 정확히 같은 경고다.
이 기준이 중요한 이유는 설계 문서에 대한 반감 대부분이 여기서 생기기 때문이다. 문서가 비대해지는 것은 양방향 문을 일방향 문처럼 다루기 때문이고, 문서가 쓸모없어지는 것은 일방향 문을 문서 없이 지나기 때문이다. 직접 분류해 보면 감이 온다.
⚠️
2026년의 각주. "처음부터 다시 쓰기는 결코 성공하지 못한다"는 스폴스키의 2000년 명제에 대해 해커뉴스에서 이견이 나왔다. LLM이 언어 간 번역에 뛰어나고, Bun이 Zig에서 Rust로 대규모 이식을 해냈다는 것이다. 린치의 답: "Bun은 LLM 재작성에 가장 우호적인 조건이다. 입출력이 자기완결적이고, 새 구현과 옛 구현을 나란히 테스트하기 쉽고, 제3자 테스트 코퍼스가 거대하다. 그리고 그 재작성이 좋은 결정이었는지는 아직 판정이 안 났다." 일방향 문이 조금 넓어졌을 수는 있다. 그러나 문이 없어진 것은 아니다.
3. 24개 구성 요소 해부
원문의 본론은 설계 문서에 들어갈 수 있는 절 24개를 하나씩 설명하고 각각에 예시를 붙이는 것이다. 예시는 전부 하나의 가상 프로젝트로 통일되어 있다. RecencyBank: Trogdor라는 웹 서버와 Postgres 데이터베이스 사이에 메모리 캐시 층을 끼우는 프로젝트다. (이름부터 원문의 첫 가르침이다. "RecencyBank는 말하기 쉽고 목적을 설명한다. 'Project Flying Silver Horse'는 장황하고 무의미하다.")
24개를 여섯 묶음으로 나누면 읽기 쉽다.
묶음
절
한 줄 요약
머리
제목 · 메타데이터 · 목적 · 배경 · 관련 문서
바깥 설명 없이 첫 페이지만 읽어도 무슨 일인지 알게
무엇을
목표 · 비목표 · 시나리오
범위의 안과 밖, 그리고 완성된 모습의 이야기
어떻게
다이어그램 · 용어집 · 제약 · 인터페이스 · 의존성/인프라
구조와 경계, 바꾸기 어려운 선택들
운영
SLO · 모니터링/알림 · 일정 · 로깅
측정 가능한 숫자와 그것을 확인하는 방법
위험
보안 · 프라이버시 · 법률
출시 뒤에 알면 늦는 것들
꼬리
열린 이슈 · 해결된 이슈 · 검토한 대안 · 리뷰 진행
아직 모르는 것, 결정한 것, 버린 것
전부 넣으라는 말이 아니다. "일반적으로 모든 문서에 모든 절이 필요하지는 않다. 맞는 부분집합을 고르라." 아래 탐색기에서 프로젝트 유형을 바꿔 가며 어떤 절이 살아나고 어떤 절이 흐려지는지 보라.
몇 가지 절은 따로 짚을 가치가 있다.
목표는 구현이 아니라 영향으로
나쁜 목표 (구현 세부)
좋은 목표 (영향)
인프라에 쿠버네티스를 도입한다
새 버전 배포와 관련된 장애를 최소화한다
Redis 캐시를 추가한다
사용자가 체감하는 반응 속도를 높이고 DB 부하를 줄인다
왜 이것이 중요한가. 목표를 구현으로 쓰면 리뷰어가 "쿠버네티스가 정말 최선인가"를 물을 자리가 사라진다. 영향으로 쓰면 "배포 장애를 줄이는 데 쿠버네티스 말고 더 단순한 길은 없나"라는 질문이 자연스럽게 열린다. 검토한 대안 절이 살아나는 것이다.
비목표는 오해를 막는 울타리
"독자가 범위 안이라고 잘못 짐작할 만한 목표가 있는가? 그렇다면 명시적 비목표로 적으라." RecencyBank 예시의 비목표는 두 개다. 범용 재사용 캐시 시스템 만들기(이 캐시는 Trogdor 전용 최적화를 한다), 그리고 사용자 가까운 곳에 두는 지역 기반 캐싱(나중엔 유용할 수 있지만 v1 범위 밖).
해커뉴스에서 한 댓글 작성자는 AI 에이전트와 일할 때 이 절이 가장 중요하다고 썼다. "좋은 설계 문서가 하는 가장 중요한 일은 무엇이 범위 안이고 밖인지 정하는 것이다. 두 번째는 공통 어휘를 정확히 정의하는 것이다. 나는 모든 클로드 세션을 '이 문서를 읽고 세계에 익숙해진 뒤 일하자'로 시작한다." 에이전트는 "지엽적인 것에 빠지거나 반쯤 하고 끝났다고 말하는" 경향이 있어서 범위를 못 박아 주는 문서가 그라운딩 역할을 한다는 것이다.
SLO는 SLA에서 벌금을 뺀 것
서비스 수준 목표(Service Level Objective)라는 용어가 낯선 독자를 위해 원문은 재치 있게 설명한다. "SLA(서비스 수준 협약)는 들어 봤을 것이다. SLA는 SLO에 재정적 벌칙을 더한 것이다. 회사 안에서는 보통 동료의 실수에 벌금을 물리지 않으므로(그러면 좀 재미있긴 하겠지만), 설계 문서는 SLA가 아니라 SLO를 정한다." 해커뉴스 첫 댓글이 바로 이 농담에 대한 반응이었다. "동료의 실수에 벌금을 물리는 게 '재미있지'는 않을 것 같은데요."
농담 뒤의 요점은 진지하다. 관리자가 "모바일에서 성능 좋게"라고 말하면 그 사람 머릿속의 '성능'은 2ms 지연일 수 있고, 당신은 코드를 다 짠 뒤에야 그것을 알게 된다. SLO는 그 모호함을 숫자로 바꾼다. 가용성(몇 %의 시간 동안 살아 있나), 지연(요청을 얼마나 빨리 끝내나), 규모(얼마나 많은 일을 처리하나).
≤200ms
Trogdor 사용자 HTTP 요청 p50 (SLO)
≤80ms
Postgres 쿼리 p50 (SLO)
≥3s
p95가 이 값을 넘으면 온콜 호출 (모니터링)
≥90%
2분 평균 CPU가 이 값을 넘으면 온콜 호출
p50과 p95는 백분위수다. p50은 요청 절반이 그보다 빠르다는 뜻이고, p95는 95%가 그보다 빠르다는 뜻이다. SLO를 중앙값(p50)으로 정하고 알림을 꼬리(p95)로 거는 원문의 구성은 흔한 실무 패턴이다. 평균은 몇 개의 극단값에 끌려가서 목표로도 알림으로도 쓰기 나쁘다.
일정은 "쓸모 있는 산출물"로 자른다
"이해관계자에게 유용한 산출물을 만드는 마일스톤을 고르라. 예를 들어 더미 데이터를 보여주는 UI부터 만들어 고객에게 먼저 보여주라. 고객 요구를 잘못 이해했다면, 가짜 데이터 덕분에 프로덕션 데이터를 채우는 배관을 다 만든 뒤가 아니라 일찍 알게 된다." RecencyBank의 마일스톤 1은 "하드코딩된 캐시 데이터로 테스트 환경에서 가동(Postgres를 읽지 않음)"이다. 캐시 무효화 규칙은 마일스톤 3에야 나온다.
보안·프라이버시·법률은 "없다"고 써도 쓴다
"보안 위협이 있을 법하지 않거나 무관하다고 생각해도, 그 근거를 문서화하는 것이 도움이 된다. 당신의 설명이 리뷰어가 놓친 위협을 찾아내게 할 수 있다." 원문이 묻는 질문은 세 가지다. 어떤 위협을 고려했나(공격자가 모든 비밀번호를 시도하면? 사용자가 악성코드 감염 PDF를 올리면?). 공격 표면은 어디인가(어디서 악의적일 수 있는 데이터를 처리하나). 신뢰 경계는 어디인가(데이터가 덜 신뢰되는 시스템에서 더 신뢰되는 시스템으로 넘어가는 지점. 웹 앱에서 브라우저의 요청은 신뢰 경계를 넘는다).
법률 절의 예시는 이 글에서 가장 현실적인 대목 중 하나다. 가상의 파트너 FizzleCorp와의 계약이 그들의 독점 생체 데이터 복제를 엄격히 제한한다. 캐시는 데이터를 복제하는 것 아닌가? "다행히 법무팀이 계약 문구를 검토해 캐시 층이 기존의 '저장 계층' 정의에 포함된다고 확인했으므로 재협상 없이 캐시할 수 있다." 이런 확인은 출시 후에는 할 수 없다. 설계 단계에서만 할 수 있다.
4. 아키텍처 읽기 — RecencyBank는 실제로 어떻게 생겼나
원문의 '인터페이스' 절은 24개 절 중 유일하게 코드가 나오는 곳이다. 짧지만 소프트웨어 설계의 핵심 기법 하나가 통째로 들어 있어서, 용어가 낯선 독자를 위해 천천히 풀어 보자.
"2023년 Trogdor 웹 앱을 출시했을 때 페이지는 보통 100ms 이하에 로드됐다. 3년이 지나 페이지 로드 중앙값이 600ms로 불어났고, 사용자는 앱이 굼뜨다고 느낀다. 조사해 보니 데이터베이스 조회가 페이지 로드 시간의 80%를 차지했다. 데이터가 커질수록 조회가 느려졌다. 또 데이터베이스 조회의 95%가 같은 3%의 행을 향한다는 것도 발견했다. 이런 사용 패턴은 메모리 기반 캐싱에서 큰 이득을 본다."
여기에 캐시의 존재 이유가 다 있다. 자주 읽히는 데이터가 전체의 3%뿐이고 그것이 조회의 95%를 받는다면, 그 3%를 RAM에 올려 두면 조회 95%가 디스크 기반 데이터베이스를 건드리지 않아도 된다. 캐시 용어로 이 3%를 핫셋(hot set), 캐시에서 답을 찾는 비율을 적중률(hit rate)이라 부른다.
인터페이스 절: 한 줄만 바꾸는 설계
원문의 설계는 우아하다. 현재 Trogdor 서버는 Postgres 구현체에 직접 매달려 있다.
hljs language-go
type Server struct { db PostgresDB }
PostgresDB에는 GetUser(id), ListUsers() 같은 메서드가 있다. 설계는 이렇게 진행된다.
1
인터페이스를 뽑는다.PostgresDB와 똑같은 메서드 목록을 가진 Go 인터페이스 Store를 정의한다. 인터페이스란 "이런 메서드들을 갖고 있으면 누구든 이 자리에 올 수 있다"는 약속이다. 구현이 아니라 계약이다.
2
캐시 타입이 같은 계약을 이행하며 원본을 감싼다.RecencyBank는 Store를 구현하고, 안에 진짜 PostgresDB를 품는다. 읽기 요청은 먼저 자기 메모리를 보고, 있으면 바로 답하고, 없으면 Postgres에 물어본 뒤 답을 기억해 둔다. 쓰기 요청(상태를 바꾸는 것)은 Postgres로 그대로 넘긴다.
3
서버는 멤버 하나의 타입만 바꾼다.type Server struct { db store.Store }. 서버 코드의 나머지는 한 줄도 손대지 않는다. 서버는 자기가 Postgres와 이야기하는지 캐시와 이야기하는지 모른다. 알 필요가 없다.
이 구조에는 이름이 있다. 같은 인터페이스를 구현하면서 원본을 감싸고 앞뒤로 무언가를 덧붙이는 객체를 데코레이터 또는 프록시라 부른다. 캐시가 읽기를 가로채 답하고 쓰기를 통과시키는 방식은 읽기 통과(read-through) 캐시다. 그리고 "서버는 인터페이스에만 의존하고 구현을 모른다"는 원칙이 1972년 파나스가 말한 정보 은닉이다. 7장에서 다시 만난다.
Trogdor 웹 서버 — db store.Store 만 안다
↓ GetUser / ListUsers
RecencyBank — 읽기: 메모리에 있으면 즉답, 없으면 아래에 묻고 기억 · 쓰기: 아래로 통과
↓ 캐시 미스 · 모든 쓰기
PostgresDB — 진실의 원천
원문이 리뷰어에게 보여주는 것은 두 가지다. 변경 범위가 극도로 작다는 것(한 줄), 그리고 캐시를 떼어내는 것도 쉽다는 것(그 한 줄을 되돌리면 된다). 다시 말해 이 설계 자체가 일방향 문을 양방향 문으로 바꾸는 장치다. 캐시 도입이라는 결정을 나중에 되돌릴 수 있게 만들어 두었으니, 문서에서 논쟁할 일이 줄어든다.
의존성 절: 바꾸기 어려운 것만 걱정하라
"언어·라이브러리·인프라 결정은 시스템의 복잡도와 장기 유지보수 비용에 큰 영향을 준다. 구현 후 바꾸기 어려운 의존성을 깊이 생각하라. 쉽게 갈아 끼우는 것은 걱정하지 마라. 언어나 저장 백엔드를 바꾸는 건 어렵지만, 이메일 발송 업체가 마음에 안 들면 오후 한나절이면 바꾼다." RecencyBank는 Go(이미 널리 쓰고 병렬 처리에 적합)와 bbolt(널리 쓰이는 키-값 저장소 구현)를 고른다.
열린 이슈: RAM은 얼마나
이 아키텍처에서 결정이 안 난 것이 하나 남는다. 캐시에 RAM을 얼마나 줄 것인가. 원문의 열린 이슈 예시는 문제·선택지·다음 단계라는 세 요소를 정확히 갖추고 있다.
"RAM을 늘리면 성능이 오르지만 RAM은 비싸고 수확 체감이 있다. 캐시와 데이터베이스 사이 인프라 비용을 최소화하는 최적값이 이론적으로 존재한다. 테스트 환경을 만들어 시뮬레이션을 여러 번 돌리면 찾을 수 있지만, 그 시뮬레이션은 개발자 시간을 쓴다. 테스트 환경 구축과 첫 시뮬레이션에 3.0 개발일, 이후 회당 0.75 개발일로 추정한다.
제안: 테스트 없이 128GB로 간다. 아마 최적값에 가깝고, 개발자 시간이 RAM보다 훨씬 비싸다.
다음 단계: 테크리드에게 의견을 구한다."
그리고 해결된 이슈 절에서 이 항목은 결정 요약 한 줄과 함께 닫힌다. "128GB. 성능 목표에 못 미치고 RAM이 제약이면 그때 추가한다. 완벽한 RAM 크기를 찾는 테스트 비용이 추가 RAM 비용을 훨씬 넘는다." 토론 전문은 그 아래에 그대로 남긴다.
이 판단이 옳았는지 원문의 숫자로 직접 확인해 보자.
다이어그램은 왜 피드백의 절반을 받나
원문에는 다이어그램 절의 예시로 실제 그림 하나가 붙어 있다. 린치가 만든 영화 기록 앱 ScreenJournal의 아키텍처다.
원문의 예시 다이어그램. 단순한 웹 애플리케이션의 아키텍처. 출처: refactoringenglish.com
박스 일곱 개와 화살표 다섯 개짜리 그림이지만 원문이 "다이어그램에 무엇을 넣어야 하나"라고 물은 네 질문에 전부 답하고 있다. 데이터가 어떻게 흐르나(브라우저에서 Go 백엔드로, 백엔드에서 SQLite로, Litestream이 그 SQLite를 Backblaze B2로 복제), 구성 요소가 어떻게 맞물리나(Docker 안에 백엔드와 Litestream, 그 Docker가 fly.io 위에), 의존성과 클라이언트는 무엇인가(외부의 TMDB API), 신뢰 경계는 어디인가(빨간 상자 '웹 브라우저'에서 초록 상자 'fly.io'로 넘어오는 화살표 하나).
동반 글에서 린치는 "설계 문서를 리뷰에 보내면 피드백의 약 50%가 다이어그램에 대한 것이다. 좋은 일이다. 리뷰어들이 색깔이나 도형을 트집 잡는 게 아니라, 다이어그램이 아키텍처와 설계 결정에 대한 지적이고 건설적인 토론을 촉발하기 때문"이라고 썼다. 그리고 실용적 경고 하나. 화이트보드에 멋진 그림을 그려 사진으로 찍어 넣지 마라. "첫 초안은 근사해 보이지만, 그 뒤로는 그 그림에 영원히 갇힌다. 사진은 처음부터 다시 그리지 않고는 못 고친다." Excalidraw, draw.io, Google Drawings, 혹은 Mermaid·D2·Graphviz 같은 코드형 도구를 쓰고 소스를 링크하라.
5. 리뷰 편 — 문서를 쓴 다음에 벌어지는 일
원문은 마지막 절에서 동반 글 「설계 문서에 의미 있는 피드백 받는 법」(2025년 11월)으로 넘긴다. 해커뉴스에서 "링크된 글이 오히려 더 유용했다"는 댓글이 여럿 나왔으므로 함께 읽는다.
역피라미드: 첫 페이지는 모두를 위해
린치가 신입 시절 멘토에게 설계 문서를 건네며 프로젝트 배경을 설명하자 멘토가 얼굴을 찌푸리며 말했다. "방금 말한 것 전부가 설계 문서의 첫 페이지에 있어야 해요." 그는 팀원만을 독자로 상상하고 썼지만, 실제 독자에는 협력 팀, 멘토, 승진 위원회가 있었다.
해법은 신문 기자들의 역피라미드다. 넓은 독자층이 관심 있는 것을 맨 위에, 가장 깊이 관여한 독자만 읽을 세부를 아래로. "다른 팀을 위한 REST API를 설계한다면 그들은 API 의미와 신뢰성 목표는 읽겠지만 진단 메시지를 어떻게 로그에 남길지는 안 읽는다." 그래서 24개 절의 순서 자체가 독자층이 좁아지는 순서다.
리뷰어 한 명으로 시작하라
초안이 끝나면 팀 전체에 뿌리고 싶어진다. 참으라. 두 가지 이유가 있다. 첫째, 초안에는 반드시 설명 빈틈이 있고, 그것을 한 명이 걸려 넘어지는 게 열 명이 같은 데서 넘어지는 것보다 낫다. 둘째, 방관자 효과. 열 명에게 보내면 모두가 "누군가 꼼꼼히 보겠지" 하고 훑어만 본다. 한 명을 지목하면 그 사람은 철저한 리뷰를 기대받는다는 것을 안다.
누구를 고르나. "프로젝트에 가장 많이 걸린 사람." 함께 구현할 사람, 잠재 고객, 상류 의존성의 소유자. 그리고 2025년의 문장 하나가 눈에 띈다. "AI 어시스턴트는 팀원과 공유하기 전의 예비 설계 피드백에 유용할 수 있다." 린치는 AI로 문서를 쓰는 것에는 반대하지만 AI에게 먼저 읽히는 것에는 찬성한다. 이 구별이 9장의 핵심이 된다.
댓글 스레드를 죽여라
동반 글에서 가장 많이 인용된 대목이다.
"구글에서 일할 때 역사적인 설계 문서를 읽으려 하면 거의 불가능했다. 모든 페이지가 설계와 모순되는 여백 메모로 덮여 있었다. 개발팀이 원래 설계를 구현했는지 여백 토론의 아이디어를 구현했는지 알 수가 없었다."
규칙은 명확하다. 문서 저자는 댓글 스레드를 가능한 한 빨리 해결로 몰고 갈 책임이 있다. 질문을 받으면 댓글이 아니라 문서 본문을 고쳐서 답한다(안 그러면 다음 독자가 같은 질문을 한다). 두세 번 오간 뒤에도 안 끝나는 토론은 부록의 '열린 이슈'로 옮기고, 원래 스레드는 닫고, 본문 해당 절에 링크를 남긴다. 부록에서도 안 끝나면 회의로 넘긴다.
그리고 회의는 마지막 단계다. "많은 팀이 설계 리뷰의 첫 단계로 회의를 잡는 실수를 한다." 모두가 각자 읽고, 대안을 내고, 장단점을 이해한 뒤에 남은 이슈만 다루는 것이 회의다. 안건을 미리 공유해서 "이미 논란 없이 넘어간 결정에 막판 반대를 던지는 자리가 아님"을 분명히 한다.
1
문제
여백 댓글이 수백 개 쌓이면 문서는 읽을 수 없게 되고, 무엇이 결정이고 무엇이 잡담인지 아무도 모른다.
2
해법
질문은 본문 수정으로 답하고, 길어지는 토론은 부록 '열린 이슈'로 옮기고, 결정되면 요약을 맨 위에 적어 '해결된 이슈'로 옮긴다. 회의는 그래도 남은 것만.
3
결과
3년 뒤 이 문서를 여는 사람이 "왜 이렇게 했지"의 답을 부록에서 찾는다. 파나스가 1986년에 말한 "합리적 설계 과정을 흉내낸 기록"이 이렇게 만들어진다.
설계 포스트모템
구현이 끝나면 설계 과정 자체의 사후 검토를 한다. 무책임 추궁(blameless) 원칙으로. "출시가 2주 밀린 이유가 마이클이 서버 신청을 잊어서라면, 질문은 '마이클은 왜 그렇게 건망증이 심한가'가 아니라 '사람의 기억에 의존하지 않도록 절차를 어떻게 바꿀까'다." 예시 항목은 실제 사건 같다. "DuckDB 통합에 6주가 걸려 초기 추정의 2배였다. 설계 시점에 Objective-C 바인딩이 없다는 것을 몰랐고, 팀에 DuckDB 경험자가 없었으며, SQLite 통합 경험으로 추정한 것이 맞지 않았다." 교훈: 데이터베이스 기술을 고를 때 언어 바인딩을 확인하고, 팀의 미경험을 일정에 더 무겁게 반영하라.
6. 실제 문서 한 편 — Little Moments
"공개된 좋은 설계 문서를 본 적이 없다"고 한 린치는 직접 하나를 썼다. 가족 사진 공유 앱 Little Moments의 설계 문서다. 2026년 3월 6일 작성, 손으로만 16시간. 코드베르크(Codeberg) 저장소에 마크다운으로 공개되어 있고, 그는 지금 이 설계대로 앱을 구현하고 있다.
문서가 흥미로운 이유는 24개 절의 원칙이 실제 프로젝트에서 어떻게 구부러지는지 보여 주기 때문이다.
배경이 개인적이다. "나는 TinyBeans의 유료 고객이다. 프라이버시 친화적이고 광고 없는 앱이라고 광고해서 가입했는데, 가입하고 보니 유료 고객의 사진 앨범에도 광고를 끼워 넣고 있었다. 아기 사진 공유 서비스가 내 가족 사진에 광고를 넣고 친구·가족의 광고 타깃팅 정보를 모으는 것이 역겹다." 이 배경이 있어야 뒤의 목표(추적·광고 없음, 이메일 요약은 하루 한 번, 실시간 알림 없음. "앱은 느리고 차분하게 느껴져야 한다")가 이해된다.
목표에 숫자가 있다. 가족 한 세대당 호스팅 비용 월 10달러 이하. v1 구현 40 개발시간 이하.
비목표가 유혹을 자른다. 상용 사진 공유 앱 만들기(남의 사진을 호스팅하는 것은 치명적 위험이 너무 많다). 여러 가족이 서버 하나를 공유하기. 네이티브 모바일 앱(앱스토어 비용이 너무 크고, 크로스플랫폼 기술에 능숙하지 않다).
SLO가 솔직하다. 가용성 99%("2 나인", 연간 3.65일 장애 허용. "항상 켜져 있어야 하는 중요 앱이 아니다"). 썸네일 400ms. 사용자 50명, 동시 15명. 사진 50메가픽셀·50MB, 영상 8K·5GB·30분.
아키텍처 절이 곧 의존성 절이다. Go 백엔드, 프레임워크 없는 HTML/JS, SQLite("수백만 사용자로 확장하긴 어렵지만 우리는 수십 명이면 된다"), ffmpeg, fly.io, Bunny 스토리지, Sendamatic 메일(SMTP만 쓰므로 교체 가능), Litestream + Backblaze B2 백업, NixCI, Cronitor 모니터링, Codeberg. 각 항목에 이유가 한두 문장씩 붙는다. 작업 스케줄러는 "직접 만든다"인데, gocron·go-quartz·Dagu를 검토한 결과가 세 줄로 적혀 있다.
보안 절이 가장 길다. 위협 시나리오가 아홉 개다. 가족 구성원이 이메일을 전달하다 S3 URL이 새면(버킷 목록 비활성, UUID 파일명, 버킷 이름은 비밀 환경변수), 스크래퍼 봇이 서버를 두들기면(공개 페이지는 로그인뿐이라 렌더가 싸다), 사용자가 매직 로그인 링크를 실수로 전달하면(첫 사용 또는 30분 후 만료, 그리고 "귀여운 사진 같은 전달하고 싶은 것을 로그인 메일에 넣지 않는다"). CSRF는 SameSite Lax 쿠키와 "GET으로 상태를 바꾸지 않는다"로, 클릭재킹은 frame-ancestors 헤더로. 위협마다 "이건 이 앱 규모에서 그럴싸하지 않으니 이 정도만"이라는 판단이 붙어 있다.
프라이버시 절에 Exif가 있다. 사진 파일에는 촬영 시각, 카메라 정보, GPS 좌표가 숨어 있다. 앱은 업로드된 모든 사진·영상의 메타데이터를 벗기고 무작위 파일명을 붙인 뒤에야 다른 사용자에게 보여준다. 원본은 저장하되 v1의 웹 UI로는 접근할 수 없다. 2장의 분류 퀴즈에서 이 결정이 일방향 문인 이유가 여기 있다. 한 번 새어 나간 위치 정보는 되돌릴 수 없다.
마일스톤 8개는 "ROI 최대화, 낭비 최소화"로 정렬됐다. 1번은 TinyBeans에서 내보낸 데이터를 읽기 전용으로 보여주는 로컬 서버다. 데이터베이스도, 인증도, 업로드도 없다. "SQL 스키마 설계를 첫 마일스톤으로 잡는 일은 결코 없을 것이다. 그 자체로는 아무 가치가 없기 때문이다. 데이터베이스 없이 하드코딩된 미디어 파일 네 개를 서빙하는 진짜 웹 앱이 낫다." SQLite는 2번, 클라우드 스토리지 3번, 인증 4번, 배포 5번, 업로드 6번, 댓글 7번, 완성 8번.
🔍
읽는 법. 이 문서에서 배울 것은 절의 개수가 아니라 절의 길이 배분이다. 보안과 프라이버시가 가장 길고, 아이콘 라이브러리는 '검토한 대안' 부록의 몇 줄이다. 저자가 어디에서 가장 오래 고민했는지가 지면 배분에 드러난다. 9장에서 보겠지만, 바로 이 점이 AI가 쓴 설계 문서와 사람이 쓴 설계 문서를 가르는 가장 큰 차이였다.
1969년 4월 새벽 세 시, UCLA 대학원생 스티브 크로커는 친구 집 욕실에 서서 메모를 썼다. 자는 친구들을 깨우지 않기 위해서였다. 메모의 제목은 「Host Software」, 번호는 1번. ARPANET에 연결될 컴퓨터들이 서로 어떻게 대화할지에 대한 제안이었다. 그가 붙인 이름 "Request for Comments(의견 요청)"는 겸손에서 나왔다. 대학원생들에게는 표준을 정할 권위가 없었고, 그들은 그저 아이디어를 돌려 읽으며 의견을 구하고 있었다. 크로커는 2009년 뉴욕타임스 기고에서 이렇게 회고했다. 어떤 문서도 최종이 아니었고, 누구든 다음 번호로 반박할 수 있었으며, 그 열린 태도가 인터넷 공학 문화의 톤을 정했다고.
이것이 설계 문서의 원형이다. 코드가 아니라 글로, 혼자가 아니라 여럿이, 결정 전에.
1970년대: 설계는 결정의 문제라는 발견
1970년 윈스턴 로이스가 요구→설계→구현→검증의 단계 그림을 그렸다. 그 자신은 이 단선 흐름이 "위험하고 실패를 부른다"며 반복을 권했지만, 그림만 살아남아 '폭포수 모형'이 되었고, 설계 문서에 대한 반감의 뿌리가 되었다.
1972년 데이비드 파나스가 「시스템을 모듈로 나누는 기준에 관하여」를 썼다. 모듈은 처리 단계가 아니라 바뀔 가능성이 큰 설계 결정을 숨기도록 나눠야 한다는 주장이다. 4장의 Store 인터페이스가 정확히 이것이다. "저장소가 Postgres인가 캐시인가"라는 결정을 인터페이스 뒤에 숨기니 서버는 그 결정이 바뀌어도 모른다. 설계의 단위가 코드가 아니라 결정이라는 생각, 그리고 결정 중 어떤 것이 비싼지 먼저 골라내야 한다는 생각이 여기서 나왔다.
1975년 프레드 브룩스는 『맨먼스 미신』에서 "개념적 통일성"을 시스템 품질의 핵심으로 꼽고, 그것은 소수의 설계자가 글로 쓴 명세로 지켜진다고 했다. 여러 사람의 머릿속 그림을 하나로 맞추는 장치로서의 문서.
1981: "몇 년을 아낀다"의 숫자
배리 뵘은 『Software Engineering Economics』에서 TRW·IBM·GTE 자료를 모아 결함 수정 비용이 단계마다 오른다는 곡선을 냈다. 요구 단계에서 1이면 설계 3~8, 코딩 5~20, 테스트 10~50, 인수 테스트 30~100, 운영 50~200. "설계 단계의 실수가 가장 싸다"는 상식의 출처다.
다만 정직하게 적어야 할 것이 있다. 뵘 자신이 2001년 바실리와 함께 쓴 「소프트웨어 결함 감소 톱 10」에서 소규모·비핵심 프로젝트에서는 이 비율이 5:1 정도라는 단서를 달았다. 그리고 2016년 멘지스 등이 171개 프로젝트를 재검증한 「늦은 이슈는 정말 더 어려운가」는 "늦은 단계의 이슈 해결 노력이 일관되게 또는 실질적으로 더 크다는 증거를 찾지 못했다"고 결론지었다. 흔히 인용되는 "IBM 시스템 사이언스 연구소의 1:6.5:15:100"이라는 표는 출처가 확인되지 않는 교과서 각주의 전승이다.
그래서 설계 문서의 근거를 "버그가 100배 비싸진다"에 두면 흔들린다. 린치가 그 근거를 쓰지 않고 "틀렸을 때의 벌칙"이라는 결정 단위의 가역성에 둔 것은 우연이 아니다. 언어를 잘못 고른 결정의 벌칙은 뵘의 곡선과 무관하게 크다.
1986: 흉내내라
파나스와 클레멘츠의 「합리적 설계 과정: 어떻게, 왜 흉내낼 것인가」는 설계 문서의 철학을 한 문장으로 요약한다. 실제 설계는 결코 교과서처럼 요구에서 구현으로 곧게 진행되지 않는다. 그럼에도 우리는 "마치 그랬던 것처럼" 문서를 남겨야 한다. 후임자가 영웅적 노력 없이 설계자의 사고를 되짚을 수 있도록. 린치의 "해결된 이슈에 토론 전문을 남기라"는 규칙이 바로 이것이다. 문서는 과정의 녹취가 아니라 근거의 기록이다.
2000년대: 산업이 형식을 만들다
2000년 조엘 스폴스키가 「고통 없는 기능 명세」를 썼다. "프로그램을 사람 말로 설계하면 여러 가능성을 몇 분 만에 시험해 볼 수 있다. 코드로 하면 몇 주다." 해커뉴스에서 여러 사람이 "명세를 처음 알게 해 준 글"로 꼽았고, 린치는 재미있는 사실을 덧붙였다. 스폴스키가 공개한 실제 명세를 읽어 보니 20쪽 중 한 쪽이 넘게 변수명 접두사 규칙에 쓰여 있어서 "약간 실망했다"고. 명세의 전도사조차 양방향 문에 지면을 낭비했던 것이다.
2001년 애자일 선언은 "포괄적인 문서보다 작동하는 소프트웨어를"이라고 썼다. 문서를 없애자는 뜻이 아니었지만 많은 팀이 그렇게 읽었다. 해커뉴스의 한 댓글이 이를 이렇게 회고했다. "25년 전 애자일 선언은 잘 쓴 유스케이스 문서를 포스트잇에 들어갈 사용자 스토리로 찢으라고 가르쳤다. 찢을 문서가 있다면 괜찮은 아이디어였다. 그런데 곧 우리는 문서 대신 사용자 스토리를 쓰기 시작했고, 개발자들은 말했다. 문서 따위 필요 없다고."
2004년 아마존에서 제프 베이조스는 파워포인트를 금지했다. 에드워드 터프티의 에세이 「파워포인트의 인지 양식」을 읽은 뒤였다. 회의 자료는 서사형 6페이지 메모가 되었고, 회의 첫 20~30분은 참석자 전원이 침묵 속에서 읽는다. 베이조스의 설명: "좋은 4쪽 메모를 쓰는 것이 20쪽 파워포인트를 '쓰는' 것보다 어려운 이유는, 메모의 서사 구조가 무엇이 무엇보다 중요한지, 무엇이 어떻게 연결되는지 더 잘 생각하고 이해하도록 강제하기 때문이다." 신제품은 보도자료와 FAQ를 먼저 쓰는 PR/FAQ로 시작하게 됐다. 해커뉴스에서 아마존 출신 댓글 작성자는 그래서 자기는 설계 문서 하나 대신 "한 회의에서 다 읽을 수 있는" 짧은 문서 여러 개(관리자용, 아키텍처용, API·DB용)로 쪼갠다고 했다.
2011년 마이클 나이가드가 아키텍처 결정 기록(ADR)을 제안했다. 결정 하나에 문서 하나, 맥락·결정·결과를 한두 쪽에 적어 코드 옆에 둔다. 린치의 '해결된 이슈' 절을 저장소에 상주시킨 형태다.
2012~13년 우버는 엔지니어 50명 미만이던 시절 "고무 오리에게 설명하듯" 설계를 적는 DUCK 문서에서 시작해, 수천 명 규모에선 검색 도구와 승인자 필드를 갖춘 계층형 RFC 체계로 자랐다. 2019년 창업한 옥사이드 컴퓨터는 골랑·러스트·쿠버네티스 제안 절차를 참고해 RFD(토론 요청)를 만들었고, 기술 설계뿐 아니라 채용·문화·프로세스까지 5년 미만에 500편 넘게 썼다.
2020: 구글의 설계 문서
2020년 7월 구글 엔지니어 말테 우블이 「구글의 설계 문서」를 썼다. 구글 문화의 핵심 요소로서 설계 문서를 소개한 이 글은 린치의 원문과 나란히 놓고 읽을 만하다. 골격은 맥락과 범위, 목표와 비목표, 설계(시스템 맥락 다이어그램, API 스케치, 데이터 저장), 검토한 대안, 교차 관심사(보안·프라이버시·관측성). 주요 프로젝트는 10~20쪽, 소규모 개선은 1~3쪽. 그리고 이 문장. "설계 문서는 트레이드오프를 적어 두는 자리다." 『구글의 소프트웨어 엔지니어링』 10장은 "구글 대부분의 팀은 주요 프로젝트를 시작하기 전에 승인된 설계 문서를 요구한다"고 확인한다.
린치의 24개 절은 이 골격을 더 잘게 쪼개고 절마다 예시를 붙인 것으로 읽을 수 있다. 두 사람 모두 구글 출신이고, 그래서 해커뉴스의 한 댓글은 "구글 가이드까지 포함해 이런 것들은 이제 낡았다"고 도발했다. 그 논쟁은 8장에서.
8. 해커뉴스 137개 댓글의 논쟁
토론은 크게 다섯 갈래로 갈라졌다. 논점마다 원문 저자의 답이 있다는 점이 이 스레드를 특별하게 만든다.
논점 1: "AI 시대에 이 근거는 낡았다"
저자는 설계 문서를 싫어하는 이유를 두 가지로 정리했다.
"1. 설계 문서를 무의미한 의식으로 보는 팀에서 일한 경험. 저자는 무의미한 요구사항으로 취급해 나쁜 문서를 쓰고, 팀원은 무의미하다고 보니 유용한 피드백을 주지 않고, 그래서 모두의 믿음이 강화된다.
2. 남이 자기 엔지니어링 선택을 문제 삼는 것을 싫어하는 개발자. 완성된 코드는 설계 문서보다 반박하기 어렵다는 것을 안다. 설계보다 구현에 먼저 투자하면 계산이 '이상적인 구현'이 아니라 '이미 구현된 것' 쪽으로 기운다. 게다가 팀이 1만 줄의 설계 결정을 검토하는 것은 5쪽 문서를 검토하는 것보다 어렵다."
한 사용자가 받아쳤다. "AI 코딩 시대에 이 근거들은 좀 낡았다." 왜냐고 묻자 이렇게 답했다. "잘 지시하면 Fable이 소프트웨어 엔지니어의 80%보다 낫다고 본다. 어쩌면 그 이상. 왜 아직도 팀과 설계 결정을 검토해야 하나?" (그는 "미끼를 던지는 것일 수 있지만 솔직한 의견을 듣고 싶다"고 덧붙였다.)
저자의 답은 이 스레드에서 가장 많이 인용된 대목이다.
"LLM은 복잡도를 제한하는 데 아직 사람보다 못하다. 그것이 설계 리뷰의 가장 중요한 결과 중 하나다. 시니어 엔지니어에게 '토론 포럼을 만드는데 사용자가 아바타를 고르는 방법을 세 가지 주고 싶다. (1) Gravatar 가져오기, (2) JPG·SVG·PNG·GIF 업로드, (3) 캔버스에 직접 그리기'라고 하면, LLM은 기꺼이 그걸 설계하고 5천 줄을 짠다. 좋은 엔지니어는 반박한다. '그건 JPG만 허용하는 것의 10배 복잡도예요. v1에서는 JPG 업로드만 하면 어때요?'
Fable이나 Sol에게 '복잡도를 줄이기 위해 단순화할 기능을 찾아 봐'라고 해 봤지만 이해하지 못한다. 통째로 잘라낼 기능을 추측하긴 하지만, 복잡도 없이 기능의 본질을 잡아내는 법은 못 본다. 요즘 Fable에게 '실패하면 웹 UI에 오류 메시지를 보여 줘'라고 하면, 세 군데 입력을 조합하는 switch문 잔뜩 든 800줄짜리 오류 메시지 생성기를 들고 온다. 내가 원한 건 '업데이트 실패: 데이터베이스가 잠겨 있음' 한 줄이었는데."
누군가 더 밀어붙였다. 복잡도 자체가 적인가, 아니면 복잡도의 결과(버그, 변경 비용, 혼란)가 적인가? AI가 그 결과를 완화해 준다면 복잡도를 껴안아도 되지 않나? 저자의 답: "AI가 모든 소프트웨어 복잡도를 관리해 줄 것이라 믿기엔 아직 멀었다. LLM은 자기가 만든 복잡도에 자주 걸려 넘어진다. 설령 그렇지 않더라도, 시스템이 무엇을 하는지 이해하는 사람이 루프 안에 있어야 한다. 컴파일러와 비슷하다. 컴파일러가 충분히 잘해서 개발자 99%는 기계어 수준을 이해하지 않지만, CPU 명령어를 이해하는 마지막 1%를 잃으면 심각한 곤경에 빠진다."
논점 2: "코드가 싸졌으니 문서 대신 구현을 세 개 만들자"
가장 생산적인 반론이었다. "AI가 가능케 한 가장 큰 것은 싼 코드다. 문서에 세 가지 제안을 적고 하나를 추천하는 대신, 진짜 구현 세 개를 만들어 트레이드오프를 탐색할 수 있다. 계획은 필수지만 현실과 만나면 살아남지 못한다. 그런데 AI는 현실과의 접촉을 싸게 만들었다. 구현 몇 개를 만든 뒤에 설계를 쓰면 왜 안 되나?"
저자는 반쯤 동의했다. "에이전트에게 '빠른 프로토타입 만들어 줘'라고 해서 설계 문서에 참고하는 건 유용하다. 하지만 팀과 설계 결정을 검토하는 것이 목적이라면 설계 문서를 우회할 방법이 안 보인다. 팀원이 AI가 생성한 1만 줄을 보내며 설계를 검토해 달라고 하는 건 원치 않는다."
다른 댓글 작성자가 구체적인 예를 들었다. "나는 코드에 깊이 빠져 있을 때는 떠오르지 않을 '건드려야 할 곳'을 찾는다. 예를 들어 데이터베이스와 연결되는 코드는 고쳤는데 데이터베이스 안의 저장 프로시저는 안 고쳐서 트랜잭션마다 불일치 상태가 생기는 경우. 설계 문서는 그런 것을 생각하게 만드는 장치다. 스파이크 구현을 세 개 돌려서 AI가 어디를 건드렸는지 본다고 그것이 나오지 않는다." 이에 대한 재반론은 "체크리스트가 있으면 되고, 그 체크리스트는 문서에도 스파이크에도 똑같이 적용된다"였다. 이 부분은 결론이 나지 않았다.
논점 3: "요즘 읽는 설계 문서는 100% 생성물이다"
"농담으로 '클로드, 이 블로그 글대로 설계 문서 만드는 스킬 짜 줘'라고 하겠지만, 진지하게 말하면 내 일의 큰 부분이 문서 리뷰인데 요즘 읽는 설계 문서의 100%가 생성물이고 슬롭이 많다. 그걸 이해하려고 다시 AI로 파싱하니 문제에 기여하는 셈이다."
답들은 단호했다. "AI로 설계 문서를 '쓰지' 마라. 스스로 강제 못 하면 관리자에게 강제하게 하라." "슬롭이면 반려하고 이유를 말하라." "작성자가 발표하는 회의를 잡고 이상한 부분을 파고들어라. 자기가 썼다는 것을 이해 못 한다고 인정하게 되면, 이해 못 하는 문서를 생성해 남에게 떠넘기는 것이 용납되지 않는다는 것을 상기시켜라." 한 조직에서는 원칙을 세웠다고 했다. "작성자가 독자보다 최소 10배의 시간을 써야 한다. 아니라면 설계 문서는 그것을 생성한 프롬프트로 대체해도 된다." 그는 손으로 쓰는 1~2쪽 문서로 돌아갔다고 했다.
Lobsters의 최다 추천 댓글도 같은 말이었다. "글쓰기가 생각을 강제한다는 것이 이 글의 가장 중요한 부분이다. LLM에게 명세를 쓰게 하면 중요한 부분, 즉 생각을 건너뛰는 것이다. 0단계: 손으로 써라. 제발."
중간 지대를 찾은 사람도 있었다. "브레인스토밍은 에이전트와 하고, 마지막에 상세한 prompt.md를 뽑아 그대로 만들라고 한다"는 쪽과, "LLM이 만든 명세는 수십 쪽이라 읽기가 피로하다. 의사코드를 넣으라고 하면 1~2쪽이 되어 훑고 방향을 바꾸기 쉽다. 나머지 미사여구는 LLM에게 주는 컨텍스트일 뿐"이라는 쪽.
논점 4: 문서의 수명
"진짜 질문은 설계 문서를 어떻게 최신으로 유지하느냐다. 첫 버전은 괜찮은데 시간이 갈수록 현실에서 멀어진다." 저자의 답은 명쾌해서 논쟁의 한 축을 정리했다.
"설계 문서가 시스템의 영구적·살아 있는 기술서가 되기에 좋은 매체라고 생각하지 않는다. 설계 문서는 구현 시점의 설계를 포착해야 한다. 구현하는 동안에는 고치되, 끝나면 문서를 동결하고 후대를 위해 보존만 한다. 설계 문서는 시스템에 대한 특정 변경에 관한 것이다. 시스템의 고수준 아키텍처가 진화하는 것을 기술하는 문서가 필요하면 그건 다른 문서여야 한다."
썬 마이크로시스템즈 출신 댓글 작성자가 이 구분에 이름을 붙였다. 썬에서는 아키텍처 문서(인터페이스와 계약만 다룬다)와 설계 문서(알고리즘 같은 내부 세부)를 구분했다. "사람들이 '설계'라고 말할 때 대개 '아키텍처'를 뜻한다." 구현 중 요구가 크게 바뀌면 언제 재리뷰를 받나? 저자의 경험칙: "이것이 리뷰한 문서에 있었다면 승인하지 않았을 가능성이 있는가? 그렇다면 후속 리뷰를 보내고 왜 바꿔야 했는지 설명한다. 대개 '그래, 괜찮아'가 돌아온다. 하지만 혼자 조용히 설계를 바꾸면 신뢰가 무너진다."
논점 5: 소프트웨어 바깥의 시선
가장 짧으면서 가장 날카로운 댓글은 광학·전자 엔지니어에게서 나왔다. "설계 문서가 유용한지 아닌지를 두고 이렇게 논쟁이 벌어지는 것이 흥미롭다. 소프트웨어 바깥의 어떤 엔지니어도 무엇을 만들지 모두가 동의하고 큰 걸림돌이 없는지 확인하는 몇 문단 없이 프로젝트를 시작하지 않는다. 소프트웨어의 낮은 반복 비용 탓이라고 본다. LLM으로 더 낮아졌고." 항공(DO-178C)과 의료기기(IEC 62304) 경험자는 원문의 문서가 규제 산업 제출 문서 패키지의 상당 부분을 이미 덮는다고 했다. 남은 것은 요구에서 설계로, 설계에서 검증 방법과 결과로 이어지는 추적성뿐이라고. 그리고 "소프트웨어는 원자력 발전소가 아니다"라는 댓글에 대한 반론 하나. 2024년 한 보안 업체의 QA 실패로 850만 대의 시스템이 멈추고 4만 2천 편의 항공편이 지연됐다. "개발자들은 '우리 문제 아니야'라고 했겠지만, 그 무관심은 현실의 결과를 낳았다."
논점
회의론
저자·옹호론의 답
AI가 문서 근거를 낡게 했나
Fable이 엔지니어 80%보다 낫다면 왜 팀 리뷰가 필요한가
LLM은 복잡도를 줄이지 못한다. 시스템을 이해하는 사람이 루프에 있어야 한다
코드가 싸졌다
제안 대신 구현 3개를 만들어 비교하고 나중에 설계를 쓰자
프로토타입은 문서의 입력이지 대체물이 아니다. 1만 줄로 설계를 검토하게 하지 마라
생성된 문서의 홍수
어차피 다 AI가 쓰고 AI로 읽는다
손으로 써라. 작성자가 독자의 10배 시간을 써라. 아니면 반려하라
문서는 곧 낡는다
현실과 멀어져 쓸모없어진다
설계 문서는 변경 하나의 기록이다. 구현 끝나면 동결한다. 살아 있는 아키텍처 문서는 별도
그냥 만들어 보면 된다
소프트웨어는 원전이 아니다
가끔은 원전이다. 그리고 안전하지 않은 도메인에서도 일방향 문은 존재한다
한 가지 더. "팀원들에게 이 관행을 어떻게 설득하나"라는 질문에 저자는 8년 동안 머릿속에 있었다는 긴 답을 남겼다. "유용한 엔지니어링 관행 대부분은 팀에서 처음 도입하는 사람에게 위험이다. 모두가 자동 테스트를 멍청하다고 생각하는 팀에서 당신이 테스트를 도입하면 단기적으로 당신이 느려 보인다. 결국 사회적 자본을 쌓는 문제다. 팀원들은 시간 낭비 아이디어 전력이 있는 사람을 위해 위험을 감수하지 않는다. 나는 설계 문서를 밀기 전에 몇 가지 승리를 먼저 쌓았고, 남에게 쓰라고 하기 전에 내가 먼저 문서에 많이 투자해서 가치를 보여 줬다."
9. 2026년 — 사양 주도 개발과 "어느 문서를 사람이 썼나"
원문이 6월에 조용했다가 9월에 터진 배경에는 지난 1년 사이 업계에 퍼진 흐름이 있다. 사양 주도 개발(Spec-Driven Development).
"사양이 새로운 코드다"
2025년 6월 샌프란시스코 AI 엔지니어 월드 페어에서 OpenAI의 션 그로브가 「The New Code」라는 발표를 했다. 요지는 이렇다. 개발자들은 LLM에 프롬프트를 던지고 결과 코드만 남기고 프롬프트를 버린다. "소스를 파쇄하고 바이너리를 정성껏 버전 관리하는 것"과 같다. 의도와 요구를 담은 글로 쓴 사양은 어떤 모델 실행보다 오래 살아남고, 사람들을 같은 목표에 정렬시킨다. 코드는 사양의 "손실 있는 투영"이다. 그러므로 앞으로 희소한 기술은 "의도와 가치를 온전히 담은 사양을 쓰는 것"이다.
이 선언 이후 도구가 쏟아졌다. AWS의 Kiro는 기능 하나마다 요구(requirements.md)·설계(design.md)·과제(tasks.md) 세 파일을 강제한다. 요구는 "WHEN [조건] THE SYSTEM SHALL [행동]" 꼴의 EARS 표기법으로 쓰고, 설계에는 아키텍처와 시퀀스 다이어그램, 과제에는 추적 가능한 구현 단계가 들어간다. GitHub의 Spec Kit은 헌법(원칙)→사양→계획→과제→구현의 단계를 슬래시 명령으로 만들었고 2026년 중반 13만 개가 넘는 별을 모았다. 클로드 코드의 플랜 모드, 커서, 구글의 앤티그래비티까지 모든 주요 코딩 도구가 자기 방식의 "먼저 쓰고 나중에 만들기"를 실었다.
구분
린치의 설계 문서
Kiro 스펙
Spec Kit
주 독자
사람(팀원·협력 팀·후대)
에이전트 + 사람
에이전트 + 사람
단위
변경 하나(프로젝트)
기능 하나
기능 하나
범위 정의
목표·비목표·시나리오
사용자 스토리 + EARS 수용 기준
사양(specify) 단계
구조
절 24개 중 선택
요구·설계·과제 3파일 고정
헌법·사양·계획·과제 고정
트레이드오프
검토한 대안·열린 이슈·해결된 이슈
design.md의 고려사항
plan 단계
수명
구현 끝나면 동결
기능과 함께 진화
기능과 함께 진화
리뷰
사람 한 명→팀→회의
사람이 각 단계 승인
사람이 각 단계 승인
표에서 보이듯 둘은 대체 관계가 아니다. 사양 주도 도구는 린치의 절 중 '무엇을'(목표·비목표·시나리오)과 '어떻게'(인터페이스·의존성)를 에이전트가 읽기 좋게 구조화한 것이고, 린치의 문서가 무겁게 다루는 '위험'(보안·프라이버시·법률)과 '꼬리'(열린 이슈·검토한 대안)는 대개 얇다. 그리고 결정적으로, 사양 주도 도구는 사양의 초안을 에이전트가 쓴다. Lobsters와 해커뉴스가 반복해서 경고한 바로 그 지점이다.
저자의 실험: 어느 설계 문서를 사람이 썼나
린치는 이 경고를 실험으로 확인했다. 2026년 3월, Little Moments 설계 문서를 세 벌 만들었다. 하나는 자기가 16시간 동안 손으로 쓴 것(6장에서 읽은 그 문서). 하나는 Claude Opus 4.6(중간 노력)이, 하나는 GPT-5.4(높은 노력)가 몇 분 만에 생성한 것. AI에게는 책의 설계 문서 장과 골격만 주고, 그가 쓴 버전은 보여주지 않았다. 그리고 독자에게 물었다. 어느 것이 사람이 쓴 것인가?
16h
사람이 쓴 문서에 든 시간
수 분
AI 두 벌을 만드는 데 든 시간
50%
사람 버전을 맞힌 독자 (조금 못 미침)
1/4
사람 버전을 "확실히 AI"로 판정한 독자
사람 버전을 고른 독자는 절반이 조금 안 됐다. 다른 두 버전보다 2:1로 앞섰지만, 넷 중 하나는 손으로 쓴 문서를 "확실히 AI"라고 했다. 독자들이 사람의 흔적으로 꼽은 것은 개인적 경험과 의견("나는", "우리는"), 본문 밖으로 새는 링크, NixCI나 PolyForm 비상업 라이선스 같은 비주류 기술 선택, "미국 동부 시각 오전 9시"처럼 구체적인 시간대. AI의 흔적은 "부풀림. 모든 문장이 무관한 말로 채워져 있다", 의미 없는 굵은 글씨, "그 선택은 자체 호스팅 목표에 부합한다" 같은 목표 작성자와 본문 작성자가 다른 듯한 어색함, 그리고 "마일스톤당 10시간"처럼 엔지니어라면 하지 않을 지나치게 정밀한 시간 추정.
가장 중요한 발견은 이것이다.
"AI 생성 설계 문서 둘 다에서 가장 크게 빠진 것은 무엇이 어려운 문제였는가에 대한 감각이다. 설계가 균형 잡아야 했던 경쟁하는 이해관계는 무엇이었나? 사람이 쓴 설계 문서를 읽으면, 어떤 절이 얼마나 많은 지면을 차지하는지로 어려운 결정을 직관할 수 있다. 나에게 이 앱의 가장 큰 과제는 보안과 사용성의 균형이었다. 그래서 프라이버시와 보안 절이 그렇게 긴 것이다. AI 문서의 보안·프라이버시 절은 이 앱에 특정한 것이 하나도 없는 웹 앱 모범 사례의 일반적 목록이었다."
AI가 생성한 다이어그램. 화살표가 텍스트 위를 지나간다. 출처: refactoringenglish.com
박스와 라벨은 그럴듯하지만, TinyBeans 아카이브에서 워커로 올라가는 화살표가 설명 문장 위를 그대로 가로지른다. 린치는 "클로드는 더 나은 다이어그램을 만들었지만 요소끼리 충돌하는 비슷한 배치 문제가 있었다. 사람이라면 즉시 잘못됐다고 알아볼 것"이라며 세 버전 모두에서 다이어그램을 뺐다. 위 4장에서 본 ScreenJournal 그림과 나란히 놓으면 "다이어그램이 피드백의 50%를 받는" 이유가 보인다. 배치는 정보다. 무엇이 무엇 안에 있고, 어느 화살표가 신뢰 경계를 넘는지, 사람은 그것을 배치로 읽는다.
한 가지 반전도 있다. 린치는 클로드 버전에 "기분 좋게 놀랐다"고 썼다. 기술 선택이 자기와 너무 비슷해서 이전 세션의 기억이 새어 들어간 것이 아닌지 의심할 정도였다. 반면 GPT-5.4 버전은 '검토한 대안' 절을 비목표의 부풀린 재탕으로 채워 "요점을 완전히 놓쳤다." 모델 사이의 차이도 크다.
그래서 2026년에 설계 문서의 역할은 무엇인가
이 특집이 이르는 판단은 세 줄이다.
첫째, 설계 문서의 독자에 에이전트가 추가되었다. 그러나 저자는 아직 사람이어야 한다. 해커뉴스의 한 댓글이 정확히 짚었다. "AI는 많은 것을 맞히지만 가끔 틀린다. 설계 문서는 사람이 쓴 유일한 텍스트일 수 있고, 미래의 에이전트가 구현의 어딘가가 잘못됐음을 알아보게 해 준다." 에이전트가 쓴 사양을 에이전트가 구현하고 에이전트가 검토하면, 잘못된 전제를 바로잡을 지점이 어디에도 없다.
둘째, "틀렸을 때의 벌칙" 기준은 더 중요해졌다. 코드가 싸지면 양방향 문은 더 넓어진다. '더 보기' 버튼은 이제 몇 시간이 아니라 몇 분이다. 그러니 문서는 더 짧아져야 한다. 하지만 일방향 문은 그대로다. 언어, 저장소, 공개 API, 개인정보, 계약. 오히려 에이전트가 쉽게 만들어 버리는 것들이라 더 위험하다. 한 댓글의 사례처럼, 에이전트는 "특정 고객에게 금지된 라이브러리 Foo"나 "회사가 폐기 중인 레거시 인증 플랫폼 API"를 누군가 한 번 쓴 적이 있다는 이유로 태연히 고른다.
셋째, 문서를 쓰는 시간이 곧 생각하는 시간이라는 것을 지켜야 한다. 린치가 문서 초안은 손으로 쓰되 AI에게 먼저 읽히라고 한 구별이 실용적인 경계선이다. 생성은 쉽고 생각은 어렵다. 해커뉴스 토론에서 반복된 "작성자가 독자의 10배"라는 원칙은 그 경계선을 조직 규칙으로 옮긴 것이다.
💡
코어닷투데이의 관점. 우리는 에이전트와 함께 일하는 프로젝트에서 설계 문서의 무게중심이 두 절로 옮겨 가는 것을 본다. 비목표와 용어집이다. 사람 팀에서는 "당연히 안 하는 것"이 에이전트에게는 당연하지 않고, 사람 팀에서는 "대충 알아듣는 말"이 에이전트에게는 다른 뜻이 된다. 범위의 바깥과 단어의 뜻을 못 박는 절이 에이전트 시대의 설계 문서에서 가장 먼저 읽히고 가장 자주 참조된다. 나머지 절은 짧아져도 된다. 이 두 절은 길어져야 한다.
10. 이번 주에 해볼 일
원문과 토론에서 뽑은, 바로 적용할 수 있는 것들이다.
1
지금 하는 일에 여섯 질문을 던진다. 1장의 판정기로. '예'가 둘 이상인데 문서가 없다면 그것이 이번 주의 일이다. 하나도 없다면 안 써도 된다. 그것도 원문의 가르침이다.
2
한 장짜리로 시작한다. 목적 한 문장, 배경 세 문장, 목표와 비목표 각 세 줄, 틀리면 비싼 결정 두세 개와 그 이유, 열린 이슈. 다이어그램 하나. 이것만으로 대부분의 팀 규모 프로젝트에 충분하다.
손으로 쓰고, AI에게 먼저 읽힌다. 초안은 직접. 그다음 에이전트에게 "이 문서에서 설명이 빠진 곳, 정의 안 된 용어, 고려 안 한 위협"을 묻는다. 그다음에야 사람 리뷰어 한 명.
5
댓글은 본문 수정으로 답한다. 두세 번 오간 스레드는 '열린 이슈'로 옮기고 닫는다. 회의는 그 뒤에, 안건과 함께.
6
구현이 끝나면 동결하고, 한 번 돌아본다. 문서를 살아 있는 아키텍처 기술서로 만들려 하지 않는다. 대신 30분짜리 무책임 추궁 포스트모템으로 "설계 시점에 무엇을 놓쳤나"를 적어 다음 문서에 반영한다.
에이전트와 일하는 팀이라면 하나 더. 문서의 첫 페이지를 에이전트의 세션 시작 컨텍스트로 쓴다. 해커뉴스 댓글 작성자의 말처럼 "이 문서를 읽고 세계에 익숙해진 뒤 일하자." 그러면 문서를 사람이 쓸 이유가 하나 더 생긴다. 그 문서가 에이전트를 붙잡아 두는 닻이 되기 때문이다.
마치며 — 석 달 만에 1면에 오른 이유
원문은 바뀌지 않았다. 세상이 바뀌었다. 6월에는 "설계 문서를 어떻게 쓰나"가 질문이었고, 9월에는 "설계 문서를 여전히 사람이 써야 하나"가 질문이 되었다. 두 번째 질문은 첫 번째보다 훨씬 많은 사람을 불러 모았다.
린치의 답은 겸손하고 완고하다. 가끔은 안 써도 된다. 쓸 때는 틀리면 비싼 것만 쓴다. 그러나 그것을 쓰는 사람은 당신이어야 한다. 1969년 욕실에서 크로커가 메모를 쓴 이유, 1975년 브룩스가 명세를 고집한 이유, 2004년 베이조스가 파워포인트를 금지한 이유가 전부 같다. 글로 쓰지 않은 생각은 아직 생각이 아니다.
코드가 사양의 투영이라면, 사양은 생각의 투영이다. 그 첫 번째 투영을 기계에 맡기는 순간 우리는 무엇을 만들고 있는지 모르게 된다. 이 글이 석 달 만에 1면에 오른 이유는, 그 사실을 많은 사람이 동시에 느꼈기 때문일 것이다.
본문의 삽화와 인터랙티브 위젯은 코어닷투데이가 제작했습니다. 두 장의 아키텍처 다이어그램(ScreenJournal, Codex 생성 Little Moments)은 마이클 린치의 글에서 설명 목적으로 인용한 것이며 저작권은 원저자에게 있습니다. 원문·댓글 인용은 우리말로 옮긴 것이며, 정확한 표현이 중요한 대목은 원문을 함께 확인하시기를 권합니다. 해커뉴스 점수와 댓글 수는 2026년 9월 15일 기준입니다.