Anthropic에서 소스 컨트롤을 다시 설계하기
TMThttps://www.anthropic.com/engineering/redesigning-source-control
Anthropic에서는 이제 시스템을 만들거나 연구를 하는 데 코딩이 병목이 아닙니다. Claude는 연구 루프를 스스로 반복하고, 복잡한 프로그램을 세밀하게 최적화하고, 새로운 서비스를 바닥부터 만들어 내는데, 그 속도와 규모는 저희가 지금껏 본 적 없는 수준입니다. 이제 병목은 사람 규모에 맞춰 만들어진 개발자 인프라 전반, 즉 소스 컨트롤과 빌드와 CI입니다.
2026년 5월 Anthropic에서는 하루 평균 약 2,500건의 코드 변경이 병합되었습니다. 9월 현재는 하루에 3만 건 넘게 병합하고 있습니다. 이 성장세가 조만간 꺾일 것으로 보지는 않습니다. 코드 병합에 대한 잠재 수요는 사실상 무한하고, 병목을 하나 없앨 때마다 저희가 만들어 내는 코드의 양은 곧바로 더 늘어나기 때문입니다.
2026년 1월부터 9월까지 저희 모노레포에 하루 동안 병합된 변경 건수입니다.
이 성장을 감당하기 위해 저희는 사내 버전 관리 시스템인 Scion을 만들었고, 5개월 만에 모노레포를 git에서 완전히 이전했습니다. 같은 기간에 코드 리뷰 도구(Antique라고 부릅니다), 코드 검색, 소스 컨트롤을 위한 정교한 IAM 시스템, 리뷰를 마친 대량의 코드를 관리하고 반영하는 새로운 방법 등도 만들어 배포했습니다. 이 글에서는 그중에서도 Scion을 어떻게 만들었는지에 집중하겠습니다. 흥미로운 사례 연구가 될 만한 이야기입니다. 애초에 저희를 이런 상황에 몰아넣은 것도 Claude의 코드 작성 능력이었고, 이 상황을 감당할 고품질의 확장 가능한 시스템을 빠르게 만들 수 있었던 것도 바로 그 능력 덕분이었기 때문입니다.
커져 가는 모노레포
저희가 무엇을 만들었는지 살펴보기 전에, 저희 워크로드가 얼마나 특이한지부터 짚고 넘어가야 합니다. 당연하게도 Anthropic은 거의 어떤 회사보다도 Claude로 소프트웨어를 많이 작성하기 때문에, 사람 규모에 맞춰 만든 도구가 어디서부터 버거워지는지를 가장 먼저 보게 되는 경우가 많습니다. 소스 컨트롤은 그 한 예일 뿐입니다. 가까운 시일 안에 이런 문제를 겪을 조직이 많지는 않겠지만, 머지않아 AI 코딩 도구를 쓰는 다른 곳들도 같은 압박 지점에 부딪힐 것으로 짐작합니다. 그래서 저희가 무엇을 만들었고 무엇을 배웠는지 공유하고 싶었습니다.
Git은 분산 시스템입니다. 모든 클론은 그 자체로 완결된 저장소여서, 완전히 오프라인 상태에서도 diff를 계산하고, 이력과 blame을 읽고, 어떤 리비전이든 체크아웃할 수 있습니다. 대다수 저장소에는 이것이 올바른 설계이며, git이 표준이 된 큰 이유이기도 합니다.
그런데 저희 모노레포는 커질수록 이 설계가 상정한 범위에서 점점 벗어나고 있습니다. main 브랜치의 이력만 해도 100GB에 육박하고, 압축한 작업 사본조차 25GB가 넘습니다. CI만으로도 하루에 2,500만 회 안팎으로 코드를 체크아웃하는데, 여기에는 개발자 환경, 에이전트 샌드박스, 연구 작업은 포함되지도 않았습니다. 이를 아무 최적화 없이 그대로 가져온다면 git 트래픽이 하루 600PB를 넘을 것입니다.
Git에는 얕은 클론(shallow clone), 스파스 체크아웃(sparse checkout), promisor 리모트처럼 저장소의 일부만 다루는 도구가 있습니다. 그 밖에도 대형 모노레포를 위한 표준적인 우회책으로, 사내 git 미러를 두거나 저장소 스냅샷(시드)을 블롭 스토리지에 보관하는 방법이 있습니다. 저희는 이 방법을 모두 써 봤습니다. 가장 많을 때는 부하를 감당하려고 사내 git 미러를 수백 대 운영했습니다. 덕분에 시간을 벌었지만, 병합 속도가 빨라질수록 운영하기가 점점 어려워졌습니다. 시드는 갱신과 갱신 사이에 main의 최신 커밋에서 점점 더 뒤처졌고, diff나 blame처럼 이력에 의존하는 작업이 부분 클론에서 계속 동작하게 하려면 갈수록 더 많은 손이 갔습니다.
git 체크아웃을 확장할 때 흔히 쓰는 구성입니다.
한발 물러서서 보니, 저희도 대부분의 회사처럼 git을 기준 사본 하나를 둔 중앙집중식 시스템으로 쓰고 있었는데, 정작 클라이언트는 거의 전부가 본질적으로 항상 온라인인 에이전트와 작업이었습니다. git을 분산 작업과 오프라인 작업에 탁월하게 만드는 바로 그 특성이, 저장소가 커질수록 오히려 확장을 가로막고 있었습니다. 그래서 저희는 스스로에게 물었습니다. 에이전트가 항상 온라인이라는 사실을 처음부터 염두에 두고 소스 컨트롤을 설계한다면 어떤 모습이 될까요?
에이전트 규모의 소스 컨트롤을 위한 원칙
에이전트 코딩이 자리 잡으면서 소프트웨어 개발 방식에 대한 흔한 가정이 많이 바뀌고 있습니다. 저희는 Scion을 만들면서 이런 변화를 적극 받아들였고, 덕분에 여러 핵심 원칙에서 git과 근본적으로 다른 접근을 택할 수 있었습니다. 거대한 모노레포를 위한 소스 컨트롤에는 선행 사례가 있습니다. 대표적으로 Google의 Piper와 Meta의 Sapling이 있어서, 저희는 이들이 어렵게 얻은 교훈을 염두에 두고 Scion을 만들 수 있었습니다. 저희의 원칙은 다음과 같습니다.
클라이언트는 항상 온라인입니다. Git은 클라이언트가 오프라인으로 작업하며 저장소 전체 사본이 필요하다고 가정합니다. 저희 클라이언트는 거의 모두 에이전트와 작업이므로, Scion의 클라이언트와 프로토콜은 언제든 접속할 수 있는 서버를 중심으로 설계했고, 클라이언트는 필요할 때 데이터를 가져오게 했습니다.
클라이언트와 서버의 비대칭. git에서는 모든 클라이언트가 온전한 서버 역할까지 할 수 있습니다. Scion에서는 서버가 파일 이력과 blame에 관한 질의에 답하고, 커밋을 만들고, 병합과 리베이스를 수행하는 등의 일을 맡습니다. 클라이언트는 크기가 제한된 로컬 객체 캐시를 유지하고, 작업 사본 파일을 디스크에 배치하고, 파일 시스템 변경을 감시하며, 사용자가 서버와 편하게 작업할 수 있는 수단을 제공합니다. 클라이언트가 혼자서 계산할 수 있는 것은 거의 없지만, 그 대가로 로컬에 둬야 하는 데이터가 훨씬 적습니다.
포괄적인 소스 컨트롤 서비스가 있으면 새로운 애플리케이션을 많이 만들 수 있습니다. git에서는 누가 마지막으로 이 줄을 바꿨는지, 두 커밋이 어떤 관계인지처럼 저장소에 대해 무언가를 물어야 하는 CI 작업이나 도구가 저장소의 로컬 사본을 유지하거나, 벤더별 API가 답을 주기를 바라야 합니다. Scion에서는 클라이언트가 쓰는 모든 소스 컨트롤 질의가 API로도 제공되기 때문에, 많은 경우 작업에 로컬 저장소가 아예 필요 없습니다. 자동 bisect 파이프라인이나 자동 revert 파이프라인을 비롯한 여러 사내 도구는 이렇게 소스 컨트롤에 저렴하게 프로그래밍 방식으로 접근할 수 없었다면 대규모로 운영하기 어려웠을 것입니다.
모든 것을 수평 확장할 수 있어야 합니다. 가장 많을 때 저희는 git 미러를 수백 대 운영했는데, 이 때문에 용량에 큰 부담이 생겼고, 저장소가 미러의 디스크나 메모리 한계를 넘어서자 더는 확장할 수 없었습니다. Scion에서는 저장소 데이터가 분산되어 있고, 모든 구성 요소를 독립적으로 확장할 수 있습니다. 저장소 전체를 온전히 갖춘 사본은 서버를 포함해 어디에도 없습니다. 팩파일(git이 객체를 압축해 묶은 번들)에 해당하는 것이 없으므로 저장소 유지 보수도 필요 없습니다.
커밋은 비용이 적게 들고, 증분 방식으로, 락 없이 이뤄져야 합니다. git에서는 로컬에서 커밋한 다음 푸시해서 작업을 공유합니다. Scion에서는 모든 커밋, 리베이스, 병합이 서버에서 일어나므로 푸시할 것이 없지만, 그 대신 각 작업이 빨라야 합니다. 커밋을 만들고 그에 딸린 하위 데이터 구조를 갱신하는 비용이 저장소 전체 크기가 아니라 변경의 크기에 비례해야 하며, 그렇지 않으면 서버가 따라갈 수 없습니다. Scion의 개발 수명 주기에서는 main ref나 릴리스 브랜치를 제외하면 ref(브랜치나 태그처럼 커밋을 가리키는 포인터)를 되도록 쓰지 않게 합니다. 모든 서버가 합의해야 하는 전역 상태는 언젠가 닥칠 확장 문제이기 때문입니다.
작업 사본은 선택 사항이고, 처음부터 필요한 부분만 담도록 설계했습니다. 저희 모노레포는 워낙 크고 CI를 위해 하루에도 수천만 번 코드를 체크아웃하기 때문에, 가능하면 체크아웃을 피하고 싶었습니다. 예를 들어 Scion에서는 어떤 커밋과 그 병합 기준점(merge base) 사이의 diff가 필요한 CI 작업이 서버에 요청하기만 하면 됩니다. 쓰기도 마찬가지입니다. 많은 쓰기 워크로드 역시 체크아웃 없이 API만으로 처리할 수 있습니다. Scion의 프로토콜은 클라이언트가 요청한 디렉터리만 담는 스파스 체크아웃과, 파일을 필요할 때 디스크에 만들어 내는 가상화 체크아웃을 중심으로 설계되었습니다. 그래서 작업에 실제로 디스크 위의 파일이 필요할 때도 클라이언트는 실제로 읽는 만큼만 비용을 치릅니다.
Scion의 동작 방식
Scion을 만들 때 이 원칙들이 실제로 어떻게 맞물렸는지 알아 두면 도움이 됩니다. 여기서 얻은 통찰은 다른 소스 컨트롤 시스템에도, 더 넓게는 소프트웨어 개발 수명 주기의 다른 단계에도 적용할 수 있습니다.
데이터 구조
Scion에서 작업의 단위는 '체인지셋(changeset)'으로, write-ahead log에 기록되는 항목 하나입니다. 체인지셋에는 git 커밋에 기대할 만한 내용이 대부분 들어 있습니다. 다만 git 커밋이 트리를 가리키는 포인터를 저장하는 반면, 체인지셋은 첫 번째 부모1와 비교해 바뀐 파일 목록과 함께, 블롭 스토리지에 있는 압축된 파일 내용을 가리키는 콘텐츠 주소 기반(content-addressed) 포인터를 저장합니다. 체인지셋은 서버에서 만들어지며, 만들어지는 즉시 어디서나 쓸 수 있습니다.
Scion 체인지셋의 구조입니다.
이 구조 덕분에 체인지셋을 매우 높은 처리량으로 받아들일 수 있습니다. 받아야 할 팩파일도, 락이나 서버 간 조율도, 옮겨야 할 ref도 없기 때문입니다. 엄밀히 말하면 Scion도 ref를 지원하지만, 커밋을 만들 때도 가져올 때도 ref가 관여하지 않습니다. 그래서 ref를 옮기는 일은 체인지셋 생성과 별개로 Spanner 행 하나에 compare-and-swap을 수행하는 것으로 끝납니다.
체인지셋에는 바뀐 내용만 기록되므로, 체인지셋만으로는 누가 마지막으로 이 줄을 수정했는지, 어떤 커밋이 이 파일에 영향을 주었는지 같은 질문에 빠르게 답할 수 없습니다. 이런 질문에 답하기 위해 Scion은 체인지셋으로부터 추가 데이터 구조를 만듭니다. 파일 blame과 경로 이력을 위한 전용 구조, 커밋 그래프를 위한 스킵 리스트 등이 여기에 해당합니다. 저희는 체인지셋에 직접 속하지 않는 모든 것을 '파생 데이터(derived data)'라고 부르며, 전부 하나의 범용 메커니즘으로 계산합니다. 각 파생 데이터 유형은 재귀적으로 정의되므로, 어떤 체인지셋에 대한 값은 그 체인지셋의 부모들에 대한 값으로부터 계산됩니다.
이 메커니즘에는 세 가지 이점이 있습니다. 첫째, 새로운 데이터 구조로 어떤 작업을 더 빠르게 만들 수 있을 때 새 파생 데이터 유형을 쉽게 추가할 수 있습니다. 둘째, 유형마다 미리 계산할지 나중으로 미룰지 고를 수 있어서, 필요 없는 데이터를 만들어 두지 않아도 됩니다. 셋째, 클라이언트는 이 데이터 구조의 내부를 전혀 보지 않으므로, 클라이언트를 바꾸지 않고도 데이터 구조를 최적화할 수 있습니다. 시스템이 커 가면서 저희는 복사 감지나 경로 기반 파일 검색을 위한 새 인덱스처럼 새로운 파생 데이터 유형을 여러 번 추가했습니다.
Scion 확장하기
소수의 Scion 서버가 체인지셋 조회, diff 계산, 병합 기준점 찾기, 블롭 가져오기처럼 클라이언트에 필요한 모든 작업에 대해 소스 컨트롤 API를 제공합니다. 모든 소스 컨트롤 데이터는 콘텐츠 주소 기반이어서 한번 저장된 데이터는 절대 바뀌지 않으며, 어느 서버든 다른 서버에 확인하지 않고 그 데이터를 캐시할 수 있습니다. 그 결과 서버는 수평 확장이 가능하고 서로 조율할 일이 거의 없습니다. 사실상 이 서버들은 파생 데이터를 그때그때 계산해 결과를 Spanner에 다시 기록할 수도 있는 대형 캐시입니다.
Scion을 쓰는 수많은 시스템은 더 이상 자체 로컬 저장소를 유지할 필요가 없습니다. 예전에는 소스 컨트롤에 질문해야 하는 CI 작업이나 도구, 특히 커밋 조상 관계와 blame을 물어야 하는 경우에는 저장소를 가져와 유지하는 일이 큰 유지 보수 부담이었습니다. 이전 초기, 아직 자체 클라이언트나 저장소 포맷이나 프로토콜이 없던 시절에 Scion은 이런 '메타데이터' 질의에만 답했습니다. 파일 내용을 가져오고 작업 사본을 실제로 만들어 내는 일은 훨씬 더 많은 데이터를 다루는 작업이어서, 따로 설계가 필요했습니다.
Scion의 scn 클라이언트는 몇 가지 중요한 지점에서 git의 fetch 프로토콜과 다릅니다. 그 덕분에 git 서버보다 CPU를 훨씬 적게 쓰면서도 확장성이 매우 높은 아키텍처를 갖추기에 알맞습니다. Scion의 협상 과정에서는 클라이언트가 이미 무엇을 가지고 있는지 서버에 알리지 않습니다. 대신 클라이언트가 원하는 트리와 블롭만을 대상으로 동작합니다. 클라이언트는 루트 트리에서 시작해 로컬 저장소에 없는 트리를 확인하고 재귀적으로 요청한 다음, 블롭에 대해서도 같은 과정을 반복합니다. 모든 요청은 절대 바뀌지 않는 특정 객체에 대한 것이므로 어떤 캐시든 응답할 수 있고, 아키텍처는 전통적인 계층형 캐시와 매우 비슷해집니다. 수 기가바이트짜리 팩파일 하나로 응답하는 방식이 아니므로 이 과정은 효율적이고, 중간에 끊겨도 이어서 진행할 수 있습니다. 클라이언트는 원하지 않는 트리를 요청하지 않으면 그만이므로, 스파스 체크아웃은 물론 가상화 체크아웃에도 특별한 지원이 필요 없습니다.
플릿(fleet)에서는 클라이언트가 소켓을 통해 scion-daemon이라는 데몬과 통신하며, 이 데몬이 노드 전체의 객체를 저장합니다. 저희 노드는 대부분 모노레포에 접근해야 하고, 같은 노드에서 도는 작업들은 대부분 같은 객체를 재사용합니다. 각 데몬은 주기적으로 갱신되는 스냅샷에서 시작한 다음, 자기 리전에 있는 트리·블롭 캐시 서버인 scion-cache와만 통신합니다. 이 캐시 서버는 데몬이 그대로 읽을 디스크 포맷으로 메모리에서 객체를 직접 스트리밍하므로, 클라이언트에 없는 객체를 계산하거나 델타 압축을 하는 데 시간을 쓰지 않아도 됩니다. 캐시에 객체가 없으면 기준이 되는 scion-server에 요청하고, scion-server는 필요에 따라 Spanner나 클라우드 스토리지에서 데이터를 읽습니다.
scion-daemon, scion-cache, scion-server는 모두 이 프로토콜에 대해 똑같은 RPC에 응답하므로, 클라이언트는 캐시 토폴로지를 알 필요가 없습니다. 이론상으로는 어느 계층이든 다른 어느 계층과도 통신할 수 있지만, 장애 범위를 격리하기 위해 계층 구조를 엄격하게 지키도록 강제합니다. 리전 단위의 scion-cache에서 난 장애가 상위의 scion-server에 감당할 수 없는 부하를 몰아 전체 시스템을 멈춰 세우는 상황은 피하고 싶기 때문입니다.
Scion의 체크아웃 아키텍처입니다.
이 시스템의 각 계층은 99%가 넘는 캐시 적중률을 유지하며, 오래 유지해야 하는 상태가 없어서 필요하면 쉽게 증설할 수 있습니다. 이제 Scion 인프라는 CPU와 메모리 요구량을 기준으로 이전 git 미러링 인프라의 200분의 1 규모입니다. CI와 연구 작업은 코드를 약 100배 빠르게(몇 분이 아니라 몇 초 만에) 체크아웃하며, 덕분에 플릿 전반에서 상당한 용량을 확보했습니다. CI에서만 CPU 용량을 25% 아꼈습니다. 클라이언트도 캐시도 저장소 유지 보수를 할 필요가 없어서 작업의 수명 주기 관리도 단순해집니다.
Scion을 만들며 배운 것
저희가 Scion을 만들기 시작한 시기는 Claude Mythos Preview와 Claude Tag를 사내에서 쓸 수 있게 된 시기와 거의 겹칩니다. 두 릴리스는 Scion의 필요성을 키우는 동시에, 저희가 Scion을 만드는 속도도 크게 끌어올렸습니다.
특히 인상적인 사례가 하나 있습니다. 올해 초 저희는 git의 데이터를 Scion으로 가져오는 수집(ingestion) 파이프라인의 첫 버전을 프로토타입으로 거의 손으로 작성했습니다. 꽤 잘 만들었다고 생각했는데, Claude Mythos Preview의 초기 사내 스냅샷을 써 보고 나서 생각이 달라졌습니다. 전체를 다시 작성해 달라고 했더니, 별다른 지시 없이도 메모리는 20분의 1만 쓰고 속도는 4배 빠른 버전을 만들어 냈습니다. 그러면서도 수집 순서와 데이터 구조에 관한 암묵적인 불변 조건을 모두 지켰습니다.
2026년 1월부터 9월까지 Scion과 Antique 코드베이스에 한 주 동안 병합된 변경 건수입니다.
Scion을 만들고 운영하며 배운 것들은 에이전트 규모의 소프트웨어를 만드는 일이 어떤 모습일지에 대해 흥미로운 교훈을 줍니다.
작은 팀이 빠르게 개발하는 일이 더 흔해질 것입니다. 7명으로 이뤄진 팀이 Scion과 Antique(저희 코드 리뷰 도구로, 이것만으로도 블로그 글 한 편은 충분히 쓸 수 있습니다)를 모두 만들었고, 관련 시스템도 여섯 개쯤 더 만들었으며, 5개월 만에 이 시스템들로 완전히 이전했습니다. 그동안 하루에 병합되는 코드의 양은 10배로 늘었습니다. 예전 같으면 이런 소스 컨트롤 시스템을 개발하고 배포하는 데 훨씬 많은 엔지니어가 투입되어 여러 해에 걸쳐 단계적으로 이전해야 했을 것입니다. 저희는 이렇게 빠르고 민첩한 이전이 앞으로 더 흔해질 것으로 봅니다.
엔지니어의 가치는 줄지 않았지만, 하는 일은 바뀌고 있습니다. 이 시스템을 작업한 엔지니어들은 이제 모두 코드를 작성하는 일만큼은 Claude가 자신보다 낫다고 평가할 것입니다. 하지만 시스템 사이를 잇는 상위 구성 요소를 이해하고 설계 수준의 트레이드오프를 판단하는 귀중한 역할은 여전히 엔지니어가 맡았고, 해결하려는 문제와 달성해야 할 규모를 잘 알고서 선택을 내렸습니다. 엔지니어가 하는 일이 Claude에게 안 된다고 말하는 것인 경우가 아주 많았습니다. 에이전트는 애초에 허용되지 말았어야 할 패턴을 맞추려고 핵심 시스템 제약을 어기기도 합니다. 이전 작업에서는 이런 일이 특히 잦았습니다. 예를 들어 어떤 변경이 언제 main에 병합되었는지 알아내려고 코드 리뷰 도구에 묻는 대신, 커밋 로그를 처음부터 차례로 읽어 가며 무작정 찾으려 한 시스템이 여럿 있었습니다. Anthropic은 적대적 리뷰(adversarial review)도 폭넓게 활용합니다. 여러 면에서 매우 효과적이지만 시야가 좁아질 수도 있어서, 숙련된 엔지니어가 가정에 불과한 우려 때문에 Claude가 시스템 일부를 과하게 설계하지 않도록 방향을 잡아 줘야 했습니다. 예를 들어 한 리뷰는 다른 사내 서비스를 신뢰하는 문제에 지나치게 방어적이었고, 그 결과 Claude가 과도한 검증 로직과 복잡성을 덧붙였습니다. 저희 팀원들은 지금도 이 시스템에 대한 변경 요청을 모두 리뷰하지만, 이제는 코드를 한 줄 한 줄 읽기보다 변경의 의도를 살핍니다.
최적화와 품질을 크게 끌어올릴 수 있었습니다. Claude는 저희가 직접 하는 것보다 훨씬 빠르게 엄청난 양의 코드를 작성할 수 있었고, 그 덕분에 Scion은 저희가 다뤄 본 코드베이스 가운데 테스트와 방어 장치가 가장 잘 갖춰진 축에 듭니다. 촉박한 일정 속에서도 저희는 지금껏 겪은 사소하지 않은 인프라 및 소스 컨트롤 상호작용을 빠짐없이 재현하는 밀폐형(hermetic) 시뮬레이션을 만들었고, 퍼징과 정교한 속도 제한도 갖췄습니다. Claude는 대수롭지 않다는 듯 중요한 최적화를 찾아내기도 했습니다. 예를 들어 저희 인덱스 하나를 활용하지 못하던 조상 관계 질의를 알고리즘 수준에서 최적화했는데, 전문가라면 분석하고 튜닝하는 데 며칠에서 몇 주는 걸렸을 일이었습니다. 그리고 다음 날 그런 일을 또 해냈습니다.
네이티브 Scion 저장소에서 관측한 성능 개선입니다.
모노레포 보안을 새로운 방식으로 다룰 토대를 마련했습니다. 거대한 모노레포에서 안전, 보안, 컴플라이언스를 관리하는 일은 크기와 규모를 관리하는 일만큼 중요합니다. 저희는 처음부터 이 점을 염두에 두고 Scion을 만들었습니다. Scion은 저장소에 대한 정교한 접근 제어를 지원하며, 개별 디렉터리에 권한을 적용할 수도 있어서 모노레포의 이점을 잃지 않으면서 가장 민감한 코드를 보호할 수 있습니다. 또한 저희가 만든 코드 리뷰 도구는 승인에 관한 복잡한 의미적 제약 조건을 표현할 수 있습니다. 그래서 주석만 바꾼 변경 같은 단순한 경우와 민감한 로직 변경을 구분할 수 있고, 사람 리뷰어는 가장 파급력이 큰 변경에 집중할 수 있습니다.
한 차원 높은 운영 수준이 가능해졌습니다. 저희 팀은 Claude Tag를 많이 쓰며, 덕분에 시스템의 각 구성 요소를 모니터링하는 데 도움을 받았습니다. 예를 들어 Slack 채널을 만들고, 그 채널의 Claude에게 구성 요소 하나의 상태에만 집요하게 매달리는 임무를 맡겼습니다. 저희는 이런 Claude를 '슈퍼팬(superfan)'이라고 부릅니다. scion-daemon 슈퍼팬, scion-cache 슈퍼팬, Antique 병합 큐 슈퍼팬 등이 있습니다. 이들은 텔레메트리와 로그에 접근할 수 있으며, 차트를 새로 고치며 이상한 점을 찾는 일 말고는 할 일이 없는 노련한 엔지니어처럼 움직입니다. 모든 시스템에 전통적인 알림도 걸어 두었지만, 슈퍼팬은 미묘하고 처음 보는 문제까지 잡아내기 때문에 이에 비하면 알림은 단조로워 보일 정도입니다.
기존의 전제를 처음부터 다시 생각하고 있습니다. 이 프로젝트를 계기로 저희는 사람 규모에 맞춰 설계된 다른 워크플로도 아주 냉정하게 다시 들여다보게 되었습니다. 예를 들어 제대로 된 병합 큐는 에이전트 규모에서는 별 의미가 없습니다. 테스트가 돌아가는 동안 수백, 심지어 수천 건의 변경이 병합될 수 있다면 CI란 대체 무엇을 뜻할까요? 저희는 업계 표준처럼 병합 큐에 저장소 전역 락을 거는 방식을 효과적으로 재현하지 못했고, 대신 병합 후, 배포 전 단계의 자동화 테스트에 투자했습니다. 이 방식에서는 동시에 들어온 변경끼리 충돌할 수 있지만, Claude는 보통 사람이 충돌을 알아차리기도 전에 고쳐 냅니다.
더 넓은 생태계에 기여하기
저희는 Scion을, 점점 더 유능해지는 AI 에이전트가 불러온 확장 문제에 대한 해답 가운데 하나일 뿐이라고 봅니다. 이런 세부 사항을 공유하는 것은 비슷한 과제를 팀들이 어떻게 풀 수 있는지 보여 주는 예시가 되기를 바라서이며, 저희의 해법이나 고려 사항이 모든 경우에 들어맞으리라고 기대하지는 않습니다.
Scion은 일반적인 용도로 git을 대체하기에는 결코 적합하지 않습니다. 여기서 설명한 개념은 수만 명의 엔지니어나 수많은 에이전트가 엄청난 양의 코드를 쏟아 내는, 정말로 거대한 모노레포에서만 의미가 있습니다. 게다가 Anthropic은 사내 용도로 쓸 수 있는 토큰이 다른 어떤 기업이 현실적으로 쓰려 할 양을 훨씬 넘어선다는 점에서 독특합니다. 저희가 이렇게 하는 것은 저희의 소프트웨어 개발 수요를 해결하는 동시에 Claude의 역량을 시험하기 위해서입니다.
현실적으로 말하면, Scion을 다른 조직에도 두루 쓸모 있는 형태로 제공하기는 어렵습니다. Scion은 git과 크게 다르기 때문에, 도입하려는 회사는 개발 수명 주기의 모든 부분을 이전해야 하고, 전용 코드 리뷰와 코드 검색과 CI도 갖춰야 합니다. 저희가 사내에서 쓰는 이 구성 요소들은 저희 환경에 맞춰 고도로 특화되어 있어서 다른 조직이 도입하기 어려울 것입니다. 모두를 만족시키려는 공개 버전을 만들어 봐야 실제로는 별 쓸모가 없을까 걱정되기도 합니다.
하지만 저희는 이런 종류의 문제가 앞으로 6개월에서 12개월 사이에 더 흔해질 것으로 예상하며, git을 쓰는 모든 회사가 비슷한 과제를 각자 홀로 떠안는 것은 엔지니어링 자원을 비효율적으로 쓰는 일입니다. 그래서 저희가 할 수 있는 가장 영향력 있는 일은 저희의 생각을 공유하는 것이라고 봅니다. 그러면 다른 개발자들이 전체 모델을 벗어나지 않고도 Scion에서 가장 성공적이었던 부분 일부를 git에 적용할 수 있습니다. git 서버가 git 클라이언트와 같은 방식으로 동작할 필요는 없습니다. 확장성을 크게 개선하는 새로운 서버 아키텍처도 이미 나와 있습니다. git 플랫폼은 Scion처럼 포괄적인 서버 측 RPC를 제공할 수 있고, 어쩌면 git 클라이언트가 그 RPC를 쓸 수 있도록 여러 포지(forge)에 걸쳐 표준화된 방식으로 제공할 수도 있습니다. 협상 프로토콜도 지금과 똑같은 모습일 필요는 없으며, git의 여러 스파스 기능과 얕은 클론 기능이 서로 잘 맞물리도록 만들 수도 있습니다.
마지막으로, git 커뮤니티가 거의 20년 동안 수백만 명의 개발자를 위해 이 플랫폼을 확장해 왔다는 점을 짚고 싶습니다. 저희의 기여는 그보다 훨씬 좁습니다. 에이전트 기반 소프트웨어 개발이 이런 시스템과 어떻게 맞물리는지 저희가 먼저 엿본 내용을 공유해서, GitHub, GitLab, 오픈소스 커뮤니티와 함께 개발자의 달라지는 요구를 뒷받침하려는 것입니다. 소프트웨어 개발 수명 주기가 AI의 기하급수적 발전과 맞닿는 지금, 이것은 저희 모두가 함께 마주한 일입니다.
Footnotes
-
병합 커밋에서 첫 번째 부모를 기준으로 바뀐 파일을 저장하는 것은 취향에 따른 선택입니다. 실제로 모노레포에서 트렁크 기반 개발을 할 때 사람들이 이력이나 blame을 신경 쓰는 커밋은 main 라인에 있는 커밋뿐이었습니다. ↩