버전관리, 패키지 매니저, 그리고 에이전트 패키지 매니저
코드와 라이브러리를 누구에게나 같은 상태로 맞추려던 도구의 역사를 따라가, AI 에이전트의 작업 환경을 APM 으로 고정한 dira 의 기록
2026년 10월 25일 · 20분
같은 저장소에서 같은 요청을 해도 사람마다 AI 가 내놓는 결과가 다릅니다. 어떤 사람의 기계에는 스킬이 여럿 깔려 있고 어떤 사람의 기계에는 하나도 없습니다. 누구는 MCP 커넥터를 붙여 두었고 누구는 붙이지 않았습니다. CLAUDE.md 는 저마다 고쳐 쓰다 보니 저장소마다 내용이 갈라집니다.
코드 개발은 이 문제를 오래전에 풀었습니다. 소스는 버전관리 시스템이, 라이브러리는 패키지 매니저가 누구의 기계에서든 같은 상태로 맞춰 줍니다. AI 작업 환경에는 그런 장치가 없었습니다. 하네스 엔지니어링이라는 이름으로 CLAUDE.md, AGENTS.md, DESIGN.md 같은 파일을 쓰는 관행에는 공감대가 생겼습니다. 그러나 프로젝트가 어떤 스킬과 플러그인과 커넥터를 쓰는지 선언하고 명령 하나로 설치하는 방법은 표준이 없었습니다.
저는 dira 라는 에이전트 오케스트레이터를 만들면서 이 공백을 매일 겪었고, 10월에 Microsoft 의 APM(Agent Package Manager)을 dira 의 표준으로 들였습니다. 그 결정까지 오는 길은 코드와 라이브러리가 먼저 걸어간 길과 많이 닮았습니다.

소스를 복사해 두던 시절과 버전관리
버전관리 시스템이 없을 때 사람들은 파일을 다른 폴더에 복사해 두었습니다. Git 공식 도서는 이 방법을 가장 흔한 버전관리로 소개하면서, 날짜를 붙인 폴더를 만드는 사람은 그나마 똑똑한 축이고 실수하기 아주 쉽다고 적습니다. 바뀐 부분만 주고받는 방법도 있었습니다. Usenet 에 올라온 patch는 diff 가 만든 차이 목록을 원본 파일에 적용해 주는 도구였습니다.
버전관리 도구는 그보다 먼저 나왔습니다. 70년대 초 Bell Labs 에서 만든 SCCS가 시작입니다. 당시 불편은 이랬습니다. 버전마다 소스를 통째로 보관하면 공간이 모자랐고, 언제 어디가 바뀌었는지 알기 어려웠고, 고객이 문제를 겪는 바로 그 버전을 찾기 힘들었다고 합니다. 뒤이은 RCS는 최신본만 통째로 두고 이전 버전은 거꾸로 간 차이로 저장했습니다. 두 사람이 같은 파일을 동시에 고치는 일은 잠금으로 막았습니다.
잠금은 협업을 느리게 만들었습니다. 일정이 제각각인 학생들과 컴파일러를 함께 만들던 한 연구자가 RCS 위에 셸 스크립트를 얹어 각자 따로 커밋할 수 있게 했고, 이것이 C 로 다시 쓰여 CVS 가 됐습니다. CVS 의 뒤는 Subversion이 이었습니다.
리눅스 커널은 다른 길을 갔습니다. 10년 넘게 커널의 변경은 메일로 오가는 패치와 묶음 파일로 오갔습니다. Linus Torvalds 는 훗날 그 방식이 CVS 보다 훨씬 나은 소스 관리였다고 말했습니다. 커널은 한동안 상용 분산 버전관리인 BitKeeper 를 썼고, 무료 사용이 끊기자 Linus 는 Git 을 만들기 시작했습니다. 대안을 찾겠다고 알린 다음 날 Git 은 자기 자신의 소스를 관리하기 시작했습니다.
이 도구들이 없앤 불편은 매번 같았습니다. 누가 어느 상태의 소스를 들고 있는지 모르는 것입니다. 버전관리는 소스의 이력을 모두에게 같은 모양으로 나눠 주면서 그 불편을 없앴습니다.
Linus 가 Git 을 만들던 무렵 저는 초등학생이었습니다. 아버지의 데스크톱으로 스타크래프트 유즈맵과 네이버 카페 채팅 프로그램을 뽀짝뽀짝 만들던 시절이고, 제 버전관리는 폴더를 통째로 복사해 두는 것이었습니다. 배포할 때 붙이는 버전 번호가 이력의 전부였습니다. SCCS 부터 세면 30년 넘게 쌓인 도구를, 저는 이름도 모른 채 폴더 복사로 다시 겪고 있었습니다. 고등학생이 되어 GitHub 을 썼지만 git 이 무엇인지는 제대로 몰랐습니다. 폴더로 관리하던 습관 그대로, GitHub 은 코드를 올려 두는 곳 정도였습니다. 고등학교 3학년 현장실습으로 들어간 첫 직장 씨엔티테크에서는 SVN 을 썼습니다. 커밋하면 제 변경이 팀의 이력에 남았고, 동료가 바꾼 것도 같은 저장소에서 받아 볼 수 있었습니다. 폴더를 복사해 두던 제 버전관리가 처음으로 저 혼자의 것이 아니게 됐습니다.

