
왜 Claude Code Skills의 설정을 프로젝트 외부에 두는가
요약
Claude Code Skills의 재사용성을 높이기 위해 설정을 프로젝트 외부로 분리하는 설계 원칙을 설명합니다. 3층 컨피그 머지(3-layer config merge) 구조를 통해 스킬 본체와 프로젝트별 고유값을 효율적으로 관리하는 방법을 다룹니다.
핵심 포인트
- 스킬 로직과 프로젝트 고유값(GA4 ID 등)의 분리 필요성
- 3층 컨피그 머지: 스크립트 기본값, 글로벌 설정, 프로젝트 설정 구조
- jq를 활용한 딥 머지(Deep Merge)로 중첩된 객체 설정 관리
- 설정 외부화를 통한 스킬의 유지보수성 및 재사용성 향상
이 기사는 playpark Blog에서 전재되었습니다.
- 스킬을 프로젝트 간에 재사용할 수 없는 근본 원인
- 3층 컨피그 머지(Config Merge)라는 설계의 의도
- 글로벌 설정과 프로젝트 설정을 어떻게 구분하여 사용하는가
Claude Code Skills는 반복적인 작업을 AI 워크플로우로 정의하는 메커니즘입니다. GA4 분석, SNS 게시글 생성, 기사 공개 플로우——각각을 Skill로 작성해 두면 어떤 프로젝트에서도 호출할 수 있습니다.
있어야 했습니다.
실제로는 스크립트 안에 프로젝트 고유값이 직접 작성(Hard-coded)되어 있습니다:
PROPERTY_ID="123456789" # 이 프로젝트의 GA4 ID
SITE="sc-domain:example.com" # 이 프로젝트의 GSC URL
두 번째 프로젝트에서도 동일한 스킬을 사용하려면 값을 수정하여 복사/붙여넣기 할 수밖에 없습니다. 그렇게 되면 동일한 스킬이 두 개로 분열되어, 한쪽만 버그 수정이 이루어지는 상황이 발생합니다.
"자동화 도구를 수동으로 이식한다"는 모순이 발생하고 있었습니다.
프로젝트 간에 설정을 구분하여 사용하는 방법은 몇 가지가 있습니다:
| 접근 방식 | 개요 | 문제점 |
|---|---|---|
| 복사/붙여넣기하여 값을 수정 | 스킬마다 프로젝트용 복사본을 생성 | 스킬이 분열되어, 버그 수정이 모든 스킬에 파급되지 않음 |
| 환경 변수로 전달 | .env 파일에 모든 설정을 작성 | .env가 비대해지며, "어느 것이 어떤 스킬용인지" 불분명함 |
| 설정 파일로 외부화 | 스크립트 외의 JSON에서 설정을 읽음 | 도입 비용은 발생하지만, 스킬 본체는 공통 상태를 유지 |
세 번째 방식을 체계화한 것이 skill-config.json에 의한 3층 컨피그 머지(3-layer config merge)입니다.
근본적인 질문은 "무엇이 변하고, 무엇이 변하지 않는가"의 구분입니다.
변하지 않는 것 (스킬 본체):
- 스크립트의 로직
- Claude에 대한 지시서
- 에러 핸들링 (Error Handling)
변하는 것 (프로젝트 고유값):
- GA4 프로퍼티 ID
- 도메인 이름
- 출력 디렉토리
"변하는 것"만 외부에 빼두면, 스킬 본체는 한 번만 작성하면 됩니다.
외부로 뺀 설정을 어디에 둘 것인가에도 의도가 있습니다:
스킬 내장 기본값 ← 글로벌 설정 ← 프로젝트 설정
(최저 우선순위) (사용자 공통) (최우선 순위)
| 계층 | 경로 | 배치 내용 |
|---|---|---|
| 글로벌 | ~/.config/skills/config.json | 타임존, 언어, SNS 기본값 |
| 프로젝트 | <project>/skill-config.json | GA4 ID, 도메인 이름, 출력 위치 |
| 기본값 | 스크립트 내의 초기값 | 폴백(Fallback) 값 |
글로벌 설정은 "어느 프로젝트에서나 동일한 값"만을 둡니다. 타임존은 Asia/Tokyo, 게시 언어는 ja, SNS 게시 대상은 기본적으로 X와 LinkedIn입니다. 이것들을 프로젝트마다 다시 작성할 이유가 없습니다.
프로젝트 설정은 "이 프로젝트만의 값"만을 둡니다. GA4 프로퍼티 ID는 당연히 프로젝트마다 다릅니다.
source "$SKILLS_DIR/_lib/common.sh"
config=$(load_skill_config "ga-analyzer")
# 글로벌 + 프로젝트의 머지된 설정을 얻을 수 있음
...
내부에서는 jq의 * 연산자를 사용하여 딥 머지(Deep Merge)를 구현하고 있습니다:
echo "$global_cfg" | jq --argjson proj "$project_cfg" '. * $proj'
딥 머지(Deep Merge)를 선택한 이유는 중첩된 객체의 일부만을 덮어쓰기 위해서입니다. 섀로우 머지(Shallow Merge)를 사용하면 중첩된 객체 전체가 덮어씌워져, 글로벌 설정의 대부분이 사라지게 됩니다.
이 설계가 효과를 발휘하는 것은 "동일한 스킬을 여러 프로젝트에서 재사용하고 싶을 때"입니다.
스킬이 1~2개이고 프로젝트도 하나라면 직접 작성하는 것으로 충분합니다. 여러 프로젝트에 걸쳐 있고, 스킬이 늘어남에 따라 설정 관리 비용이 상승하는 단계에서 도입을 검토하는 것이 현실적입니다.
반대로, 이 설계를 도입해 두면 "새로운 스킬을 작성하는 심리적 장벽이 낮아지는" 이차적인 효과가 있습니다. 어떤 프로젝트에서도 동작한다는 것을 알고 있다면, 하나의 스킬을 작성하는 투자의 회수처가 늘어나기 때문입니다.
이 기사에서는 3층 설정 병합 (3-layer config merge)의 설계 의도를 해설했습니다.

Skills를 「어떤 프로젝트에서도 동작하는」 포터블 자산으로 만드는 설계 에서는 추가로:
_lib/
공유 라이브러리를 통한 중복 코드 제로화 구현 상세 - 외부 스킬 (skills.sh 등)의 심볼릭 링크 (symlink) 통합과
.gitignore
자동 관리 - 구형 설정 파일을 일괄적으로 이전하지 않고도 계속 동작하게 만드는 레거시 폴백 (legacy fallback) 메커니즘
을 다루고 있습니다.
playpark LLC - 업무 자동화 · AI 활용 · Web 개발
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기