에이전트가 신뢰할 수 있는 문서화 (그리고 이것이 나를 더 빠르게 만든 이유)
요약
코딩 에이전트가 신뢰할 수 있는 문서를 작성하기 위해 '불변성(Immutability)'과 '대체(Supersession)' 원칙을 적용하는 방법을 제안합니다. 기존의 수정 가능한 ADR 방식 대신, 새로운 결정을 새로운 문서로 기록하여 에이전트가 맥락을 정확히 파악하도록 최적화합니다.
핵심 포인트
- 에이전트를 위한 문서화는 인간을 위한 문서화와 맥락 최적화 방식이 유사함
- 기존 ADR의 수정 방식은 정보의 파편화와 신뢰도 저하를 야기함
- 결정 기록은 수정하지 않고 새로운 ADR로 대체하는 '불변성' 원칙이 핵심
- 명시적인 대체 체인을 통해 에이전트가 데이터의 최신성을 신뢰할 수 있게 함
원문은 olund.dev에서 처음 게시되었습니다.
이 글의 이전 두 포스트는 몇 주 전에 완료된 작업들을 설명합니다. 20개의 측정된 쿼리(queries)가 포함된 검색(retrieval) 버그와 설계 대안을 포함한 프레젠스 레이어(presence layer)에 관한 내용입니다. 저는 각각을 오후 한때에 작성했으며, 아무것도 재구성하지 않았습니다. 모든 숫자, 모든 거부된 옵션, 모든 이유는 이미 예측 가능한 장소에, 변하지 않았음을 신뢰할 수 있는 형태로 기록되어 있었습니다.
이것은 근면함 때문이 아닙니다. 제 습관에 맡겨둔다면 저도 다른 사람들처럼 문서화를 합니다. 시작할 때는 열정적이지만, 그 이후로는 절대 하지 않죠. 기록이 존재하는 이유는 제 프로젝트들이 인간보다 맥락(context)이 적은 독자, 즉 아무런 사전 정보 없이 투입되는 코딩 에이전트(coding agent)를 위해 설계된 문서화 표준을 따르기 때문입니다. 그 독자를 위해 문서를 최적화하는 것이 인간에게도 극적으로 더 좋다는 사실이 밝혀졌습니다. 미래의 저 또한 더 많은 과신을 가졌을 뿐, 아무런 사전 정보 없이 투입되는 독자이기 때문입니다.
실패 모드: 무엇이 사실인지 아무도 알 수 없음
표준화하기 전에 저는 제 자신의 저장소(repos)를 조사했습니다. 그 증거는 구체적이고 계산 가능한 방식으로 당혹스러웠습니다:
- 계속해서 늘어나기만 하는 아키텍처 결정 기록(Architecture decision records, ADR). 한 ADR은 9개의 날짜가 지정된 수정 섹션과 약 390줄의 내용을 축적했습니다. 다른 하나는 500줄이 넘었습니다. 하나를 읽는다는 것은 일기를 읽는 것과 같았고, 어떤 부분이 여전히 적용되는지 정신적으로 재구성해야 했습니다.
- 단일 빌드 계획(build-plan) 파일과 960줄에 달하는 "배포됨(shipped)" 장부. 진행 중인 상태(in-progress state)는 없었으며, "완료(done)"에 대한 두 개의 진실의 원천(sources of truth)이 서로 일치하지 않았습니다.
핵심 원칙: 승인된 결정 기록(decision record)은 다시는 수정하지 않습니다.
ADR 하나당 하나의 결정만을 담으며, 짧게 작성합니다. 만약 결정이 변경된다면, 이전 것을 대체하는 새로운 ADR을 작성합니다. 그리고 이전 ADR의 상태를 "NNNN에 의해 대체됨(superseded by NNNN)"으로 변경합니다. 이는 본문은 건드리지 않은 채 메타데이터 한 줄만 바꾸는 작업입니다.
이 방식을 채택하기 전, 저는 발표된 분야 전반에 대해 조사(research pass)를 수행하며 각 주장을 적대적 검증(adversarially verified)했습니다. 그 결과 발견한 단 하나의 가장 강력한 수렴점은 다음과 같습니다. 네 개의 독립적인 주요 소스(AWS의 규정 지침, adr-tools, log4brains, MADR) 모두가 '불변성(immutability)과 대체(supersession)'를 제 리포지토리들이 보여주었던 바로 그 '추가 전용 저널 확산(append-only journal sprawl)' 문제에 대한 해결책으로 지목했습니다.
이 방식이 작동하는 더 깊은 이유는 신뢰(trust)이며, 신뢰는 스타일 선호도가 되기 이전에 에이전트(agent)의 필수 요구 사항입니다. 가변적인(mutable) 문서를 인용하는 에이전트는 결정이 내려진 이후에 텍스트가 변경되었는지 의심해야만 합니다. 명시적인 대체 체인(supersession chain)을 가진 불변의 기록은 자신의 이력에 대해 거짓말을 할 수 없습니다. 상태가 '승인됨(accepted)'이라고 되어 있다면, 본문의 내용은 승인된 날에 의미했던 바를 오늘날에도 동일하게 의미합니다. 이러한 속성 덕분에 저는 몇 주 뒤에 코드와 대조하여 재검증하는 과정 없이도 설계 근거(design rationale)를 블로그 포스트로 옮길 수 있었습니다.
불변성을 정직하게 유지하기 위한 보조 규칙이 하나 더 있습니다: 실제 구축된 현실(as-built reality)은 ADR에 살지 않습니다. ADR은 결정을 기록하고, 이를 구현한 계획(plan)을 가리키는 포인터 한 줄을 포함합니다. 구현이 실제로 어떻게 진행되었는지—예상치 못한 상황이나 편차 등—는 계획에 기록됩니다. 이러한 분리가 없다면,
태스크 ID는 영원히 안정적입니다. 태스크는 생성 시 T1, T2 등으로 할당되며 절대 번호가 바뀌지 않습니다. 분할되거나 순서가 바뀐 태스크는 새로운 ID를 받지만, 기존 ID의 의미는 조용히 변경되지 않습니다. 이는 커밋 기록, 세션 노트, 그리고 현재 작업 포인터가 모두
둘째, 진행 중인 상태(in-flight status)는 의도적으로 일시적(ephemeral)입니다. "세션 A가 T3를 작업 중임"이라는 정보는 이전 포스트에서 언급한 실시간 존재 레지스트리(live presence registry)에만 존재하며, 계획(plan) 내의 영구적인 마커(durable marker)로 남지 않습니다. 영구적인 '진행 중' 플래그는 세션이 작업 도중 종료될 때 정확히 부패(rot)하는 요소이며, 이것이 바로 나의 예전 '현재 작업(current-task)' 노트가 전문적인 거짓말쟁이가 된 이유입니다. 영구적인 파일은 영구적으로 진실인 것을 기록하며, 실시간 상태(live state)는 프로세스와 함께 소멸하는 어딘가에 존재합니다.
강제되지 않는 규율은 장식에 불과하다
위의 모든 사항은 만약 나의 일관성에 의존했다면 한 달 안에 부패했을 것이기에, 그렇게 하지 않습니다.
- 새로운 리포지토리(repo)는 첫 번째 커밋에 구조, 템플릿, 용어집(glossary)이 포함된 스캐폴딩(scaffolded) 상태로 생성되므로, 표준을 따르는 것이 가장 저항이 적은 경로가 됩니다.
- 기계가 읽을 수 있는 불변량(invariants)에 대해 린트(lint)를 실행합니다: 프론트매터(frontmatter) 상태 값, 태스크 ID(task-id)의 고유성, 아카이브 이동, 존재하는 계획을 참조하는 포인터 파일, 그리고 여전히 경로가 유효한 ADR의 구현자(implemented-by) 경로 등이 대상입니다.
- 기존 리포지토리에 대한 마이그레이션 규칙은 순방향(forward-only)입니다. 아무것도 소급하여 다시 쓰지 않지만, 오래된 미결 항목을 건드리는 것은 그것을 먼저 실제 계획(plan)으로 끌어올리는 것을 의미합니다. 오래된 혼란은 세탁되는 것이 아니라 격리됩니다.
린트(lint)는 보기보다 중요합니다. 그것은 "우리는 이것을 하기로 합의했다"를 "빌드(build)가 당신이 하지 않았을 때를 알려준다"로 변환하며, 이는 바쁜 한 주를 견뎌내고 살아남는 유일한 형태의 합의입니다.
무엇이 전이되는가
- 가장 적은 맥락을 가진 독자를 위해 작성하세요. 아무런 사전 정보 없이 투입되는 에이전트(Agent)는 미래의 당신을 대신하는 정직한 대리인입니다. 에이전트가 당신의 저장소(Repo)로부터 무엇이 결정되었고, 무엇이 수행되었으며, 무엇이 미결 상태인지를 재구성할 수 있다면, 어떤 인간도 그렇게 할 수 있습니다.
- 기록을 불변(Immutable)하게 만들고 변경 사항을 명시하세요. 조용히 수정될 수 없는 문서만이 당신과 에이전트 모두가 재검증 없이 인용할 수 있는 유일한 종류의 문서입니다.
- 모든 질문에 정확히 하나의 권위 있는 보금자리를 부여하세요. 그리고 어떤 축이 지속 가능(Durable)하고 어떤 축이 일시적(Ephemeral)인지에 대해 정직해지세요. 대부분의 정보 노후화(Staleness)는 지속 가능한 파일이 실시간 상태(Live state)를 알고 있다고 주장할 때 발생합니다.
- 깔끔한 번호 재매기기보다 안정적인 ID가 낫습니다. 문서 외부에서 참조되는 모든 것은 결코 의미가 변해서는 안 됩니다.
- 기계적으로 강제하거나, 아니면 표류하는 것을 지켜보세요. 템플릿(Template)은 준수를 저렴하게 만들고, 린트(Lint)는 표류를 명확하게 드러냅니다.
이러한 복리 효과는 저를 놀라게 했습니다. 메모리 시스템(Memory system), 존재 레이어(Presence layer), 그리고 이 표준에 이르기까지 각 레이어는 각자의 국소적인 문제를 해결하기 위해 구축되었으며, 이들에 대한 포스트들이 존재하는 이유는 이 레이어들이 서로를 문서화하기도 하기 때문입니다. 제 에이전트들을 정직하게 유지해 주는 인프라가 결국 제가 여러분에게 이 이야기를 할 수 있게 해주는 바로 그 인프라임이 밝혀졌습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기