라이브러리를 손으로 받던 시절과 패키지 매니저
남이 만든 코드를 가져다 쓰는 일에도 같은 불편이 있었습니다. CPAN 이 생기기 전 Perl 코드는 인터넷 곳곳의 FTP 사이트에 흩어져 있었고 사이트마다 관리자가 따로 있었다고 합니다. 라이브러리가 다른 라이브러리를 필요로 하고, 그것이 또 다른 것을 필요로 하는 사슬을 사람이 직접 따라가야 했습니다. 같은 패키지의 다른 버전이 동시에 필요해지는 충돌까지 겹치면 사람들은 이를 dependency hell이라고 불렀습니다.
맨 먼저 모인 것은 보관소입니다. TeX 자료를 모은 CTAN을 본떠 Perl 의 CPAN 이 문을 열었고, CPAN 설치 도구는 필요한 라이브러리를 거슬러 올라가며 함께 설치했습니다. 운영체제 쪽에서도 dpkg 와 RPM 이 나왔고, 곧이어 APT가 의존하는 패키지를 알아서 받아 설치하기 시작했습니다. 언어마다 같은 흐름이 이어져 RubyGems, Maven, pip, npm이 차례로 나왔습니다.
필요한 것을 적어 두는 것만으로는 모자랐습니다. 같은 선언 파일로 설치해도 그날 레지스트리에 어떤 버전이 있느냐에 따라 결과가 달랐습니다. Facebook 이 Yarn 을 발표하며 쓴 글이 이 문제를 정확히 가리킵니다. npm 이 의존성을 비결정적으로 설치해서 기계마다 node_modules 가 달라지고, 그 차이가 찾기 오래 걸리는 "works on my machine" 버그를 만든다는 것입니다. Facebook 은 그걸 피하려고 node_modules 를 통째로 저장소에 넣었는데, babel 의 마이너 버전만 올려도 80만 줄짜리 커밋이 생겼고 병합에 하루가 걸리기도 했다고 합니다.
답은 lockfile 이었습니다. Ruby 의 Bundler 는 일찍부터 Gemfile.lock 을 두었고, RubyGems 가이드는 이 파일이 마지막으로 모든 게 확실히 돌아갔던 때의 남의 코드까지 앱과 함께 묶어 둔다고 설명합니다. Yarn 은 yarn.lock 을 들고 나왔고, npm 도 package-lock.json 을 기본으로 만든 뒤 lock 대로만 설치하는 npm ci를 내놓았습니다. 선언 파일은 무엇이 필요한지를, lockfile 은 실제로 무엇을 설치했는지를 적습니다.
의존성이 공급망이라는 것도 드러났습니다. 한 개발자가 상표 분쟁 끝에 자기 패키지를 npm 에서 내렸고, 그중 11줄짜리 left-pad에 기대던 수많은 프로젝트의 빌드가 몇 시간 동안 깨졌다고 합니다. npm 은 곧 패키지 내리기 정책을 바꿨습니다. 패키지 매니저는 그때부터 설치 도구이면서 신뢰를 다루는 도구가 됐습니다.
left-pad 가 터지던 2016년 봄에 저는 씨엔티테크에서 프랜차이즈 홈페이지와 주문 시스템을 만들고 있었습니다. 소스는 SVN 에 올렸지만 배포는 FTP 로 서버에 파일을 올리는 일이었고, 결과물은 공유 폴더로 주고받았습니다. 그해 가을 Yarn 이 lockfile 을 들고 나왔고, 3주 뒤 저는 리디로 옮겼습니다. 리디에서 Git 과 코드리뷰, CI 와 자동 배포, 클린 코드를 배웠고, npm 이 lockfile 을 기본으로 만들고 npm ci 를 내놓는 동안 그곳에 있었습니다. 파일을 손으로 옮기던 일이 선언과 고정으로 바뀌는 과정을, 저는 회사를 옮기면서 한꺼번에 겪었습니다.

