CLAUDE.md가 너무 길어졌을 때: AGENTS.md, Skills, CI의 경계를 다시 나눠봤다
Codex나 Claude Code 같은 Coding Agent를 오래 쓰면 AGENTS.md와 CLAUDE.md가 길어지는 것은 꽤 자연스러운 일입니다. 처음 설계를 잘못해서라기보다 실제 작업에서 문제가 한 번 생길 때마다 규칙이 하나씩 늘어나기 때문입니다.
Agent가 요청 범위 밖의 파일을 건드리면 “관련 없는 파일은 수정하지 말 것”을 추가합니다. 테스트를 실행하지 않고 완료했다고 하면 “실제 검증 결과를 보여 줄 것”을 추가합니다. migration 실패 뒤에 디버깅할 증거까지 정리해 버리면 cleanup을 제한하는 규칙을 하나 더 넣습니다. 각각은 합리적이지만, 몇 달 뒤 root instruction은 개발 규칙, 장애 메모, workflow, 주의사항이 한데 섞인 내부 핸드북처럼 변합니다.
제가 더 신경 쓰였던 것은 줄 수 자체가 아니라 거의 모든 규칙이 always-on이 된다는 점이었습니다. README 한 줄을 고쳐도 frontend 경계, release 절차, protocol 제약, database migration 주의사항이 함께 따라옵니다. 같은 규칙이 root에도 있고 Skill에도 있고 docs에도 있고 CI에도 생기기 시작하면 “문서화돼 있는가”보다 “누가 이 규칙의 실제 owner인가”가 더 중요한 문제가 됩니다.
그래서 Nession의 issue #1437이 눈에 들어왔습니다. 이 repository의 root CLAUDE.md는 약 760줄까지 커져 있었고, 단순히 문장을 줄이는 대신 root guidance, scoped owner, Skills, executable Gate로 책임을 다시 나누는 migration을 진행했습니다. 구현은 PR #1442에 들어갔습니다.
하지만 저는 이걸 “4계층 구조가 정답”이라는 글로 만들고 싶지는 않았습니다. 궁금했던 것은 더 실용적인 부분이었습니다. 분리한 뒤 always-on surface가 실제로 얼마나 줄었는지, 그 경계를 CI가 지킬 수 있는지, 그리고 지금의 Codex / Claude Code instruction loading이 예전 글에서 반복되던 가정과 여전히 같은지 보고 싶었습니다.
그래서 migration 전후의 고정 commit을 GitHub API로 읽어 직접 다시 측정했고, 제 Content Lab에는 작은 instruction-contract validator를 따로 만들었습니다. 그렇게 해 보니 “CLAUDE.md는 몇 줄 이하가 좋은가”보다 더 오래 남는 질문이 하나 있었습니다.
이 규칙의 owner는 누구인가. 언제 필요한가. 그리고 기계적으로 검증할 수 있는가.
진짜 문제는 760줄이라는 숫자 자체가 아니다
줄 수가 싫은 것뿐이라면 파일을 쪼개면 됩니다. CLAUDE.md의 700줄을 다른 파일로 옮겼는데 그 파일도 모든 task에서 항상 읽힌다면, 보기만 깨끗해졌을 뿐 구조는 거의 달라지지 않습니다.
저는 root instruction을 “거의 모든 task가 실제로 필요로 하는 최소 공통 계층”으로 보는 편이 더 낫다고 생각합니다. 프로젝트의 최상위 목표, 안전 경계, 더 깊은 instruction을 찾는 방식, 모든 변경에 공통으로 적용되는 검증 원칙은 root에 둘 수 있습니다. 반대로 web/ 안에서만 성립하는 규칙은 그 directory 가까이에 있는 것이 자연스럽습니다. staging release나 code review처럼 반복 실행하는 절차라면 Skill에 가깝습니다. root budget, 중복 Skill name, 깨진 compatibility link처럼 프로그램이 명확하게 판정할 수 있는 규칙이라면 저는 prose를 한 줄 더 쓰기보다 CI가 막게 하고 싶습니다.
결국 질문은 “AGENTS.md와 CLAUDE.md를 어떻게 나눌까?”보다 “각 instruction surface는 무엇을 소유하는가?”에 가까워집니다.
root는 하나의 owner입니다. scoped instruction은 다른 owner입니다. Skill은 반복 workflow를 연결합니다. docs는 항상 context에 둘 필요가 없는 배경과 설명을 보관합니다. 그리고 machine-checkable한 제약은 code와 CI가 소유합니다.
그래서 “모든 것을 Skill로 옮기자”도 답이라고 생각하지 않습니다. Skill도 얼마든지 또 다른 백과사전이 될 수 있습니다. 지금은 규칙 하나를 보면 아주 평범한 질문부터 합니다. README만 수정하는 task에도 이 규칙이 필요한가? 특정 directory에 들어가야만 필요한가? 반복 workflow인가? 모델에게 물어보지 않아도 software가 유효성을 판단할 수 있는가?
Nession migration의 가치도 지식을 없앤 데 있지 않습니다. 지식이 더 적절한 위치를 갖게 됐습니다. root는 작아졌지만 scoped owner는 더 늘었습니다. 단순히 문서를 줄인 것과는 다른 변화입니다.
migration 전후 snapshot을 직접 다시 측정했다
PR에 적힌 숫자를 그대로 인용하지 않기 위해 Nession의 script는 실행하지 않았습니다. 대신 GitHub API로 두 개의 immutable SHA에 있는 tree와 blob만 읽었습니다. migration 전은 2d57f38ca917a327e5e4bdd7545d1e5dc90bc0bb, 후는 7d89c460ea302ea3eeb4380341055b6f2a1da39c 입니다. repository를 checkout하지 않았고 third-party hook, package script, workflow도 실행하지 않았습니다.
다시 계산한 결과 root instruction은 760줄에서 116줄로 줄었습니다. 약 84.74% 감소입니다. 문자 수는 55,160에서 5,734로 줄었습니다. 8개의 주요 Skill entrypoint는 합계 4,079줄에서 1,327줄로 줄어 약 67.47% 감소했습니다.
| 지표 | migration 전 | migration 후 | 감소율 |
|---|---|---|---|
| root instruction 줄 수 | 760 | 116 | 84.74% |
| root decoded characters | 55,160 | 5,734 | 89.60% |
| 8개 Skill entrypoint 줄 수 | 4,079 | 1,327 | 67.47% |
| 8개 Skill entrypoint characters | 161,324 | 42,710 | 73.53% |
이 표를 그대로 성능 수치처럼 읽으면 안 됩니다. migration 뒤에 repository의 규칙이 116줄만 남았다는 뜻도 아니고 token 비용이 84% 줄었다는 증거도 아닙니다. migration 뒤에는 root, Web, protocol, agent runtime, design, scripts, GitHub workflows, docs 각각에 canonical AGENTS.md owner가 있습니다.
지식은 남아 있습니다. 달라진 것은 모든 지식을 every task의 default context에 넣지 않게 됐다는 점입니다.
저는 이 부분이 progressive loading의 핵심이라고 봅니다. CLAUDE.md를 짧게 만드는 것이 목적이 아니라 always-on layer를 작게 유지하고 task-specific knowledge를 실제로 필요한 위치에 더 가깝게 두는 것입니다. 장기 유지보수에서는 줄 수보다 locality가 더 중요합니다.
이 migration을 보면서 구조 자체도 작은 실험으로 만들었습니다. Content Lab의 validator는 Nession 전용 path를 모르고 abstract instruction graph만 봅니다. root budget 초과, editable compatibility copy, 깨진 local link, 중복 Skill name, frontmatter 누락, canonical owner가 없는 scoped compatibility file, 존재하지 않는 target을 가리키는 symlink 등을 검사합니다.
positive / negative fixture를 각각 만들어 8개 케이스를 돌렸고 모두 예상한 error를 냈습니다. 복잡한 구현은 아니지만 오히려 이 점이 중요했습니다. instruction architecture의 위생을 지키는 일 중 상당 부분은 사람의 기억이 아니라 몇백 줄도 안 되는 deterministic code로 충분히 막을 수 있습니다.
Codex와 Claude Code 때문에 compatibility layer가 생각보다 단순하지 않다
여기까지 오면 다음 구조를 정답처럼 쓰고 싶어집니다.
AGENTS.md
CLAUDE.md -> AGENTS.md
.agents/skills -> .claude/skills
Nession도 비슷한 compatibility surface를 사용하지만 저는 이것을 universal standard라고 쓰지 않겠습니다.
OpenAI의 현재 Codex prompting guide는 Codex가 상위 위치에서 working directory 방향으로 AGENTS.md를 읽고, 더 깊은 instruction을 뒤에 context에 넣는 동작을 설명합니다. 그래서 “작은 root + scoped AGENTS.md” 설계에는 공식 동작 기반이 있습니다.
반면 Skill path는 하나의 directory 이름으로 고정해 말하기가 어렵습니다. 현재 OpenAI 자료에는 제품이나 migration 경로에 따라 repo-scoped 구성 예시가 여러 형태로 등장합니다. Skill eval 글과 Claude Agent SDK migration guide를 보면 안정적으로 유지해야 하는 것은 특정 directory 이름보다 owner와 compatibility mapping이라는 점이 더 분명해집니다.
Claude Code 쪽도 계속 바뀌고 있습니다. 현재 memory / instruction 문서는 AGENTS.md를 직접 지원하고 CLAUDE.md는 간결하게 유지하도록 권장합니다. 대략 200줄 이하를 목표로 제시하고, path-scoped rule은 지역 제약에, multi-step workflow는 Skills에 더 어울립니다. Skills 문서 역시 Skill body를 필요할 때 읽는 progressive loading 방향입니다.
따라서 “Claude와 호환하려면 모든 프로젝트가 반드시 CLAUDE.md -> AGENTS.md를 유지해야 한다”는 결론은 너무 강합니다. 두 파일이 같이 있을 때는 version과 Project instructions 설정이 영향을 줄 수 있고, symlink는 macOS/Linux에서는 편하지만 Windows에서는 Git checkout과 편집 호환성을 따져야 합니다.
저라면 작은 compatibility matrix를 유지합니다. 어떤 파일이 canonical owner인지, 어떤 surface가 adapter인지, 현재 client version이 실제로 어느 Skill path를 discovery하는지, Windows fallback은 무엇인지 명확히 적습니다. path는 구현 세부이고 owner가 architecture입니다.
지금 repository를 다시 정리한다면 “무엇을 쓸까”보다 “누가 소유할까”부터 본다
Coding Agent를 막 쓰기 시작한 작은 프로젝트라면 처음부터 instruction directory를 열 개씩 만들 필요는 없습니다. 몇십 줄 AGENTS.md로 충분하면 그대로 유지하는 편이 낫습니다.
정말 refactor할 시점은 신호가 반복될 때입니다. root가 내부 매뉴얼처럼 커지고, 같은 규칙이 root / Skill / docs에 복제되고, 특정 directory의 요구가 관계없는 task에 간섭하고, agent가 한 번 실패할 때마다 유일한 대응이 “prompt에 한 줄 더 추가”가 되는 순간입니다.
그때부터는 규칙별 owner를 정합니다. global constraint는 root, directory 고유 invariant는 그 근처, 반복 절차는 Skill, 긴 배경 설명은 docs, 확정적으로 판정할 수 있는 제약은 validator / CI로 보냅니다.
특히 high-risk rule을 자연어만으로 남기고 싶지는 않습니다. migration 실패 후 증거를 지우면 안 된다거나, release 전에 특정 gate를 반드시 통과해야 한다거나, 특정 directory에 mock implementation이 들어가면 안 되는 규칙은 실패 비용이 큽니다. Prompt는 이유를 설명하고 Skill은 절차를 안내할 수 있지만 마지막 guardrail은 가능한 경우 executable해야 합니다.
이번 experiment가 증명하는 범위는 여기까지입니다. Nession의 root와 Skill entrypoint가 구조적으로 크게 줄었다는 것, 그리고 작은 instruction-graph validator가 대표적인 regression을 잡을 수 있다는 것은 확인했습니다. 하지만 인증된 Codex / Claude Code client를 이용한 전체 task benchmark는 실행하지 않았기 때문에 성공률이 몇 % 올랐다거나 token 사용량이 몇 % 줄었다고 말하지 않습니다.
그래도 제 습관 하나는 바뀌었습니다. AGENTS.md나 CLAUDE.md가 다시 길어지기 시작하면 “이 500줄을 더 잘 쓰는 법”을 먼저 고민하지 않습니다. 그중 몇 줄이 애초에 always-on일 필요가 없는지부터 봅니다.
Codex 자체가 workflow layer를 어떻게 키우고 있는지 보고 싶다면 새 Codex는 무엇이 달라졌나: 이제 왜 개발 환경에 더 가까운가가 자연스럽게 이어집니다. 모델 바깥의 permission, context, memory, guardrail 쪽이 더 궁금하다면 Claude Code 소스 유출에서 배울 수 있는 Harness Engineering이 이 글과 더 가깝습니다.