본문으로 건너뛰기

AI 관련 문서를 하나의 저장소에서 일괄 관리할 수는 없을까?

  • claude-code
  • ai-documents
  • documents

저장소마다 흩어지는 AI 문서

Claude나 Codex를 사용하다 보면 AI 에이전트를 디렉터리별로, 저장소별로 실행하게 됩니다. 처음 AI를 도입하거나 새 저장소를 만들 때, 에이전트를 원활히 쓰기 위해 여러 가지 문서를 설정하게 되는데요, 저장소가 나뉘어 있으면 이 문서들을 정비하는 게 상당히 불편하게 다가왔습니다.

크게 불편했던 점은 다음과 같습니다.

  1. 좋은 스킬이나 에이전트가 있을 때, 다른 저장소에서도 쓰고 싶다면 일일이 복사해야 합니다.
    • 그래서 수정 사항이 생기면 매번 각 저장소에서 따로 고쳐야 합니다.
  2. 저장소의 작업 이력(Git 히스토리)에 AI 문서가 섞이기 시작합니다.
    • AI 문서도 주기적으로 최신화해야 하는데, 작업 저장소에 섞이다 보니 AI 문서 수정 사항을 기능 PR에 같이 넣어야 하는지, 별도 PR로 분리해야 하는지 같은 문제가 생깁니다.
    • 문서 작업도 PR 리뷰 범위에 들어가기 때문에, 점점 AI 문서 갱신이 뒤처지고 사용감도 나빠집니다.
  3. A 저장소와 B 저장소를 오가며 서로를 확인해야 할 때 문서 정비가 어렵습니다.
    • FE와 BE 저장소가 분리돼 있거나, BE도 API별로 저장소를 나눠 관리하는 경우가 그렇습니다. 매번 gh로 다른 저장소를 읽고 그 저장소의 AI 문서를 확인하느라 여러 단계를 거쳐야 해서 속도와 토큰 사용량 모두에 악영향이 있었습니다.

사람이 신경 써서 고치면 되는 거 아니냐… 라고 말할 수도 있겠습니다만, 저는 기본적으로 사람의 선의나 의식적인 노력에 기대는 게 그렇게 좋은 방법이라고 생각하지 않습니다.

귀찮아서 안 한다거나, 까먹는다거나, 실제 개발 업무가 바쁘다거나 하는 이유로 우선순위가 낮은 작업은 뒤로 밀릴 수밖에 없잖아요?

그렇다면 문서 구조를 어떻게 정비해야 사람의 인지 부담을 줄일 수 있을까요?

어떤 방식으로 관리할까

원하는 조건은 다음과 같았습니다.

  • 설정의 원본은 한 곳에서만 관리한다.
  • 공통 설정과 저장소별 설정을 나눌 수 있다.
  • 저장소를 클론한 위치가 저마다 달라도 동작한다.
  • 따로 설치할 의존성이 없다.

이 조건을 두고 몇 가지 방법을 검토해 봤습니다.

Git 서브모듈

처음 떠올린 건 서브모듈(git submodule)입니다. 서브모듈로 관리하면 위 조건을 달성할 수는 있습니다. 다만 다음 두 가지 단점이 꽤 크게 다가와서 결국 채택하지 않았습니다.

첫째, AI 문서를 업데이트하려면 서브모듈을 주기적으로 최신화해야 합니다. 서브모듈은 특정 커밋을 가리키는 구조라서 AI 문서가 갱신되면 서브모듈을 최신 커밋으로 올려야 하고 이 변경 또한 작업 저장소에 커밋해야 합니다.

둘째, AI 에이전트가 쓰는 워크트리(git worktree)와의 궁합입니다. 워크트리와 서브모듈의 궁합이 좋지 않다는 건 에이전트를 쓰면서 이미 알고 있었습니다. AI 문서를 서브모듈로 들여오면 워크트리를 만들 때마다 추가 설정이 필요할 거라고 판단했습니다.