에이전트 작업 환경에서 다시 생긴 문제
토스에서 5년 가까이 사내 제품을 만들다 2023년에 나와 창업할 때만 해도, LLM 을 두고 하던 고민은 단순했습니다. GPT 가 제대로 된 답을 내게 하려면 어떻게 물어야 하는지, 할루시네이션은 어떻게 막는지, 프롬프트 엔지니어링이 대체 무엇인지를 따졌습니다. 그 뒤 몇 해 사이에 모델은 질문에 답하는 도구에서 저장소를 열고 코드를 고치고 테스트를 돌리는 동료가 됐습니다. 지금 저는 프루퍼에서 자체 제품을 만들고, 그 개발을 에이전트들에게 나눠 맡깁니다. 동료의 작업 환경을 맞추는 문제가 에이전트의 작업 환경을 맞추는 문제로 바뀌어 다시 찾아왔습니다.
지금 AI 에이전트의 작업 환경은 패키지 매니저 이전의 라이브러리 세계와 닮았습니다. 에이전트가 일하는 환경은 모델만으로 정해지지 않습니다. Claude Code 나 Codex 같은 하네스, 그 위에 얹는 지침 파일, 스킬, 플러그인, MCP 커넥터, 훅이 함께 결과를 만듭니다. 이것들은 대개 사람마다 홈 디렉터리에 손으로 깔립니다. 어느 버전을 깔았는지, 동료도 같은 것을 쓰는지 아무도 적어 두지 않습니다. FTP 사이트를 돌며 라이브러리를 모으던 모습과 같습니다.

형식은 빠르게 표준이 생겼습니다. Anthropic 은 MCP 를, OpenAI 는 AGENTS.md 를 Linux Foundation 산하 Agentic AI Foundation에 넘겼습니다. Anthropic 이 공개한 스킬 형식 SKILL.md 는 몇 달 만에 30개가 넘는 코딩 도구가 받아들였고, 올여름에는 주요 벤더들이 플러그인 포장 형식인 Agent Plugins 1.0을 함께 내놓았습니다. 그런데 이 규격들은 모두 물건의 생김새만 정합니다. 프로젝트가 무엇을 쓰는지 선언하고, 그대로 설치하고, 설치한 것을 고정하는 일은 Agent Plugins 문서조차 범위 밖이라고 적습니다.
left-pad 의 교훈도 더 빠르게 되풀이됩니다. 스킬은 에이전트가 그대로 따르는 지시문이고, 스크립트를 함께 담기도 합니다. 한 보안 업체가 공개 스킬 저장소를 살펴보니 열에 하나 꼴로 악성이었다고 합니다. 누가 어떤 스킬을 어느 버전으로 깔았는지 모르면, 문제가 생겨도 어디까지 퍼졌는지 알 수 없습니다.
패키지 매니저가 풀 수 있는 범위도 정해져 있습니다. 코드 세계에서는 입력을 고정하면 컴파일러가 같은 결과를 냅니다. 모델은 그렇지 않습니다. temperature 를 0 으로 두어도 서버가 요청을 묶는 크기에 따라 출력이 달라진다는 연구도 나왔습니다. 그래서 에이전트 패키지 매니저에게 기대할 수 있는 것은 같은 입력과 추적 가능한 변경입니다. 결과의 품질은 평가(eval)로 따로 재야 합니다.
에이전트 패키지 매니저 가운데 APM 을 고른 이유
이 빈칸을 노리는 도구는 이미 많습니다. 스킬 관리 도구를 모은 한 목록에만 170개가 넘는 저장소가 올라 있습니다. 크게 나누면 이렇습니다.
- 생성기: rulesync, Ruler 처럼 소스 폴더에서 하네스별 설정 파일을 만들어 줍니다. 원격 패키지도 lockfile 도 없습니다.
- 한 가지만 설치하는 도구: Vercel 의 skills CLI는 스킬만, Neon 의 add-mcp 는 MCP 설정만 여러 하네스에 퍼뜨립니다.
- 패키지 매니저: Microsoft 의 APM, Sentry 의 dotagents, 상용 레지스트리인 Tessl 이 여기에 듭니다.
고르는 기준은 pnpm 이 코드에 해 주는 일을 에이전트 환경에 해 주느냐였습니다. 무엇을 쓰는지 적는 선언 파일, 원격 의존성 해석, 내용 해시까지 담은 lockfile, CI 에서 lock 대로만 설치하는 명령입니다. dotagents 는 lockfile 을 두지만 지금 버전에서는 --frozen 옵션이 경고만 찍고 일반 설치를 하며, 지침 파일은 관리하지 않습니다. Tessl 은 평가와 보안 점수가 강하지만 CLI 가 비공개 소스이고 문서에서 lockfile 을 찾지 못했습니다.
APM은 이 조건을 모두 갖췄습니다. apm.yml 에 지침, 스킬, 프롬프트, 에이전트, 훅, 플러그인, MCP 서버를 선언하고, apm.lock.yaml 에 의존성마다 해석된 커밋과 내용 해시를 남깁니다. apm install --frozen 은 npm ci 와 같은 일을 하고, apm audit --ci 는 lock 과 다른 파일을 잡습니다. 한 번 선언하면 Claude Code, Codex, Copilot, Cursor, Gemini CLI 등 하네스 아홉 곳에 각자의 형식으로 풀어 줍니다.
APM 이 만드는 결과물은 각 하네스가 원래 읽는 파일이라, 나중에 APM 을 빼더라도 설치된 환경은 그대로 돕니다. 의존성 업데이트 봇인 Renovate 가 apm 을 정식으로 지원하기 시작했고, JFrog Artifactory 도 APM 패키지 저장소를 지원합니다.
APM 은 아직 1.0 전이라 거의 매주 호환이 깨지는 변경이 나오고, Python 런타임이 필요합니다. 하네스마다 형식을 옮기는 과정에서 빠지는 것이 있어서, 예를 들어 Codex 는 프롬프트를 받지 못합니다. 같은 이름의 스킬이 두 패키지에서 들어오면 나중 것이 조용히 덮어씁니다. 공식 보안 문서는 서명과 런타임 격리를 하지 않는다고 스스로 적습니다. 저는 CLI 버전을 고정하고 이름 충돌은 dira 가 직접 막는 조건으로 APM 을 받아들였습니다.
dira 에 적용하고 달라진 것
dira 는 제가 프루퍼에서 만드는 자체 제품입니다. 로컬에서 여러 에이전트를 관리하는 도구로, 여러 Claude 세션에 페르소나를 입혀 티켓 단위로 일을 나눠 맡깁니다. 저는 dira 를 포함한 여러 프로젝트를 dira 로 개발합니다.
dira 의 중심 개념은 페르소나입니다. pm, developer, qa, designer, writer 처럼 역할을 나누고, 역할마다 지침과 쓰는 스킬을 줍니다. 페르소나 여럿을 묶으면 스쿼드가 됩니다. 같은 페르소나를 어느 프로젝트에서나 똑같이 쓰는 것은 APM 을 들이기 전에도 dira 안에서 할 수 있었습니다. 다만 그 페르소나는 dira 가 직접 정한 형식으로 만들어져 dira 안에서만 통했습니다. 다른 도구와 주고받으려면 그 형식부터 알아야 했습니다.
APM 을 들이면서 페르소나를 담는 그릇을 dira 만의 형식에서 Microsoft 가 만든 APM 의 인터페이스로 바꾸었습니다. 페르소나는 이제 지침과 스킬을 묶은 APM 패키지이고, 스쿼드는 페르소나 패키지를 의존성으로 거는 패키지입니다. 같은 형식으로 만들어진 다른 사람의 패키지를 그대로 가져와 섞을 수 있고, dira 의 페르소나도 APM 이 지원하는 하네스 어디로든 설치됩니다. APM 을 지원하는 도구들도 따로 맞추지 않고 붙일 수 있습니다.

