만약 Claude Code, Cursor 또는 Markdown 지침을 읽는 모든 에이전트를 사용한다면, 여러분은 아마도 '스킬' 폴더를 가지고 있을 것입니다. 배포 체크리스트, 코드 리뷰 플레이북, X에서 누군가가 공유한 규칙 세트 등이 그것입니다.
그 출처를 한번 보세요. 하나는 gist이고, 하나는 3개월 전에 GitHub 리포지토리에서 복사해 온 것이며, 다른 하나는 Discord에서 붙여넣기 한 것입니다. 여러분은 어떤 버전을 가지고 있는지, 작성자가 이후에 무언가를 수정했는지, 아니면 다시 가져왔을 때 무엇이 바뀌었는지 알 수 없습니다.
우리는 이 문제를 수십 년 전 패키지 매니저(package managers)를 사용해 해결했습니다. 프롬프트 파일은 라이브러리가 프로그램의 기능을 바꾸는 것만큼이나 에이전트가 하는 일을 변화시키지만, 우리는 여전히 그것들을 복사-붙여넣기 방식으로 관리하고 있습니다.
그래서 저는 에이전트 스킬(agent skills), 에이전트, 그리고 MCP 서버를 위한 오픈 레지스트리인 **Amitte**를 구축했습니다. 이것이 무엇을 하는지, 그 뒤에 숨겨진 설계 결정은 무엇인지, 그리고 아직 부족한 부분은 무엇인지 설명하겠습니다.
1. 버전은 불변(immutable)합니다
여러분은 스킬을 publisher/name@version 형식으로 게시하며, 한번 버전이 게시되면 절대 변경되지 않습니다. 각각의 스킬은 콘텐츠 해시(content-hashed)(SHA-256)되므로, 주어진 @1.2.0은 항상 동일한 바이트를 참조합니다. 무언가를 바꾸려면 새로운 버전을 게시해야 합니다.
npm i -g @amitte-ai/cli
skills init acme/deploy-checklist
...
Claude Code용으로 설치하면 적절한 .claude/skills/<name>/SKILL.md 파일이 작성됩니다:
2. 번들(Bundles): 개별 파일이 아닌 전체 세트를 고정하세요
이 부분은 실제 사용자로부터 나온 아이디어입니다. 여러 스킬로 구성된 프로젝트의 유지 관리자가 저에게 각 스킬을 개별적으로 버전 관리하는 것만으로는 충분하지 않다고 말했습니다. 그들의 스킬들은 함께 작동하도록 설계되었는데, 사용자들이 결국 일치하지 않는 조합(mismatched combinations)을 갖게 되었습니다. 예를 들어, 스킬 A는 v3이고 스킬 B는 v1인 경우인데, 이는 테스트된 적이 없으며 이상한 방식으로 오작동합니다.
그들이 원했던 것은 락파일(lockfile)이 제공하는 보장입니다. 즉, 전체 세트의 알려진 좋은 스냅샷(known-good snapshot)을 얻고 필요할 때 되돌아갈 수 있는 것입니다.
따라서 **번들 릴리스(bundle release)**는 모든 멤버 스킬의 정확한 버전을 고정하고, 해당 번들이 가져온 상위 git 커밋까지 기록하는 불변 기록입니다. 유지 관리자는 자신의 레포지토리에 amitte-bundle.json을 추가하고 다음 명령어를 실행합니다:
skills release # 더티 트리(dirty tree)를 거부하고, git HEAD를 기록하며,
# 누락된 멤버 버전을 게시하고, 릴리스를 만듭니다.
사용자는 전체 세트를 한 번에 설치합니다:
skills install acme/toolkit --claude # 최신 릴리스
skills install acme/[email protected] --claude # 정확한 스냅샷 (롤백할 때도 사용)
skills bundle status --check # 무엇이 설치되었는지, 어떤 커밋에서 왔는지, 더 새로운 릴리스가 있는지?
설치 기록은 amitte.lock.json에 남습니다. 다른 릴리스를 설치하면 전체 세트 단위로 교체되며, 새 릴리스가 포함하지 않는 멤버는 제거되므로 두 개의 릴리스 조합이 혼합되는 일은 절대 없습니다.
누군가 버그를 신고할 때, skills bundle status --json 명령은 유지 관리자에게 현재 사용 중인 정확한 릴리스와 커밋을 알려줍니다.
3. 누가 게시했는지 알기
'acme'이라는 이름은 누구나 주장할 수 있습니다. 따라서 게시자는 자신이 도메인을 소유하고 있음을 증명할 수 있으며, 인증된(verified) 게시자에게는 게시하는 모든 것에 배지가 부여됩니다. 이는 npm이나 GitHub 조직의 인증된 도메인과 같은 개념입니다. 콘텐츠가 좋다는 것을 의미하지는 않지만, 누가 그 뒤에 서 있는지를 알려줍니다.
4. 에이전트가 레지스트리를 스스로 검색할 수 있다
검색은 시맨틱(semantic)합니다 (Postgres + pgvector 임베딩 사용). 따라서 'iOS 앱을 출시하는 데 도움이 되는 무언가'라는 검색어가 단어는 일치하지 않더라도 App Store 제출 체크리스트를 찾아냅니다.
또한 MCP 서버도 존재하므로, 에이전트가 직접 조회를 수행할 수 있습니다: amitte_search로 스킬을 찾고, amitte_fetch로 하나를 가져오며, amitte_compose로 여러 개를 조합하여 작업을 수행합니다. 사용자가 플레이북(playbook)을 컨텍스트에 붙여넣는 대신, 에이전트가 필요할 때 적절한 것을 찾아냅니다.
스택(The stack)
- 레지스트리(Registry): Hono + Drizzle on Postgres/pgvector
- 사이트: Next.js 15
- CLI: TypeScript (
@amitte-ai/cli)
- 가이드: Folio라는 작은 RAG 어시스턴트가 사이트 구석에 있습니다. 이 도구는 "어디에…가 있나요?"와 같은 질문에 답하고 페이지의 올바른 요소를 가리킵니다. 수작업으로 작성된 지식 기반을 대상으로 하이브리드 BM25 + 임베딩 검색(embedding retrieval)을 사용하는 저렴한 오픈 모델에서 실행됩니다.
이것은 Apache-2.0 라이선스입니다.
아직 완료되지 않은 것들 (What's not done yet)
- 암호화 서명(Cryptographic signing). 현재 무결성은 콘텐츠 해시와 불변성에 의존합니다. Sigstore 기반의 서명을 통해, 단순히 변경되지 않았다는 사실뿐만 아니라 어떤 사람이 해당 버전을 생성했는지 확인할 수 있게 하는 것이 다음 주요 과제입니다.
- 더 많은 콘텐츠. 레지스트리의 유용성은 그 안에 담긴 내용에 달려 있으며, 아직 초기 단계입니다.
- 사이트 전반의 미흡한 부분(Rough edges). 저 혼자서 작업하고 있습니다.
여러분의 의견을 듣고 싶습니다 (I'd love your take)
- 정말로 "이 프롬프트는 몇 버전인가요?"라는 문제를 겪으시나요, 아니면 복사/붙여넣기(copy-paste)로 충분하신가요?
- 만약 스킬이나 규칙 세트를 유지하신다면, 그것들을 레지스트리에 게시하는 것이 단순히 리포지토리(repo)에 보관하는 것보다 더 필요하다고 느끼는 부분은 무엇인가요?
매일 사용하는 스킬이 있다면 한번 게시해 보세요. 제가 어려움을 겪는 분들께 개인적으로 도움을 드리겠습니다. 댓글은 아래에서 열려 있으며, https://amitte.com에서 저를 찾아주세요.