-
ADR, 설계 결정을 기록하는 가장 가벼운 방법 — AI 에이전트가 '왜'를 알게 되는 문서IT 2026. 4. 26. 21:00
코드는 "무엇"을 보여주지만, "왜"는 보여주지 않는다
git blame을 하면 누가, 언제 이 코드를 작성했는지는 알 수 있다. 하지만 당시 어떤 대안이 있었고, 왜 이 방법을 택했는지는 알 수 없다. 커밋 메시지에 "PostgreSQL → SQLite로 변경"이라고 적혀 있어도, 왜 PostgreSQL을 버렸는지, 어떤 트레이드오프를 감수했는지는 사라진다.이 간극을 메우는 문서가 ADR(Architecture Decision Record)이다. "이 프로젝트에서 왜 이런 선택을 했는가"를 짧고 구조화된 형식으로 기록한다.
ADR의 기원: Michael Nygard는 누구인가
ADR이라는 형식을 처음 제안한 사람은 Michael T. Nygard다. 2011년에 쓴 블로그 글 "Documenting Architecture Decisions"에서 이 개념을 정리했다.
Nygard는 금융, 정부, 유통 등 대규모 시스템을 15년 이상 설계·운영한 소프트웨어 아키텍트다. Clojure와 Datomic을 만든 Cognitect에서 일했고, 「Release It!」(Pragmatic Bookshelf, 2007/2018)이라는 책으로 유명하다. 이 책은 "운영 환경에서 살아남는 소프트웨어를 어떻게 설계할 것인가"를 다루며, 서킷 브레이커, 벌크헤드 같은 안정성 패턴을 대중화시켰다.
Nygard가 ADR을 제안한 배경도 같은 맥락이다. 운영하다 보면 과거의 설계 결정을 이해해야 하는 순간이 반드시 온다. 그때 결정의 맥락이 기록되어 있지 않으면, 같은 실수를 반복하거나 이미 검토한 대안을 다시 검토하게 된다.
ADR의 4가지 구성 요소
Nygard가 제안한 ADR 형식은 놀라울 정도로 간결하다. 딱 4개 섹션이다:
1. Status — 이 결정의 현재 상태
Proposed,Accepted,Deprecated,Superseded중 하나. 살아있는 문서이므로, 나중에 결정이 뒤집히면 Status를 바꾸고 새 ADR을 작성한다.왜 LLM에게 중요한가: AI 에이전트가 ADR을 읽을 때 Status가
Deprecated이면 이 결정이 더 이상 유효하지 않다는 것을 즉시 파악한다. Status 없이 본문만 있으면 에이전트가 이미 폐기된 설계 원칙을 따라 코드를 작성할 수 있다.2. Context — 어떤 상황이었는가
결정을 내리게 된 배경, 제약 조건, 비즈니스 요구사항을 서술한다. "무엇을 결정했는가"보다 "왜 결정해야 했는가"가 핵심이다.
예를 들어:
## Context 가족 사진을 체계적으로 관리하고 AI 분석 결과를 활용하려면 사진 저장소가 필요했다. 선택지: 1. 로컬 파일 시스템 — 메타데이터 관리가 어렵고 얼굴 인식 없음 2. Google Photos API — 개인정보 우려, API 제한, 비용 3. Immich — 셀프호스팅 오픈소스, REST API, 얼굴 인식 내장왜 LLM에게 중요한가: Context는 에이전트에게 "이 프로젝트의 제약 조건"을 알려준다. "개인정보 우려" 때문에 클라우드를 쓰지 않는다는 맥락을 알면, 에이전트가 새 기능을 제안할 때 "Google Photos API를 쓰면 어떨까요?"라는 부적절한 제안을 하지 않게 된다.
3. Decision — 무엇을 선택했는가
선택한 방안과 그 이유를 명시한다. "X를 한다"가 아니라 "X를 한다, 왜냐하면 Y 때문이다"까지 적어야 가치가 있다.
## Decision Immich를 사진 백엔드로 사용한다. 이유: - 셀프호스팅으로 가족 사진이 외부에 나가지 않음 - REST API로 사진 조회, 태깅, 인물 검색 가능 - VLM 분석 결과를 태그로 저장하여 추적 가능왜 LLM에게 중요한가: Decision은 에이전트에게 "이 프로젝트의 기술 스택이 왜 이 모양인지"를 설명한다. Immich를 사용하는 이유를 알면, 에이전트가 관련 코드를 수정할 때 Immich의 API 패턴을 따르고, 기존
ImmichClient를 재사용하는 방향으로 코드를 작성한다.4. Consequences — 결과와 트레이드오프
이 결정의 긍정적 결과와 부정적 결과를 둘 다적는다. 모든 설계 결정에는 트레이드오프가 있다. 트레이드오프를 명시하지 않는 ADR은 반쪽짜리다.
## Consequences - 긍정: API 기반 자동화, 프라이버시 보호, 기존 코드 재사용 - 부정: Immich 서버 의존성 (다운 시 추출 불가) - 리스크: Immich API 변경 시 클라이언트 수정 필요왜 LLM에게 중요한가: Consequences는 에이전트에게 "어디가 약한 고리인지"를 알려준다. "Immich 서버 의존성"이 부정적 결과로 명시되어 있으면, 에이전트가 에러 핸들링을 작성할 때 Immich 연결 실패를 반드시 처리해야 한다는 판단을 내릴 수 있다. 이 정보가 없으면 에이전트는 외부 서비스 호출을 에러 처리 없이 작성할 수 있다.
ADR이 LLM에게 주는 3가지 맥락
정리하면, ADR의 각 섹션은 AI 에이전트에게 코드만으로는 얻을 수 없는 세 가지 맥락을 제공한다:
맥락 ADR 섹션 코드만으로 알 수 있는가? LLM에게 주는 효과 제약 조건 Context 알 수 없음 부적절한 기술 제안 방지 설계 의도 Decision 부분적 (코드 패턴으로 추측) 기존 패턴을 따르는 코드 작성 약한 고리 Consequences 알 수 없음 에러 핸들링과 방어 코드의 우선순위 판단 특히 Context와 Consequences는 코드 분석만으로는 절대 추론할 수 없는 정보다. 코드에서 Immich API를 호출하는 것은 보이지만, "Google Photos는 개인정보 때문에 배제했다"는 맥락이나 "Immich 다운 시 추출이 멈춘다"는 리스크는 코드 어디에도 없다.
ADR 작성 팁: 무엇을 기록하고, 무엇을 안 하는가
기록해야 할 것
- 한 달 뒤에 "왜 이랬지?"라고 물을 만한 결정 — 기술 스택 선택, 데이터 저장 방식, 통신 프로토콜, 인증 방식
- 대안이 2개 이상이었던 결정 — 고민 없이 자명했던 선택은 ADR이 불필요하다
- 되돌리기 비용이 높은 결정 — DB 스키마, 외부 서비스 의존, 배포 전략
기록하지 않아도 될 것
- 코딩 컨벤션(탭 vs 스페이스) — 린터로 자동화
- 라이브러리의 세부 버전 선택 —
package.json이 기록 - 모든 함수의 설계 이유 — 코드 주석이나 docstring으로 충분
분량
ADR 하나당 A4 반 페이지 정도가 적절하다. 10-15분이면 쓸 수 있다. 길어질수록 안 읽히고, 유지보수 부담이 커진다. Nygard 자신도 "짧게, 한 결정에 하나의 ADR"을 강조했다.
ADR을 CLAUDE.md에서 참조하기
이전 글에서 다뤘듯이, AI 코딩 에이전트는
CLAUDE.md나.clinerules같은 지침 파일을 가장 먼저 읽는다. ADR을 작성했다면, 지침 파일에서 연결해줘야 에이전트가 확실히 찾아간다.# CLAUDE.md 예시 ## 설계 결정 주요 아키텍처 결정은 `docs/adr/`에 기록되어 있다. 새 기능을 추가하거나 기술 스택을 변경할 때 반드시 참고할 것. - ADR-0001: 사진 백엔드로 Immich 선택 - ADR-0002: 로컬 LLM(vLLM) 사용 결정 - ADR-0003: 시간 기반 이벤트 클러스터링이렇게 하면 에이전트가 관련 작업을 할 때 해당 ADR을 읽고, 기존 결정의 맥락을 이해한 상태에서 코드를 수정한다.
마무리: 결정은 사라지고, 코드만 남는다
프로젝트가 오래될수록 "왜 이렇게 했지?"라는 질문이 늘어난다. Slack 스레드는 묻히고, 회의 내용은 잊힌다. 코드만 남아서 "what"은 알 수 있지만 "why"는 사라진다.
ADR은 이 "why"를 코드 옆에, 버전 관리되는 형태로 남겨두는 가장 가벼운 방법이다. A4 반 페이지, 15분이면 쓸 수 있고, 6개월 뒤의 나 — 또는 AI 코딩 에이전트 — 가 같은 실수를 반복하지 않게 해준다.
이 글은 생성형 AI의 도움을 받아 작성되었습니다. 원본 자료를 기반으로 AI가 초안을 생성하고, 작성자가 검토·편집하였습니다.
'IT' 카테고리의 다른 글
하네스 엔지니어링 9단계 베스트 프랙티스 #2. Code Wiki 작성 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #1. 프로젝트 규칙 설정 (0) 2026.04.27 하네스 엔지니어링 9단계 베스트 프랙티스 #0. 업무 프로세스 매핑 (0) 2026.04.27 RAG 시스템에 코드 위키를 적용한 실전 사례 — 7개 문서로 11,000 벡터를 설명하다 (0) 2026.04.26 코드 위키의 마지막 퍼즐, 모듈 문서 — AI 에이전트가 함수를 이해하는 방법 (1) 2026.04.26 데이터 파이프라인 문서에는 뭘 써야 할까 — architecture.md가 다루지 않는 것 (1) 2026.04.25 아키텍처 문서에는 뭘 써야 할까 — AI 에이전트가 읽는 시대의 architecture.md (0) 2026.04.25 Docs-as-Code로 사이드 프로젝트 문서화하기 — 코드 위키 실전 적용기 (1) 2026.04.25 벡터 DB 온디맨드 관리 — Qdrant와 임베딩 서버의 cold start 실측 (0) 2026.04.24 Claude Code settings.json vs settings.local.json — 왜 둘로 나뉘었나 (0) 2026.04.23