제가 느낀 가장 큰 변화는 확장 가능성과 범용성을 얻었다는 것입니다. 우리만의 인터페이스를 키워 가는 대신, 생태계가 이미 붙기 시작한 인터페이스에 페르소나를 올렸습니다. 버전관리가 소스를, 패키지 매니저가 라이브러리를 누구에게나 같은 모양으로 나눠 준 것처럼, dira 의 페르소나도 이제 dira 밖에서 통하는 모양을 갖게 됐습니다.

dira 는 로컬 엔진과 앱을 무료로 쓸 수 있고 MIT 라이선스로 공개돼 있습니다. 페르소나와 스쿼드로 에이전트에게 일을 나눠 맡기는 방식이 궁금하다면 dira.proofer.tech 에서 앱을 받아 첫 프로젝트를 만들어 보세요.
MORE
같은 태그의 글
Paperclip vs Buzz vs Multica, 그래도 dira 를 만든 이유
에이전트 오케스트레이션 도구 Paperclip, Buzz, Multica 를 써 보고 Multica 에 정착한 뒤에도 개발용으로는 dira 를 만들어 쓰는 이유
2026년 10월 15일
AI 이후, UI 라이브러리를 걷어낸 이유
사람이 코드를 쓰던 시절엔 UI 컴포넌트 라이브러리가 더 저렴했지만 LLM이 그 계산을 뒤집었습니다. 프루퍼가 홈페이지에서 Mantine을 걷어내고 디자인 시스템을 Claude Design에 둔 이유를 정리했습니다.
2026년 10월 11일
Claude를 팀의 OS로 쓰고 있습니다
10년치 서비스 히스토리를 AI가 읽는 컨텍스트로 옮기고 Google Drive, Slack과 묶어 Claude로 팀 업무를 자동화한 기록입니다. 정리된 지식과 실시간 정보를 나누는 구조와 운영 규칙을 다룹니다.
2026년 6월 27일