
그 SKILL.md, 다른 스킬과 트리거가 겹치지 않나요? 충돌과 깨진 참조를 CI에서 잡아내는 Linter를 만들었다
요약
Claude Agent Skills(SKILL.md)의 참조 정합성 오류와 트리거 문구 중복을 검출하는 Linter인 'skills-lint'를 소개합니다. 의존성 없이 CI 환경에서 스킬 간의 충돌과 깨진 참조를 자동으로 잡아내어 에이전트 운영의 안정성을 높입니다.
핵심 포인트
- SKILL.md 내 파일 경로 참조 정합성 검증
- 스킬 간 발화(trigger) 문구 유사도 기반 충돌 검출
- Jaccard 유사도를 활용한 가벼운 유사도 판정
- 의존성 없는 설계 및 GitHub Action 지원
Claude의 Agent Skills (SKILL.md)를 쓰기 시작했을 때, 나는 쾌적했다. 곤란해진 것은 스킬이 5개, 10개로 늘어난 뒤부터다. 두 가지 불안이 생겨났다.
하나는 참조의 부패다. SKILL.md에 "전처리는 scripts/extract.py를 사용한다"라고 적어두었는데, 나중에 그 스크립트의 이름을 변경했다. SKILL.md는 여전히 옛날 경로를 가리키고 있다. 아무도 눈치채지 못한다. 에이전트는 그것을 믿고 움직인다.
또 하나는 더 까다로운 문제인데, 스킬끼리의 "발화(trigger) 중복"이다. 스킬은 description의 트리거 문구로 호출된다. 비슷한 설명의 스킬을 두 개 두면, 동일한 입력에서 어느 쪽이 기동될지 알 수 없게 된다. 게다가 조용히, 잘못된 쪽이 작동한다.
이 두 가지를 PR(Pull Request) 시점에 기계적으로 걸러내는 도구, skills-lint를 만들었다.
솔직히 말하겠다. 만들기 전에 "어차피 누군가 만들었겠지"라고 생각하며 찾아보았다. 예상대로 트리거 충돌 검출은 pulser와 같은 선행 도구가 이미 하고 있었다. 유료인 SkillCheck에도 유사한 기능이 있다. 여기서 나는 한 번 실망했다.
하지만 자세히 보니 틈새가 있었다. 충돌을 보는 도구는 참조 정합성(reference integrity)을 보지 않는다. 참조 정합성을 보는 도구는 npm 의존성이 있거나 유료다. "참조 정합성 + 충돌 검출 + 의존성 제로 + 무료로 매 PR마다 실행"을 하나로 묶은 것은 없었다.
그래서 묶었다. 그것이 skills-lint다.
검출하는 것은 세 가지다.
- 참조 정합성:
SKILL.md본문의scripts/run.py나[doc](references/guide.md)가 실제로 존재하는가. 언어는 불문한다. - frontmatter:
name이 소문자 하이픈 형식인가,description(발화 트리거)이 있는가. - 충돌: 두 스킬의
name이 중복되지 않는가(설치 충돌),description이 너무 비슷하지 않은가.
세 번째인 "너무 비슷함"의 판정에는 문자 바이그램(bigram) 유사도(Jaccard)를 사용했다. 형태소 분석과 같은 무거운 의존성을 도입하지 않아도 되고, 일본어 트리거 문구에서도 효과적이다. 임계값(threshold)은 0.7로 높게 설정하여 오검출을 방지했다.
일부러 비슷하게 만든 두 스킬을 넣으면 다음과 같이 나온다.
✗ examples/bad/summarizer-a/SKILL.md — 1건
:4 참조 `scripts/missing.py`가 존재하지 않습니다
examples/bad/summarizer-b/SKILL.md:1 description이 summarizer-a와 고유사 (0.94) — 동일한 입력에서 혼동될 우려가 있음
...
깨진 참조와 유사도 0.94의 충돌을 동시에 잡아내어 CI를 떨어뜨린다. 이것뿐이다.
로컬이라면 한 줄.
npx @hyuga/skills-lint # .claude/skills / skills를 자동 탐색
CI에 배치한다면 GitHub Action으로.
- uses: hyuga611/skills-lint@v1
with:
paths: .claude/skills
지적 사항은 PR에 인라인 주석(inline annotation)으로 나타나며, 작업(job)이 실패한다. 사람이 의식하지 않아도 매 PR마다 실행된다. 이것이 정착의 핵심이라고 나는 생각한다.
skills-lint는 이전에 만든 reflint (AGENTS.md / llms.txt의 참조 정합성 Linter)와 같은 방식으로 만들었다. 의존성 제로, 순수 함수인 scan과 CLI 분리, GitHub Action, PR 주석.
그 reflint도 같은 날 v0.2.0을 출시했다. llms.txt 안의 markdown 링크 대상이 리포지토리 내에 실제로 존재하는지 검증하는 기능이다. 기존의 llms.txt 도구들은 포맷 검사나 외부 링크의 생존 여부(liveness) 정도까지였다. 리포지토리 내의 참조 정합성을 CI에서 확인하는 것은 찾아볼 수 없었다. 이 부분은 경쟁자가 없다.
- reflint: https://github.com/hyuga611/reflint
스킬이 늘어나는 시대, 가장 조용한 사고는 "발화의 중복"과 "깨진 참조"다. 육안으로는 알아챌 수 없다. 그래서 CI로 잡아낸다.
- 리포지토리: https://github.com/hyuga611/skills-lint
npx @hyuga/skills-lint로 지금 바로 테스트 가능
같은 고통을 겪고 있는 분이 있다면, 꼭 사용해 보길 바란다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기