데이비드 고메즈는 커서(Cursor)에서 12,000줄이 넘던 워크트리(WorkTree) 기능을 200줄 정도의 스킬, 명령어, 서브 에이전트 기반의 경량화된 레이어로 대체한 경험을 공유합니다. 그는 이 과정을 통해 병렬 코딩 워크플로우를 어떻게 마크다운으로 재구현했는지, 그리고 이 과정에서 발생한 장단점, 실패 사례, 그리고 코드 기반의 제품 기능을 프롬프트 기반으로 전환하면서 얻은 교훈들을 자세히 설명합니다.
1. 마크다운은 새로운 코드?! 😮
여러분, 안녕하세요! 오늘 이 자리에 와주셔서 정말 감사합니다. 😊 저는 오늘 마크다운이 어떻게 새로운 코드가 되었는지에 대해 이야기하려 합니다. TJ가 이미 살짝 언급했듯이, 저희 커서(Cursor) 애플리케이션에서 방대한 양의 코드를 단지 마크다운으로 작성된 스킬 하나로 대체했습니다. 이 강연에서는 수많은 코드, 의존성, 복잡한 테스트를 포함했던 거대한 기능을 단 하나의 스킬로 훨씬 더 가볍고 간결한 버전으로 전환한 여정을 공유하려고 해요.
2. 깃 워크트리(Git WorkTrees) 이해하기
시작하기 전에 깃 워크트리(Git WorkTrees)가 커서에서 어떻게 작동하는지 간략하게 설명해 드릴게요. 깃 워크트리를 들어보지 못하셨다면, 이는 기본적으로 여러분의 레포지토리(repository)에 있는 별도의 체크아웃(separate checkouts)이라고 생각하시면 됩니다. 이를 통해 병렬 작업이 가능해져요. 여러 에이전트가 동시에 또는 다른 작업에 방해받지 않고 작업할 수 있는 거죠. 🤩
커서에서 이 기능을 사용하는 방법은 다음과 같아요.
- 개별 워크트리에서 에이전트를 실행할 수 있습니다.
- 예를 들어, 동일한 파일을 두 개의 다른 워크트리에서 볼 수 있는데, 에이전트가 작업하는 동안 기본 체크아웃과는 다르게 보이게 됩니다.
- 에이전트가 명령을 실행하거나 린트(lint)를 수행하는 모든 작업은 해당 깃 워크트리 내에서만 격리되고 범위가 지정됩니다.
이 기능을 통해 화면에서 여러 에이전트가 동시에 작업하는 그리드를 구성하여 병렬로 작업할 수도 있습니다. 만약 "PR 열어줘"라고 말하면, 에이전트는 해당 워크트리에서 생성된 변경사항으로 풀 리퀘스트(pull request)를 열어줍니다. 이 기능의 가장 멋진 점 중 하나는 동일한 작업을 다른 모델들에게 동시에 부여하고, 그 결과물을 비교할 수 있다는 거예요. 우리는 이를 "베스트 이벤트(Best Event)"라고 부르며, 서로 다른 모델들이 동일한 프롬프트에 대해 경쟁하도록 한 다음, 프런트엔드 프로젝트라면 시각적 구현을 비교하고 가장 마음에 드는 것을 선택할 수 있습니다. ✨ 이 모든 기능은 지난 2025년 10월, 커서 2.0과 함께 출시되었습니다.
3. 초기 구현의 복잡성 😱
처음 이 기능을 출시했을 때, 정말 많은 복잡성이 뒤따랐습니다.
- 워크트리 생성 및 관리
- 에이전트에게 컨텍스트(context)로 제공하는 코드
- 에이전트가 작업 중인 워크트리 외부로 벗어나지 않도록 범위 지정 및 격리
- 사용자가 구성하고 실행할 수 있는 설정 스크립트(setup scripts)
- 여러 기준에 따라 어떤 구현이 가장 좋은지 알려주는 판정(judging) 시스템
- 에이전트가 워크트리 내에서 작업을 계속할 수 있도록 돕는 시스템 리마인더
- 수많은 워크트리 생성으로 인한 디스크 공간 문제를 해결하기 위한 정리(cleanup) 로직
이처럼 많은 부분이 코드화되어 있었죠. 사람들이 수백 개의 워크트리를 만들다 보면 디스크 공간이 폭발하곤 해서, 저희는 사용하지 않는 워크트리를 정리하는 데 도움을 줘야 했습니다. 😅
4. 15,000줄의 코드 삭제! 🎉
새로운 구현을 통해 우리는 이러한 복잡한 부분 대부분을 제거할 수 있었습니다. 실제로 저는 최근에 커서에서 이 기능을 통째로 제거하는 풀 리퀘스트(PR)를 올렸는데, 이는 무려 15,000줄에 달하는 코드를 삭제하는 거대한 작업이었습니다! 🤯 새로운 기능은 이전 버전과 거의 동일한 성능을 보여주면서도 훨씬 더 가볍고 유지 보수가 용이합니다. 심지어 이전 구현에는 없던 몇 가지 이점도 가지고 있습니다.
5. 스킬과 서브 에이전트로 기능 구현하기
그렇다면 어떻게 저희는 전체 기능을 단 하나의 스킬로 대체할 수 있었을까요? 🤔 저희는 두 가지 기본 요소를 활용하면 커서 사용자들이 워크트리를 쉽게 사용할 수 있을 것이라고 판단했습니다.
- 에이전트 스킬(Agent Skills)
- 서브 에이전트(Subagents)
이 둘은 모두 커서에 이미 존재하는 기능이며, 저희 문서에서 자세히 알아볼 수 있습니다. 이 두 가지를 조합하면 커서의 워크트리 기능과 베스트 이벤트 기능을 마크다운만으로도 재구현할 수 있다는 것을 깨달았죠!
영상에서 보여드린 것처럼, 이제 사용자들은 /worktree 명령어를 입력하고 "웹사이트 푸터의 오타를 수정해줘"와 같은 작업을 지시할 수 있습니다. 그러면 에이전트가 격리된 워크트리에서 작업을 수행합니다.
6. 새로운 스킬의 구조 🛠️
새로운 스킬은 놀랍도록 간단합니다. 화면에는 다 들어오지 않지만, 기본적으로 모델에게 워크트리를 생성하고, 사용자가 설정한 설정 스크립트를 실행하며, 해당 체크아웃에 머물도록 지시하는 일련의 명령어로 이루어져 있습니다. 에이전트가 워크트리에서 작업할 때 해당 체크아웃에만 머무르도록 하는 것이 중요하죠.
베스트 이벤트 스킬은 훨씬 더 간단합니다. 작은 글씨로 표시하면 화면에 전부 들어갈 정도죠! 😮 여기서 우리는 상위 에이전트에게 각 모델에 대한 서브 에이전트를 생성하고, 각 서브 에이전트가 자체 워크트리를 만들고 그 안에서 작업하도록 지시합니다. 그리고 모든 서브 에이전트가 완료될 때까지 기다렸다가, 그들의 작업에 대한 논평을 제공하도록 합니다.
"사용자에게 각 서브 에이전트가 구현한 내용이 어떻게 다른지 알려주세요. 평가하고, 비판적인 의견을 제시하며, 사용자가 어떤 것이 가장 좋은지 선택할 수 있도록 도와주세요."
"깔끔한 표 형식으로 사용자에게 제시해 주세요."
이 모든 것이 마크다운으로 단 40줄 정도에 불과합니다. 이전 버전은 4,000줄에 달하는 코드였는데 말이죠! 이 스킬을 구현할 때 고려해야 할 사항은 다음과 같습니다.
- 스킬은 크로스 플랫폼 호환이어야 합니다. (Windows, Linux, macOS 지침 포함)
- 상위 모델에게 사용자가 설정했을 수 있는 설정 스크립트를 각 워크트리에 대해 실행하도록 지시합니다.
- 가장 어려운 부분은 모델에게 "그 워크트리에 머물러라"고 지시하는 것입니다.
"절대 이 워크트리 밖에서 작업하지 말고, 절대 탈출하지 마라!"
이것은 효과적으로 강력한 프롬프트(aggressive prompting)를 통해 이루어집니다.
7. 새로운 슬래시(Slash) 명령어와 워크플로우 🚀
이제 새로운 명령어는 다음과 같습니다:
/worktree: 격리된 워크트리에서 에이전트를 시작합니다./bestevent: 동일한 작업에 대해 여러 에이전트를 시작합니다./applyworktree: 사이드 워크트리의 변경사항을 기본 체크아웃으로 가져옵니다./deleteworktree: 워크트리를 삭제합니다. (예상대로 작동합니다)
참고: 이 명령어들은 엄밀히 말하면 커서의 스킬은 아니지만, 스킬과 매우 유사하게 작동합니다. 사용자 선택 시에만 프롬프트가 컨텍스트에 로드됩니다. 이를 명령어로 만든 유일한 이유는 프롬프트를 저희 서버에서 제어할 수 있기 때문입니다. 즉, 커서 버전을 업데이트하지 않아도 프롬프트를 개선할 수 있다는 의미입니다. 다음에 사용하실 때는 항상 최신 버전의 프롬프트를 받게 될 것입니다.
베스트 이벤트 시연에서는 Kimmy, Groq, Composer GPT, Opus에게 동일한 작업을 부여합니다. 그러면 상위 에이전트가 5개의 서브 에이전트를 시작하고, 각 서브 에이전트는 자체 워크트리와 컨텍스트를 가집니다. Opus가 예상대로 조금 더 오래 걸린 후, 상위 모델은 각 서브 에이전트의 결과를 비교하여 어떤 모델이 어떤 작업을 수행했는지, 어떤 점이 달랐는지 설명합니다. 심지어 상위 에이전트에게 "Opus가 한 이 부분과 GPT가 한 이 부분이 마음에 드는데, 둘을 합쳐줄 수 있을까?"라고 요청할 수도 있고, 에이전트가 그렇게 해줄 것입니다. 🤩
8. 새로운 구현의 장점 👍
이번 재구현의 장점들을 먼저 이야기하고, 그 다음 단점들을 살펴보겠습니다.
- 유지 보수할 코드 감소: 가장 큰 장점은 개인적으로 유지 보수할 코드가 훨씬 줄어들었다는 것입니다. 워크트리는 커서 사용자 중 90%가 사용하는 기능이 아니라, 병렬 작업과 그리드를 좋아하는 소수의 파워 유저들이 사용하는 고급 기능입니다. 따라서 유지 보수에 많은 시간을 할애하고 싶지 않은 기능이죠.
- 채팅 중 워크트리 전환 가능: 이제 사용자는 채팅 도중에 워크트리로 전환할 수 있습니다. 이전에는 불가능했던 일인데, 프롬프트 UI를 드롭다운이나 설정으로 너무 복잡하게 만들고 싶지 않았기 때문입니다. 이제
/worktree슬래시 명령어만 사용하면 훨씬 쉽게 전환할 수 있습니다. - 다중 레포지토리 지원: 이전 구현은 동시에 여러 레포지토리에서 작업할 경우 작동하지 않았습니다. 프론트엔드와 백엔드가 별개의 레포지토리인 경우가 흔한데, 과거에는 이런 설정에서 워크트리를 사용할 수 없었습니다. 하지만 이제
/worktree명령어를 사용하면 모든 것이 잘 작동하며, 에이전트가 각 레포지토리에 워크트리를 생성하고 필요하면 각 레포지토리에 대한 별도의 PR을 열어줍니다. 👏 - 향상된 판정 경험: 베스트 이벤트의 판정 경험이 훨씬 우수해졌습니다. 이제 상위 에이전트는 각 서브 에이전트가 무엇을 했는지에 대한 훨씬 더 많은 컨텍스트를 가지며, 사용자는 에이전트에게 여러 구현에서 마음에 드는 부분을 취합해 달라고 요청할 수도 있습니다. 이전에는 특정 서브 에이전트나 모델 중 하나를 선택해야만 했습니다.
9. 단점과 사용자 피드백 😕
물론 단점도 있습니다. 저희 포럼을 보시면 새 구현에 대한 엇갈린 피드백을 확인할 수 있습니다. 일부 사용자들은 이전 방식에 익숙해서 변화에 불만을 느끼기도 합니다.
- 에이전트가 작업 범위에서 벗어나기 쉬움: 가장 큰 문제는 에이전트가 작업 범위 내에 머물도록 하는 것이 매우 어렵다는 것입니다. 이전에는 모델이 워크트리 외부의 파일을 건드리는 것이 물리적으로 불가능했지만, 이제는 모델을 신뢰해야 합니다. 장기적인 세션에서는 모델이 작업해야 할 위치를 잊어버리거나, 심지어는 할루시네이션(hallucination)을 일으켜 엉뚱한 작업을 할 수도 있습니다. 😮 하지만 저희는 이 문제를 해결하기 위해 노력하고 있습니다.
- 느리게 느껴지는 경험: 실제로는 느리지 않지만, 사용자는 에이전트가 워크트리를 생성하는 과정을 채팅에서 보면서 마치 시간이 낭비되는 것처럼 느낍니다. 에이전트가 미리 처리해야 할 일을 하는 것처럼 느껴지는 거죠. 이 부분도 개선을 모색 중입니다.
- 떨어진 기능 발견 용이성: 이전에는 커서를 열면 작업 방식을 선택하는 드롭다운 메뉴가 있어서 워크트리 기능을 쉽게 찾을 수 있었습니다. 하지만 이제 그 드롭다운이 사라졌기 때문에, 워크트리 기능을 사용하려면
/worktree를 직접 입력해야 합니다. 즉, 발견 용이성(discoverability)이 떨어졌습니다. 그러나 이는 고급 사용자 기능이므로, 덜 쉽게 발견되는 것에 대해서는 괜찮다고 생각합니다.
10. 스킬 개선 방안 📈
그렇다면 이 스킬을 어떻게 더 좋게 만들 수 있을까요? 🤔 현재 가장 큰 문제는 에이전트가 항상 작업 범위 내에 머무르지 않는다는 점입니다. 이를 개선하기 위한 두 가지 방법이 있습니다.
-
Evals(평가)와 프롬프트 개선:
- 커서에서는 컴포저(Composer)라는 자체 모델을 훈련합니다.
- 컴포저 2 버전에서는 이런 종류의 환경에서 작동하는 RL(강화 학습) 작업이 없었습니다.
- 저희는 수많은 워크트리 관련 작업을 RL 파이프라인에 추가하여, 컴포저 3, 4, 5 버전에서는 모델이 이 작업을 훨씬 더 잘 수행하도록 할 것입니다.
- 다른 회사에서 개발한 모델을 직접 개선할 수는 없지만, 저희는 다른 연구실 및 모델 제공업체와 이러한 종류의 피드백을 공유하고 있습니다.
- 저는 Brain Trust와 같은 도구를 사용하여 이 기능을 위한 evals를 개발하고 있습니다. evals 작성은 생각보다 매우 쉽고, 에이전트에게 프롬프트를 입력하면 모든 것을 처리해 줍니다.
- 저는 커서 CLI(명령줄 인터페이스)를 헤드리스(headless) 모드로 실행하여 두 가지 평가 지표를 사용합니다.
- 모델이 예상대로 워크트리 내에서 작업을 수행했는지 확인
- 모델이 작업해서는 안 되는 기본 체크아웃에서 작업을 수행했는지 확인 (이것의 역방향)
- 현재 evals는 비교적 단순하여 장기 세션을 시뮬레이션하지 못하고 있지만, 이미 모든 모델이 이 작업을 똑같이 잘하는 것은 아니라는 것을 파악했습니다. 예를 들어, Haiku와 같은 작고 지능이 낮은 모델은 종종 기본 체크아웃으로 이탈하지만, Composer나 Groq 같은 다른 모델들은 훨씬 더 잘 수행합니다.
- 이 evals를 더욱 복잡하게 개선하여 패턴을 발견하고 프롬프트를 개선할 수 있기를 바랍니다.
-
향상된 시스템 리마인더: 모델에게 작업 범위 내에 머물고, 작업해야 할 워크트리에서 벗어나지 않도록 지시하는 더 나은 시스템 리마인더를 제공할 수 있습니다.
11. 커서 3.0과 미래 展望 🚀
다음은 무엇일까요? 저희는 잠시 한 발 물러나서, 새로운 커서 에이전트 창에 훨씬 더 완벽하고 네이티브한 워크트리 구현을 도입할 예정입니다. 최근 발표된 커서 3.0의 일부는 더욱 에이전트 중심적인 코딩 인터페이스입니다. 코드를 편집하고 볼 수는 있지만, UI/UX가 에이전트와 채팅 인터페이스에 훨씬 더 최적화되어 있습니다. 우리는 이러한 종류의 인터페이스가 적절한 워크트리 구현을 위한 올바른 장소라고 믿습니다. 로컬 병렬화를 많이 수행하는 사람은 보통 이러한 UI를 더 많이 사용할 가능성이 높기 때문입니다. 따라서 저희는 잠시 멈춰 서서 새로운 UI에서 에이전트 중심적이지 않은, 더 네이티브한 워크트리 구현을 구축할 것입니다.
또한, evals와 RL 훈련을 통한 지속적인 작업을 통해 스킬을 개선할 것입니다.
마지막으로, 저희는 깃 워크트리가 아닌 다른 병렬화 기본 요소를 모색하고 있습니다. 깃 워크트리는 생성 속도가 느리고, 컴퓨터 디스크 공간을 많이 차지하며, 깃 레포지토리에서만 작동한다는 단점이 있습니다. 깃이 아닌 다른 것을 사용한다면 커서에서 로컬 병렬화 기본 요소가 없습니다. 가까운 미래에 이에 대해 더 많은 정보를 공유할 수 있기를 바라지만, 저희는 깃이나 깃 워크트리와 관련 없는 로컬 병렬화를 위한 다른 해결책을 찾고 있습니다.
지속적으로 관심을 가져주세요! 오늘 강연에 참석해 주셔서 감사합니다. 궁금한 점이 많으실 텐데, 저는 하루 종일 여기에 있을 예정이니 언제든지 저를 찾아와서 이야기 나눠주시면 기쁠 것 같습니다. 감사합니다! 🙏
결론
커서 팀은 15,000줄의 복잡한 깃 워크트리 코드를 단 200줄의 마크다운 기반 스킬로 대체하는 혁신을 이루어냈습니다. 이는 유지 보수 비용 절감, 다중 레포지토리 지원, 향상된 베스트 이벤트 경험 등 여러 장점을 가져왔습니다. 물론 에이전트의 작업 범위 이탈, 느리게 느껴지는 경험, 기능 발견 용이성 저하와 같은 단점도 존재하지만, evals 및 RL 훈련을 통한 지속적인 개선과 커서 3.0에서의 네이티브 워크트리 구현을 통해 이 문제들을 해결해 나갈 계획입니다. 앞으로 깃 워크트리를 넘어서는 새로운 병렬화 기술에 대한 기대감도 높아지고 있습니다.
