최종 상태가 아닌 추론 경로를 캡처하라
요약
AI 에이전트가 코드를 작성할 때 발생하는 '추론 경로(Reasoning path)'의 손실 문제를 해결하기 위한 문서화 전략을 제안합니다. 단순히 최종 결과물만 기록하는 것이 아니라, 결정 과정, 거절된 대안, 검증 로그 등을 포함하는 '다큐멘터리 수준'의 기록을 통해 미래의 디버깅과 에이전트의 연속성을 확보하는 방법을 다룹니다.
핵심 포인트
- 최종 상태(Final state)가 아닌 의사결정 과정(Reasoning path)을 기록하는 것이 핵심임
- CHANGES.md를 통해 작업 중 실시간으로 변경 사항, 이유, 거절된 대안, 검증 방법을 연대순으로 기록함
- docs/narrative/ 경로에 마이그레이션이나 장애 대응 같은 큰 흐름의 서사적 기록을 남김
- 이러한 기록은 미래의 AI 에이전트가 과거의 맥락을 이해하고 중복된 실수를 방지하는 데 필수적임
두 개의 파일, 하나의 원칙, 그리고 제 Claude Code 예산의 측정된 10-13%. 얼마 전, Claude Code를 사용하던 세션 도중, 저는 자정이 넘었을 때나 나올 법한 엉망인 영어로 반론을 입력했습니다: "are we using full netflix level doc uodsyed as ws go here ?" 제가 의도한 바는 이랬습니다: 우리가 진행하면서 Netflix 다큐멘터리 수준의 깊이로 문서를 업데이트하고 있는가, 아니면 '왜'를 제외하고 무엇이 바뀌었는지만 기록하는 게으른 버전을 하고 있는가? Claude는 Netflix 버전을 정확하게 추론해냈습니다. 그 시점부터 제 모든 프로젝트의 문서화 표준이 설정되었습니다. 그 세션은 제가 이제 '페이퍼 트레일 (paper-trail)'이라고 부르는 것의 기초가 되었습니다. 이는 Claude Code(그리고 CLAUDE.md를 준수하는 다른 모든 AI 코딩 에이전트)가 git-log 수준이 아닌 다큐멘터리 수준의 깊이로 문서를 작성하게 만드는 휴대 가능한 규칙 세트입니다. 이 포스트는 AI가 타이핑의 대부분을 수행할 때 이것이 왜 더 중요한지, 그리고 실제 실무에서 그 원칙이 어떤 모습인지에 관한 것입니다.
추론 경로 (Reasoning path)는 AI가 잃어버리는 것입니다
대부분의 문서는 최종 상태 (final state)를 캡처합니다. README는 시스템이 무엇을 하는지 말해줍니다. CHANGELOG는 어떤 버전이 출시되었는지 말해줍니다. 커밋 메시지는 어떤 파일이 변경되었는지 말해줍니다. 세션이 끝날 때 사라지는 것들은 다음과 같습니다:
- 옵션 C를 선택하기 전에 고려했던 세 가지 대안
- 원래 설계를 폐기하게 만든 운영자의 반론
- 수정 사항이 작동한다는 것을 확신시켜 준 검증 로그
- 240번 라인의 이상한 임시 방편을 설명해 주는 밤 11시의 잘못된 시작
- 무언가 고장 나기 전까지는 존재한다는 사실조차 몰랐던 의존성
직접 코드를 작성할 때는 이 지식이 약 일주일 동안 머릿속에 (비록 형편없는 상태일지라도) 머물러 있습니다. 그 이후에는 사라집니다. AI 에이전트가 타이핑의 대부분을 수행할 때는 이 격차가 더 심해집니다. 에이전트는 거절된 대안들에 대해 전혀 기억하지 못합니다. 6개월 후, 에이전트는 당신이 이미 거절했던 수정 사항을 자신 있게 제안합니다. 당신이 왜 그것을 거절했는지에 대한 기록이 없습니다. 추론 경로는 미래의 디버깅 (debugging)을 가능하게 만드는 핵심입니다. AI는 이를 동시에 더 가치 있게 만들면서도 더 취약하게 만듭니다.
두 개의 파일, 하나의 원칙
구조는 간단합니다.
리포지토리 루트의 CHANGES.md. 연대순 로그이며, 최신 항목이 상단에 위치합니다. 작업이 끝난 후가 아니라, 작업이 진행되는 과정에서 업데이트합니다. 각 항목은 무엇이 변경되었는지, 왜 변경되었는지, 무엇이 결정되었는지, 무엇이 거절되었는지, 어떻게 검증되었는지, 그리고 무엇이 아직 미결 상태인지(outstanding)를 다룹니다. 더 큰 흐름(arcs)을 위해서는 docs/narrative/<YYYY-MM-DD>-<topic>.md를 사용합니다. 마이그레이션(Migrations), 장애(incidents), 재작성(rewrites), 소스 온보딩(source onboarding) 등이 해당됩니다. 시작 상태, 트리거, 결정 사항, 거절된 대안, 단계(phases), 검증, 최종 상태, 무엇이 해결되었는지(unblocked)를 기록합니다. CHANGES.md는 인덱스(index)이고, docs/narrative는 이야기(story)입니다. 둘 다 일반 마크다운(plain markdown) 형식입니다. 둘 다 커밋(commit)됩니다. 둘 다 여러분의 도구와 미래의 에이전트(agent)가 grep(검색)할 수 있도록 설계되었습니다.
실제 CHANGES.md 항목 예시. 몇 주 전 진행된 Music sync 복구 작업의 항목입니다 (식별자는 익명화되었으나 구조는 실제와 동일합니다):
2026-05-16: iOS Settings 뷰의 Music sync 행 복구
2026-05-04의 백엔드 통합(backend consolidation) 이후, iOS Settings 뷰에서 사용자에게 Music sync를 노출하던 행이 사라졌습니다. 백엔드의 동기화 파이프라인(sync pipeline) 자체는 온전했으나, 정리 과정에서 토글(toggle)만 제거된 상태였습니다. App/Views/SettingsView.swift의 6줄 코드를 통해 "Data Sources" 아래에 해당 행을 다시 추가하여 복구했습니다. TestFlight 빌드 47에 복구된 행이 포함되어 배포되었습니다. 기기에서 새로운 동기화를 실행하고, 전달된 UUID 8b4f2a9c-7d15-4e83-9bcd-12fa8e5c61d4가 백엔드에 도달한 것을 확인하여 엔드 투 엔드(end-to-end)로 검증했습니다. 결정 사항: Settings 뷰를 재설계하는 대신 행을 있는 그대로 복구하기로 함 (통합의 근거가 이 행에는 적용되지 않음). 거절된 대안: Music을 별도의 "Media" 섹션으로 이동하는 것. 단 하나의 소스를 위해 재설계해야 할 영역(surface area)이 너무 넓음. 미결 사항: 다음 주 오디오 경로를 위한 새로운 Qwen 커밋 a3f2c8e91 연결하기. commit e74b2c1
한 단락과 6줄의 코드 블록, 그리고 4줄의 메타데이터로 구성됩니다. 휴면 상태였던 파이프라인, 배포된 빌드, 리포지토리 간 의존성(cross-repo dependency), 거절된 대안을 명시합니다. 이것이 인덱스 항목입니다. 내러티브(narrative) 문서는 그 이야기를 들려줍니다.
내러티브 문서와 동일한 이벤트 제목: "음악을 다시 불러온 설정 행 (The Settings Row That Brought Music Back)", 경로: docs/narrative/2026-05-16-music-resurrection.md. 섹션 구성: 트리거 (The Trigger): 무엇이 Music 동기화가 중단되었음을 인지하게 했는가 (매일 데이터가 있어야 하는 소스에서 테스트 쿼리가 0개의 행을 반환함), 차이점 (The Diff): 원래의 통합(consolidation) 작업이 실제로 삭제한 내용과 해당 라인 번호, 발생할 뻔했던 일 (What Almost Happened): 단 6줄의 Swift 코드가 정답임을 깨닫기 전에 고려했던 redesign-the-whole-view 경로, 검증 (Verification): 해당 경로가 엔드 투 엔드(end-to-end)로 연결되었음을 증명하는 delivery UUID, 해제된 차단 요소 (What's Unblocked): Music이 활성화되어야만 진행할 수 있었던 오디오 경로(audio path) 작업. 이것은 마치 다큐멘터리 에피소드처럼 읽힙니다. 트레이드오프 (Tradeoffs), 잘못된 시작 (false starts), 운영자의 결정, 검증 수치들. 그 누구라도 (미래의 나를 포함하여, 미래의 에이전트(agent)를 포함하여) 문서만으로 추론 경로(reasoning path)를 재구성할 수 있습니다.
첫날 설치하기
전체 내용은 github.com/niclydon/paper-trail 에 있습니다. MIT 라이선스이며, 바로 사용할 수 있습니다. DOCUMENTARY_STYLE_DOCUMENTATION.md 파일을 프로젝트 루트(예: ~/projects/)에 복사하세요. 최상위 CLAUDE.md 파일에 @DOCUMENTARY_STYLE_DOCUMENTATION.md를 추가하세요. 각 프로젝트의 CLAUDE.md에는 templates/per-project-boilerplate.md에 있는 프로젝트별 보일러플레이트(boilerplate)를 붙여넣으세요. 각 프로젝트 루트에 빈 CHANGES.md 파일을 생성하세요. 처음으로 발생하는 사소하지 않은 마이그레이션(migration)이나 인시던트(incident) 발생 시, 제공된 스켈레톤(skeleton)을 사용하여 내러티브 문서를 작성하세요. 그러면 Claude는 해당 트리 내의 다음 세션부터 CHANGES.md 항목을 추가하기 시작할 것입니다. 서브 에이전트(sub-agents)나 컨텍스트가 제한된 세션을 위해 규칙 세트의 -LITE 변형(약 75% 더 작지만 동일한 규율 적용)도 제공됩니다.
비용
솔직한 답변을 위해서는 두 가지 측정을 해야 합니다. 첫 번째: Claude Code에서 /status를 확인할 때, 나의 /narrative-docs-update 슬래시 명령어가 주간 Claude Pro Max 플랜 사용량의 약 9%를 차지합니다. 이것이 명확하게 귀속될 수 있는 비용입니다. 내러티브 문서를 작성하거나 업데이트하기 위해 의도적으로 이 기술을 호출할 때마다 해당 수치에 합산됩니다. 두 번째는 측정하기 더 어렵습니다.
CHANGES.md 추가 작업은 별도의 기술 호출(skill invocation)이 아니라 일반적인 세션 중에 인라인(inline)으로 발생합니다. 이는 일반적인 사용 흐름에 녹아들어 있으며, /status 명령의 개별 항목으로 나타나지 않습니다. 이를 측정할 수 있는 유일한 방법은 콘텐츠 자체를 살펴보는 것입니다. 그래서 직접 계산을 해보았습니다. 지난 30일 동안 1,737개 세션에서 발생한 158,000개의 Claude Code 메시지를 대상으로, CHANGES.md, docs/narrative/, 또는 docs/migrations/ 경로를 참조한 모든 어시스턴트 출력의 글자 수를 합산했습니다. 결과는 다음과 같습니다. 총 920만 자 중 116만 자였습니다. 지난 30일 동안 Claude Code가 작성한 전체 출력의 12.6%가 문서 작업에 사용되었습니다. 두 측정값이 수렴합니다. 전용 기술(dedicated skill)을 통해 명확히 집계된 9%는 최솟값(floor)이며, 12.6%는 인라인 문서 작업까지 포착하는 더 넓은 신호입니다. Claude Code 출력의 1013%라고 부를 수 있습니다. 저를 놀라게 한 부분은 이 작업이 균일하게 적용되지 않는다는 점입니다. 제 세션 중 단 11.5%만이 문서 작업을 포함했습니다. 나머지 88.5%는 CHANGES.md나 내러티브 문서에 전혀 손을 대지 않았습니다. 이들은 빠른 질의(quick queries), 탐색, 또는 일회성 작업들입니다. 문서 작업이 나타나는 곳은 실질적인 세션들입니다. 즉, 실제로 기록할 가치가 있는 무언가를 구축하거나, 마이그레이션하거나, 디버깅한 세션들입니다. 문서 작업이 포함된 세션은 어시스턴트 출력이 평균 약 50,000자였습니다. 문서 작업이 없는 세션은 평균 약 850자였습니다. 문서화 노력은 작업 노력에 비례하여 확장되며, 이것이 바로 우리가 원하는 방향입니다. 다음 세 가지 이유로 인해 1013%의 비중은 제 Claude Code 플랜에서 가장 가치 있는 지출이 됩니다: 1. 출력물이 영구적입니다. Claude 출력의 나머지 약 88%는 세션이 종료되면 사라지는 휘발성(ephemeral) 채팅입니다. 그 약 12%는 지속되고, 커밋(commit)되며, 참조 가능한 마크다운(markdown) 파일입니다. 2. 에이전트(agent)는 자신이 무엇을 구축했는지 기억하지 못합니다. 이러한 문서가 없다면, 다음 세션에서는 무엇이 거부되었는지, 왜 거부되었는지, 또는 어떤 검증을 거쳤는지 알 방법이 없습니다. 나중에 추론 과정을 재구성하는 비용은 지금 기록하는 비용보다 더 많이 듭니다. 최근의 디버깅 사례가 이를 구체적으로 보여주었습니다. 몇 주 전, 백엔드 통합 이후 iOS 파이프라인이 작동을 멈췄습니다.
원래의 통합 작업에서 작성된 CHANGES.md 항목은 Settings 뷰에서 정확히 어떤 행이 왜 삭제되었는지 저에게 알려주었습니다. 그 기록이 없었다면 저는 한 시간 동안 추적 디버깅 (trace-debugging)을 하며 시간을 허비했을 것입니다. 하지만 그 기록 덕분에, 복구하는 데 단 여섯 줄의 Swift 코드면 충분했습니다. 이러한 규율을 지키는 비용은 작습니다. 하지만 이를 건너뛰었을 때의 비용은 기록이 꼭 필요한 순간에 그 기록이 없을 때 나타납니다. 보상은 확실합니다. 두 개의 파일, 하나의 규율, 그리고 제 Claude Code 예산의 10~13% 정도가 들었습니다. 그 대가로 얻은 것은 모든 사소하지 않은 결정에 대한 검색 가능한 기록, 대안들에 대한 거절 근거 (rejection rationale), 그리고 모든 세션 리셋 (session reset) 상황에서도 살아남는 검증 수치들입니다. AI는 문서화 (documentation)의 필요성을 없애지 않습니다. 오히려 AI가 더 많은 타이핑을 수행하기 때문에 추론 경로 (reasoning path)를 더 가치 있게 만드는 동시에, 세션이 종료되면 에이전트가 모든 것을 잊어버리기 때문에 더 취약하게 만듭니다. 만약 AI가 코드의 대부분을 작성하게 할 생각이라면, AI와 당신 자신을 위해 종이 흔적 (paper trail, 기록)을 남기십시오. 바로 사용할 수 있는 리포지토리 (repo): github.com/niclydon/paper-trail . MIT 라이선스입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기