참고: Worktrees with submodules (r/ClaudeCode)

심볼릭 링크

회사에서 나온 아이디어가 심볼릭 링크로 관리하자는 것이었고 괜찮아 보였습니다. 단점은 Windows 환경에서 쓰기 어려울 수 있다는 점이었는데, 회사 작업 환경은 전원 Mac이라 이 방식으로 도입했습니다.

상세 구조

DeveloperRyou/ai-documents

디렉터리 구조

ai-documents/
  repo.yaml              # 관리할 저장소 목록 (원격 주소 기준)
  install.sh             # 저장소 찾기 → _common 미러링 → 심볼릭 링크 생성
  update.sh              # git pull 후 install.sh 재실행
  uninstall.sh           # 만든 심볼릭 링크 제거
  projects/              # 공통 문서와 저장소별 문서 (아래에서 설명)

저장소를 경로가 아니라 원격 주소로 찾기

repo.yaml에는 이 공용 AI 문서를 설치할 저장소를 등록합니다. 이때 로컬 경로 대신 Git 원격 주소(remote)로 적습니다.

anchor: /opt/ai-documents

search_paths:
  - ~/Develop

repos:
  - name: portfolio
    remote: https://github.com/DeveloperRyou/portfolio.git

이후 ai-documents에서 install.sh를 실행하면 search_paths 아래를 훑어서 원격 주소가 일치하는 클론을 찾고 찾은 경로를 기기별로 캐시해 둡니다. 노트북과 데스크톱에서 저장소 위치가 다르거나, 팀원마다 저장소 위치나 이름이 달라도 search_paths 안에만 있으면 쓸 수 있게 하기 위해서입니다.

install.sh에서 심볼릭 링크를 두 번 거치는 이유

처음에는 각 저장소의 CLAUDE.md가 ai-documents 클론을 바로 가리키게 했는데, 이러면 ai-documents를 다른 위치에 다시 클론하는 순간 모든 링크가 깨집니다.

게다가 이 링크는 실제 작업 저장소에 커밋으로 들어가는 경로입니다. 개발자마다 달라지는 로컬 경로를 커밋하면 안 되기 때문에, 중간에 고정된 앵커 디렉터리를 하나 뒀어요.

<portfolio>/CLAUDE.md
  → /opt/ai-documents/checkout/projects/portfolio/CLAUDE.md
  → (checkout은 실제 ai-documents 클론을 가리키는 링크)

각 저장소의 링크는 항상 /opt/ai-documents/checkout을 거치기 때문에 ai-documents를 옮기면 checkout 링크 하나만 다시 걸면 되고 관리 대상 저장소 쪽은 아무것도 바꿀 필요가 없습니다.

이렇게 만든 링크는 관리 대상 저장소에 커밋해 둡니다. portfolio를 새로 클론해도 CLAUDE.md와 .claude가 링크로 딸려 오고 앵커만 준비돼 있으면 바로 동작해요.

_common과 저장소별 폴더

projects/
  _common/.claude/      # 모든 저장소 공통: RULES.md, 훅, 공통 스킬
  portfolio/            # portfolio 전용: CLAUDE.md, 전용 스킬
  ai-documents/         # ai-documents 자신의 CLAUDE.md

install.sh는 먼저 _common 아래 파일을 각 저장소 폴더에 하나씩 미러링하고 그다음 저장소 폴더를 통째로 실제 저장소에 링크합니다. 미러링된 링크는 ai-documents 저장소의 .git/info/exclude에 넣어서 커밋되지 않게 합니다.

이름이 겹치는 파일은 따로 처리해야 했습니다. CLAUDE.md는 저장소마다 내용이 달라서 _common이 덮어쓰면 안 됩니다. 그래서 공통 규칙은 _common/.claude/RULES.md에 두고 각 저장소의 CLAUDE.md 맨 위에서 한 줄로 불러와요.

