6개월 만에 CI 작업량이 25배 급증했다. 지속 가능한 해결책을 찾기까지 테스트 선택 서비스를 세 차례나 패치해야 했다.
Anthropic 엔지니어들은 2021~2025년과 비교해 분기당 평균 8배 많은 코드를 출시한다. 그 코드의 80%는 Claude가 작성하며, PR 리뷰와 승인에서도 Claude의 역할이 크다.

여기에 코드베이스 전반의 테스트 수도 10배로 늘었고, 엔지니어 수는 거의 그대로였다. 이 모든 요소가 맞물려 6개월 사이에 CI 작업 수가 25배 급증했다 (계산이 맞지 않는다고 느낄 수 있는데, 뒤에서 설명하겠지만 모든 PR에서 모든 테스트가 실행되지는 않는다).
이로 인해 테스트 영향 분석(test impact analysis) 서비스가 여러 차례 과부하 위기에 처했다. 다음 병목이 되지 않으려면 서비스 전체를 뜯어고쳐야 했고, 결국 아키텍처를 처음부터 다시 설계했다. 하지만 그 과정은 순탄하지 않았다. 세 차례의 임시 수정을 거쳐야 했는데, 각각의 효과는 70일, 29일, 그리고 하루도 채 되지 않았다.
에이전트가 코드 생성과 리뷰를 계속 가속화하면서, CI 확장은 머지않아 더 많은 개발팀이 직면할 과제가 될 것이다. 에이전트를 운용하는 팀들이 더 많은 PR과 테스트를 만들어낼수록, 수평 확장 가능한 테스트 선택 아키텍처가 업계 표준으로 자리 잡을 것으로 예상한다.

이 글에서는 Anthropic에서 테스트 영향 분석 서비스를 어떻게 확장했는지, 그리고 시행착오 끝에 얻은 교훈인 '항상 지수적 성장을 염두에 두고 설계하라'를 공유하려 한다. 더 큰 머신 도입, 프로세스 병렬화, 서비스 재시작(놀랍게도 여전히 꽤 효과적이다) 같은 확장 기법들은 워낙 흔해서, 이 글의 핵심 인사이트가 아니다.
핵심은 이렇다. 이런 기법들이 예전에는 상당한 시간을 벌어줬지만, 지금은 그 효과가 훨씬 짧다. 반면 코드 작성이 더 이상 병목이 아닌 지금, 서비스를 완전히 재설계하는 데 걸리는 시간도 크게 줄었고 훨씬 지속 가능한 방향이다.
이런 부담을 미리 예측하고 아키텍처가 어떻게 발전해야 하는지 미리 설계할수록, 반쪽짜리 임시방편에 낭비하는 시간을 줄일 수 있다.
내 동료 중 상당수는 모든 변경 사항에 여전히 모든 테스트를 실행하는 조직에서 일한다. 어느 정도까지는 통하는 방식이지만 확장성이 없다. CI 게이트가 점점 길어지고, 비용도 늘어나며, 신뢰도도 떨어지기 때문이다.
또한 사람은 어떤 테스트 실패가 자신과 무관한지 잘 판단하지만, 에이전트는 더 많은 맥락과 방향 제시가 필요하다. 에이전트에게 유효한 테스트를 명확히 정해주면 스스로 검증하고 더 효과적으로 반복 작업을 할 수 있다.
Anthropic에서는 과거 성능과 패키지 연관성을 기반으로 각 변경 사항에서 어떤 테스트를 실행할지 결정하는 결정론적 테스트 영향 분석, 즉 테스트 선택 서비스를 구축했다. 이런 방식은 낯설지 않으며, 이 영역을 다루는 벤더 카테고리도 이미 존재한다.
이 서비스는 두 가지 결정론적 컴포넌트가 동기화 상태를 유지하는 데 의존한다:
효과적인 구조지만, 매 초 여러 CI 작업이 실행될 때 리스너가 PR 대기열을 따라잡지 못하기 시작한다. AI 네이티브 SDLC에서는 작은 지연도 큰 영향을 미친다. 예를 들어, 리스너가 20분 뒤처지면 수만 건의 테스트 업데이트가 셀렉터에 반영되지 않는다.
이 모든 것이 단일 프로세스로 실행됐다. 테스트별 이력을 유지하려면 결과를 적용하는 단일 라이터(writer)가 필요했기 때문이다. 이 v0 설계로 인해 수평 샤딩이 불가능했다.
작년 10월, 서비스는 이미 한계 징후를 보이기 시작했고 이틀 연속으로 페이지를 받았다.
첫 번째 조치는 간단했다. 서비스를 실행하는 코어 수를 두 배로 늘렸다. 효과가 오래가지 않을 것도 알고 있었다.

추세가 명확했음에도 담당 주체가 불분명했다. 아무도 인프라를 하나 더 떠안고 싶지 않았고, CI 팀에는 더 급한 문제들이 산적해 있었다.
이 시점에 리스너 지연이 쌓이면서 페이지를 꽤 자주 받기 시작했다. 장기적인 해결책을 모색하기 위해 사내 버전의 Claude Tag에서 서비스 모니터링 전담 세션을 장기 운영하기 시작했다. 리스너 지연이 5만 건 이상 밀릴 때마다 Claude가 알림을 보내 다음 조치를 논의하는 대화를 이어갔다.
이 방식이 수개월간 이어졌는데, 과거의 시도나 맥락을 매번 다시 설명하지 않아도 되는 것이 큰 도움이 됐다. Claude는 종종 전면적인 재설계를 주장했지만, 우리는 대부분 또 다른 임시 패치로 결론을 냈다.

