


제대로 로드되고 트리거되는 AI 에이전트 스킬과 플러그인 만들기
AI 에이전트용 스킬이나 플러그인을 만들어 리뷰에 낼 때 씁니다. 메타데이터 정본을 하나로 두는 법, 디렉터리 배치, 잘 트리거되는 이름과 설명문, 빠른 훅, 리뷰 전에 통과할 체크리스트를 알려 줍니다.
이 AI 규칙을 사용하려면
## 공식 문서를 읽고 참조 스킬을 고쳐 쓰기
무언가를 쓰기 전에, 대상으로 삼는 플러그인·스킬 시스템의 현재 공식 문서를 먼저 읽는다. 플러그인 형식, 스킬 형식, 그리고 공개된 작성 모범 사례를 모두 본다. 벤더 문서는 어떤 서드파티 해설보다도 빠르게 바뀌므로, 벤더 문서를 진실의 출처로 삼고 커뮤니티 가이드는 그 위에 얹힌 주석으로 취급한다.
그다음, 필요한 복잡도 수준에 맞는 참조 스킬을 하나 골라 구조를 처음부터 설계하는 대신 그것을 변형해서 쓴다:
- 기본: 최소한의 프런트매터와 짧은 안내 블록, 그 외에는 아무것도 없다.
- 중급: 언어 패키지, references 디렉터리, 그리고 언어별 문서.
- 고급: 스크립트, 워크플로 파일, 템플릿, 추출 헬퍼, 그리고 여러 개의 진입점.
다른 팀의 실제 운영 플러그인을 두세 개 읽어 보는 편이 대개 구조를 새로 고안하는 것보다 빠르다. 환경이 플러그인·스킬 질문에 대해 문서를 참조하는 헬퍼 에이전트를 제공한다면, 기억에 의존해 답하지 말고 그런 질문은 그쪽으로 넘긴다.
## 여러 런타임이 플러그인을 읽어도 메타데이터 정본은 하나만 두기
여러 에이전트 런타임이 플러그인을 로드할 수 있는 경우, 메타데이터 형식 하나를 정본으로 정하고 런타임별 사이드카 사본을 추가하지 않는다. 중복된 메타데이터는 반드시 어긋나며, 그 어긋남은 CI가 아니라 사용자가 먼저 발견하게 된다.
실무에서는 이렇게 한다:
- 마켓플레이스 매니페스트와 플러그인별 매니페스트를 각자의 정본 위치 한 곳에만 둔다.
- 두 번째 런타임을 위해 런타임 전용 매니페스트 디렉터리나 플러그인 메타데이터 디렉터리를 병렬로 만들지 않는다.
- 두 런타임이 이미 이해하고 있는 기본 경로를 사용해, 모든 구성 요소를 플러그인 루트에 둔다: 스킬 디렉터리, 훅 파일, MCP 설정 파일, 그리고 앱 설정 파일.
- 플러그인에 MCP 설정이 필요하다면, 플러그인 매니페스트 안에 객체로 끼워 넣지 말고 플러그인 루트의 전용 MCP 설정 파일에 넣는다.
제출 전에 지원하는 각 런타임에 대해 로드 가능 여부 검사를 실행한다. 한쪽 런타임이 실패하면 정본 소스를 고쳐서 다른 런타임이 호환 경로를 통해 로드할 수 있게 한다. 같은 메타데이터의 두 번째 사본을 추가하는 방식으로는 절대 해결하지 않는다.
## 컴포넌트 디렉터리는 메타데이터 디렉터리가 아닌 플러그인 루트에 두기
플러그인 디렉터리에는 플러그인 매니페스트(이름, 버전, 설명, 작성자)만 담은 플러그인 메타데이터 디렉터리가 들어가고, 여기에 슬래시 명령·자율 에이전트·스킬·이벤트 훅을 위한 선택적 디렉터리들, 그리고 플러그인을 설명하는 README가 더해진다.
각 스킬은 스킬 디렉터리 아래 자신만의 디렉터리에 놓이며, 프런트매터를 담은 진입점 문서와 references·workflows·scripts를 위한 선택적 하위 디렉터리를 갖는다.
사람들이 가장 많이 걸려 넘어지는 규칙은 이것이다. 구성 요소 디렉터리 — 스킬, 명령, 에이전트, 훅 — 는 플러그인 메타데이터 디렉터리 안이 아니라 플러그인 루트에 있어야 한다. 그 안에 들어갈 것은 플러그인 매니페스트뿐이다. 로더와 리뷰어 양쪽 모두 이 규칙에 의존하며, 구성 요소 디렉터리를 잘못 둔 경우는 대개 아무것도 노출하지 않고 조용히 침묵하는 플러그인의 형태로 나타난다.
## 알기 쉬운 케밥 케이스 이름을 정하고 프런트매터 채우기
스킬 진입점의 프런트매터에는 최소한 이름과 설명이 필요하다. 선택 항목인 허용 도구 목록은 스킬을 정말로 필요한 도구로만 제한하며, 스킬의 범위가 좁을 때에는 언제나 설정해 둘 가치가 있다.
- 이름은 케밥 케이스로 쓰고, 길이 제한(보통 64자) 안에 들어가게 한다.
- 설명은 3인칭으로 쓰고, 그 스킬이 무엇을 하는지와 언제 써야 하는지를 둘 다 밝힌다.
- 이름은 동명사 형태를 선호한다. "analyzing-contracts"나 "processing-pdfs"처럼 동사가 앞에 오는 이름이 "contract-analyzer"나 "pdf-processor" 같은 행위자 명사형 이름보다 잘 읽힌다.
- helper, utils, tools, misc처럼 모호한 이름은 피한다. 이런 이름은 모든 것에 매칭되면서 아무 의미도 없다.
- 런타임이 특별하게 취급할 수 있는 예약어는 피한다. 벤더명과 제품명도 여기에 포함된다.
## 설명문에 스킬이 하는 일과 쓰는 때를 적기
당신의 스킬은 수백 개의 다른 스킬과 주목을 두고 경쟁하며, 에이전트가 그 스킬을 로드할지 판단할 때 읽는 텍스트는 대개 설명문 하나뿐이다. 모호한 설명문은 스킬이 쓰이지 않은 채 방치된다는 뜻이고, 더 나쁘게는 엉뚱한 상황에서 발동한다는 뜻이다.
- 3인칭 어조로: "I help with X"가 아니라 "Analyzes X".
- 주제만이 아니라 발동 상황을 담는다: "Use when auditing smart contracts"는 "Smart contract tool"보다 훨씬 많은 라우팅 신호를 전달한다.
- 능력을 구체적으로 밝힌다: "Detects reentrancy vulnerabilities"가 "Helps with security"보다 낫다.
설명문은 실제로 그것이 담당하는 라우팅 규칙 그 자체라고 여기고 쓴 다음, 경쟁하는 다른 스킬이 같은 요청을 가져가 버리지 않을지 자문하며 다시 읽는다.
## 절대 경로를 박지 않고 스크립트 의존성을 스크립트 안에 선언하기
절대 경로를 하드코딩하지 않는다. 런타임이 제공하는 기준 디렉터리 변수를 쓰고, Windows에서도 슬래시(/)를 사용해 같은 스킬이 어떤 머신에서도 동작하게 한다.
스킬이 의존성을 가진 스크립트를 함께 배포할 때는 이렇게 한다:
1. 해당 언어의 표준 인라인 메타데이터 블록을 사용해 스크립트 헤더에 의존성을 인라인으로 선언하고, 최소 언어 버전도 함께 적는다. 이렇게 하면 러너가 별도의 설치 단계 없이 모든 것을 해결할 수 있다.
2. 그 인라인 메타데이터를 존중하는 러너를 통해 스크립트를 호출해, 의존성 해결이 문서에 적힌 사전 준비 사항이 아니라 자동으로 이루어지게 한다.
3. 린터나 포매터 같은 개발 도구를 위한 프로젝트 파일을 scripts 디렉터리에 둔다.
4. 언어 패키지 관리자가 설치할 수 없는 시스템 수준 의존성 — 예를 들어 PDF 및 OCR 도구 — 은 플랫폼별 설치 명령과 함께 워크플로 파일에 문서화한다.
## 모든 명령 전에 도는 훅을 빠르게 유지하기
모든 명령보다 앞서 실행되는 훅은 핫 패스 위에 있으므로, 그 비용은 단 한 번의 호출마다 빠짐없이 지불된다. 여기서 성능은 있으면 좋은 것이 아니라 정확성의 문제다.
- 완전한 인터프리터보다 셸에 가벼운 JSON 필터를 조합한 쪽을 선호한다. 인터프리터와 파서의 기동은 사용자가 매 명령마다 체감하는 지연을 더한다.
- 빠르게 실패시킨다: 명백히 해당하지 않는 명령에 대해서는 즉시 성공으로 종료해, 압도적 다수의 호출이 사실상 공짜가 되게 한다.
- 완전한 구문 트리 파싱보다 정규 표현식을 택한다. 성능 이득이 크고 에이전트가 명령을 다시 표현하기만 하면 되는 상황이라면, 드물게 발생하는 오탐은 감수한다.
- 오탐이 어떤 형태로 나타날지 미리 예상한다: 단지 인터프리터의 위치를 찾을 뿐인 진단 명령, 그 이름을 검색어로 언급하는 검색 명령, 그리고 그 이름을 포함한 파일명 — 이런 것들은 가로채기를 발동시켜서는 안 된다.
- 이런 절충들을 변경 설명에 문서화해, 리뷰어가 그 선택이 허술한 것이 아니라 의도적이었음을 알 수 있게 한다.
## 사양을 통째로 붙이지 말고 언제·왜 찾아볼지 가르치기
스킬은 모델이 이미 갖고 있지 않은 지침을 제공해야 한다. 명세 전체를 스킬에 붙여 넣는 것은 컨텍스트만 태울 뿐, 모델이 스스로 찾아볼 수 있는 것 이상을 더해 주지 않는다.
- 명세 전체나 API 레퍼런스를 붙여 넣지 않는다. 대신 언제, 어떻게 찾아봐야 하는지를 가르친다.
- 무엇인지만이 아니라 왜인지를 설명한다: 절충점, 판단 기준, 그리고 초심자라면 틀리기 쉬운 판단 지점을 담는다.
- 안티패턴은 금지 항목만 나열하지 말고, 그것이 왜 잘못되었는지 이유와 함께 문서화한다.
이 패턴의 좋은 예가 있다. 복잡한 바이너리 디버그 형식을 다루는 스킬은 그 형식 명세를 안에 담지 않는다. 대신 어떤 검사 도구를 꺼내 써야 하는지, 그 도구에 어떻게 질의하는지, 그리고 어떤 질문에는 어떤 도구가 적절한지를 가르친다.
## 작업 위험도에 맞춰 엄격함을 정하고 쓰지 말아야 할 때도 적기
스킬이 얼마나 엄격해야 하는지는 그 작업이 얼마나 깨지기 쉬운지에 달려 있다.
- 깨지기 쉬운 작업에는 엄격하게: 보안 감사, 암호 구현, 컴플라이언스 점검에는 경직되고 강제되는 단계별 절차가 필요하다.
- 변동이 큰 작업에는 유연하게: 코드 탐색, 문서화, 리팩터링은 선택지를 제시하고 판단의 여지를 남겨야 한다.
모든 스킬 진입점에는 두 개의 섹션이 반드시 있어야 한다. 그 스킬이 적용되는 구체적 시나리오를 나열하는 "When to Use" 섹션, 그리고 다른 접근이 더 나은 경우를 짚어 주는 "When NOT to Use" 섹션이다. 사람들이 빼먹는 쪽은 부정형 섹션인데, 스킬이 엉뚱한 곳에서 발동하는 것을 막아 주는 것이 바로 그 섹션이다.
감사와 보안 스킬에는 세 번째 섹션인 "Rationalizations to Reject"가 필요하다. 여기에는 발견을 놓치게 만드는 흔한 지름길과 변명을 나열한다. 시간에 쫓길 때 표면으로 떠오르는 것이 정확히 그런 합리화이기 때문이다.
## 진입 파일은 짧게 두고 자세한 내용은 한 단계 링크로만 연결하기
스킬 진입점은 대략 500줄 미만으로 유지하고, 나머지는 references 디렉터리와 workflows 디렉터리로 나눈다. 빠른 시작을 앞에 두고 세부 사항은 링크 뒤에 두어, 흔한 경로만 필요한 독자가 나머지를 전혀 로드하지 않게 한다.
링크는 한 단계 깊이로 유지한다. 진입점이 파일들을 링크하고, 그 파일들은 다시 다른 파일로 이어지지 않는다. 디렉터리 깊이 자체는 괜찮다 — references 디렉터리가 주제별 하위 폴더를 갖는 것은 아무 문제가 없다. 문제는 중첩된 폴더가 아니라 사슬처럼 이어지는 간접 참조다.
전형적인 형태는 이렇다. 핵심 지시를 담은 Quick Start 섹션, 상세 패턴을 다룬 참조 문서 하나를 가리키는 Advanced Usage 섹션, 그리고 완전한 메서드 문서를 담은 또 다른 문서를 가리키는 API 레퍼런스 섹션.
## 리뷰 요청 전에 자동 점검과 리뷰어 점검을 통과하고 버전 올리기
자동화가 검증하는 것과 사람 리뷰어가 판단해야 하는 것을 구분하고, 리뷰를 열기 전에 양쪽 모두를 통과시킨다.
자동 검사 항목: 이름과 설명을 갖춘 유효한 프런트매터, 길이 제한 안에 들어가는 케밥 케이스 이름, 참조된 모든 파일이 실제로 존재할 것, 홈 디렉터리 경로를 하드코딩하지 않았을 것, 지원하는 각 런타임에 대해 로드 가능 여부 검사를 통과할 것.
리뷰어 검사 항목: 설명문이 제대로 트리거되고 3인칭으로 쓰였을 것, "When to Use"와 "When NOT to Use" 섹션이 둘 다 있을 것, 예시가 입력과 그 결과 출력을 보여 주며 구체적일 것, 문서가 무엇인지만이 아니라 왜인지를 설명할 것.
문서화: 플러그인에 README가 있을 것, 루트 README의 표에 추가되어 있을 것, 플러그인 자체의 메타데이터 디렉터리가 아니라 저장소 수준의 마켓플레이스 매니페스트에 등록되어 있을 것, 그리고 코드 오너 파일의 소유권 항목이 관리자를 명시할 것.
기존 플러그인의 버전 갱신: 플러그인 매니페스트와 저장소 수준의 마켓플레이스 항목 양쪽에서 버전을 올리고, 두 숫자를 동일하게 유지한다. 많은 클라이언트가 버전 번호가 올라갈 때에만 업데이트를 받아 가므로, 버전 올리기를 빠뜨리면 아무도 그 수정을 받지 못한다.