@.claude/RULES.md

settings.json도 같은 문제가 있습니다. 공통으로 켜 둘 플러그인과 훅이 있는 한편, 특정 저장소에서만 쓰는 플러그인(Playwright, frontend-design)도 있습니다. 그래서 저장소 폴더에 settings.override.json을 두면, 공통 settings.json 위에 깊은 병합(deep merge)을 해서 최종 파일을 만들게 했어요.

규칙: main에 바로 커밋

ai-documents 자체는 브랜치나 PR 없이 main에 바로 커밋하고 푸시합니다. 코드가 아닌 문서를 고치는 데 PR까지 여는 건 과하고 리뷰 부담이 있으면 문서 갱신은 우선순위에서 밀려 빠르게 최신화되지 않습니다.

특히 AI 에이전트를 실행할 때마다 문서가 최신인지 아닌지 확인하고 실행해야 한다면, 그건 말이 안 되는 작업 흐름이라고 생각했어요.

이 규칙도 ai-documents의 CLAUDE.md에 적혀 있어서 Claude Code가 설정을 고칠 때 알아서 main에 커밋합니다.

회사에서는 상황에 따라 PR을 여는 식으로 설정해 뒀습니다. 초안(draft) 상태의 PR도 있고 기능 개발이 오래 걸리는 경우도 있어서 문서도 PR에 계류하는 걸 허용했습니다. 이 부분은 작업 상황에 따라 유연하게 가져가면 될 것 같아요.

AI 에이전트 세션이 시작될 때 자동으로 업데이트

공통 settings.json에 SessionStart 훅을 걸어서 Claude Code 세션이 열릴 때마다 update.sh가 돌게 했습니다. update.sh는 ai-documents를 git pull 하고 설치를 다시 실행하기 때문에 다른 저장소에서, 다른 개발자가 고친 규칙도 다음 세션부터 바로 적용됩니다.

제가 직접 뭘 실행할 필요가 없다는 게 이 문서 관리 방식의 포인트입니다.

스킬

_common에 쌓인 스킬은 이렇습니다.

  • backlog-issue: Why / What / Acceptance 형식으로 GitHub 이슈 작성
  • resolve-issue: 이슈 하나를 브랜치 생성, 구현, 로컬 모델 리뷰를 거쳐 PR까지
  • issue-status: 열린 PR과 이슈를 훑고 다음에 할 일 정리
  • handoff: 세션을 끊기 전에 10줄짜리 인수인계 노트 작성

이 외에도 계속 스킬을 추가하고 있는데, 스킬 이야기는 따로 다룰 때 더 자세히 써 보겠습니다.

장점이라고 느낀 부분들

공용 문서를 따로 관리하면서 느낀 장점은 역시 문서와 설정을 갱신하는 부담이 줄었다는 점입니다. 규칙을 한 곳에서 고치고 커밋하면 끝이라, “이거 불편한데” 싶을 때 바로 규칙이나 스킬로 만들면 됩니다.

실제 작업 저장소의 Git 히스토리가 오염되지 않게 된 것도 개인적으로 꼽는 장점입니다. 요즘은 AI 에이전트가 작업할 때 Git 히스토리도 읽고 코드 변경 이력도 파악하니까요.

다른 해결 방법은 없을까

사실 멀티레포 기반이 아니라, 모노레포 기반으로 작업하면 AI 문서를 정비하려고 심볼릭 링크를 도입한다거나… 하는 작업은 필요 없고 더 깔끔하게 해결될 것 같기도 합니다.

다만 이미 멀티레포 기반으로 구축된 프로젝트를 모노레포로 바꾸는 건 CI/CD도 걸려 있고 여러모로 공수가 들 것 같은데요. 그런 점에서 ai-documents는 지금의 저장소 체계를 유지하면서 문서를 쉽게 일괄 관리할 수 있는 방법이 아닐까 싶습니다.