2월이 되자 CI 작업의 기하급수적 증가가 다시 서비스를 압박하기 시작했다. 이번에는 병렬화를 택했다.
리스너에 필요한 것은 결과 순서를 보장하는 단일 라이터가 아니라, 코드베이스의 각 영역별로 테스트 결과 순서를 맞추는 패키지당 단일 라이터였다. Claude가 각 패키지의 상태를 자체 워커를 가진 샤드로 분리하는 코드를 생성해 줬다.
이 수정도 오래가지 않을 것을 알고 있었지만, 겨우 29일밖에 버티지 못할 줄은 몰랐다.

3월에는 평일 오후 중반이면 프로세스가 메모리 한계에 다다랐다. 이번에도 빠른 해결책을 찾아봤지만:
매일 재시작이 오히려 서비스를 점점 더 뒤처지게 만든다는 사실도 발견했다. 서비스가 1시간 이상 뒤처지는 상황이 몇 차례 발생했는데, 그때마다 엄청난 수의 작업 결과가 리스너에 기록되지 않았다.
분명히 해두자면, 이는 해당 PR에서 CI가 전혀 실행되지 않았거나 테스트되지 않은 코드가 프로덕션에 배포됐다는 뜻이 아니다. 리스너가 일부 결과를 수집하지 못했고, 그 결과 테스트 선택 컴포넌트가 오래된 데이터로 PR에서 실행할 테스트와 제외할 테스트를 결정했다는 의미다. 대체로 이미 심각하게 불안정하거나 전반적으로 실패하는 테스트들이 실행되는 문제로 이어졌다.
이미 한참 전에 재설계했어야 할 타이밍이었다. 우리는 Claude의 조언을 받아들여 테스트 선택 서비스에 데이터베이스, 정확히는 인메모리 데이터 스토어를 붙였다. 이를 통해 싱글톤이 담당하던 대규모 인메모리 처리를 효과적으로 분리할 수 있었다.
이제 어떤 리스너 워커든 결과를 처리하고, 인메모리 스토어의 저널에 추가한 뒤, 아무것도 메모리에 유지하지 않고 다음으로 넘어갈 수 있다. 무상태(stateless)이므로 수평 확장이 가능하다. 별도의 작은 컨슈머 프로세스가 몇 초마다 저널을 테스트별 이력으로 집계하고, 셀렉터는 관련 결과 이력을 빠르게 조회할 수 있다.

이 분산 아키텍처는 운영 비용이 더 들지만, 불안정한 싱글톤보다 확장과 메모리 프로파일링이 훨씬 수월하다. 이 프로젝트는 엔지니어 한 명이 3주 만에 완료했다. 1년 전이었다면 한 분기 가까이 걸렸을 것이다.

저널 크기와 워커 수 조정 같은 세부 튜닝은 Claude가 대부분 자율적으로 수행했으며, 이후 서비스는 안정적으로 운영되고 있다.
2025년 10월로 돌아갈 수 있다면, 지금 알고 있는 것들을 바탕으로 이 프로젝트와 다른 프로젝트들을 다르게 접근했을 것이다.
가장 큰 차이는 AI의 지수적 성장을 처음부터 고려했을 것이라는 점이다. 엔지니어당 에이전트 수가 늘고 가속화된 PR 승인이 고도화될수록, CI 작업은 기하급수적으로 증가한다.
Claude가 더 작고 세분화된 PR을 선호하면서 Anthropic에서 PR의 형태 자체가 바뀌었다 (이것이 모든 PR에서 모든 테스트를 실행하지 않아야 하는 또 다른 이유다). 이로 인해 하루 CI 작업 수가 늘었다. 또한 에이전트가 야간과 주말에도 푸시하면서 기저 활동량이 높아졌지만, 사람 엔지니어들이 여전히 상당수의 PR을 주도하고 승인하는 만큼 부하는 여전히 불규칙하게 몰린다.
개발팀에게 전하고 싶은 조언은 이렇다. 직접 구축하든 구매하든, 두 분기 안에 아키텍처가 25배 부하를 감당해야 한다고 가정하라. '과도한 설계'라는 개념이 서서히 희미해지고 있거나, 적어도 그 기준이 훨씬 높아지고 있다. 예산이 허락한다면 v0 설계 단계부터 예상 규모의 10~20배를 염두에 두어도 된다.
서비스를 Claude의 눈과 귀가 될 수 있도록 계측하라. 그러면 Claude가 우리가 수동으로 하는 것보다 훨씬 잘, 빠르게 문제를 단계적으로 파악하고 개선할 수 있다. 특히 CI 작업의 입력 수와 출력 수가 동일한지 반드시 확인하라.
처음부터 프로세스 외부에 상태를 두어라. 또한 측정이 가능하고 카나리 변경을 적용할 수 있는 경우가 아니라면, 중요한 서비스를 단일 인스턴스로 운영하는 것도 피하는 것이 좋다. CI는 너무 빠르게 진화하고 있어 다른 방식으로는 따라가기 어렵다.
Claude Tag를 활용한 CI 온콜 가속화 방법도 별도로 작성했다 (베타).