Anthropic의 새 엔지니어링 포스트에서 가장 가져다 쓸 만한 대목은 claude.ai가 2주 만에 3배쯤 빨라졌다는 사실이 아니다. 팀이 남기고 간 장치, 즉 아래로만 움직일 수 있는 CPU 명령어 수 기반 CI 게이트다. 이 게이트가 앞으로의 모든 풀 리퀘스트를 성능 테스트로 바꿔 놓는다.
핵심 요약
- 75번째 백분위에서 claude.ai 신규 로딩이 입력 가능한 화면에 도달하는 시간은 3.1초에서 0.55초로 줄었다. 새 Claude Code 세션은 0.8초에서 0.3초가 됐다.
- 2주 동안 3,000건이 넘는 변경이 머지됐고, 고객이 겪은 장애도 롤백도 없었다.
- 핫 패스 두 곳의 명령어 수가 각각 48%, 31% 줄었고 실제 소요 시간은 78%, 44% 감소했다. 팀이 시간 측정 대신 명령어 수로 CI를 막을 수 있게 만든 근거다.
왜 스톱워치가 아니라 명령어 수인가
사용자가 체감하는 것은 지연 시간이지만, 밀리초 단위 측정값은 빌드를 실패시키기에는 너무 들쭉날쭉하다. Anthropic은 대표성 있는 수치 대신 결정론적인 수치를 찾았고, 그 수치가 실제 지연 시간을 따라가는지 먼저 증명한 뒤에야 신뢰했다.
증명은 대화의 메시지 트리를 조립하는 루틴에서 이뤄졌다. Valgrind로 프로파일링하자 명령어의 4분의 1이 메가모픽 딕셔너리 조회였고, 같은 메시지 ID를 세 번씩 따로 해석하고 있었다. 이 부분과 Claude Code 출력의 상태 표시줄 스캐너를 고치자 명령어 수가 각각 48%, 31% 줄었다. 같은 경로의 실제 소요 시간은 78%, 44% 감소했다. 그제야 명령어 수는 CI의 영구 상한선이 됐고, 야간 작업이 상한선 아래로 들어온 빌드가 나올 때마다 기준을 낮춘다.
이 방식을 둘러싼 규율은 메커니즘만큼이나 중요했다. 불안정하다고 판명됐거나 사용자 지연 시간과 무관하게 움직이는 벤치마크는 감수하지 않고 삭제했다. 그러지 않으면 모델은 아무도 원하지 않은 언덕을 오른다. React 커밋 횟수, V8 커버리지 호출 횟수, 스타일 재계산, DOM 변경도 모두 같은 심사를 거쳤다.
3배라는 수치의 기준
범위는 무언가를 내보내기 전에 먼저 정했다. Claude는 Datadog MCP 서버로 사용 텔레메트리를 읽어 전체 활동의 95%를 차지하는 네 가지 동선을 골라냈다. 앱 실행, 새 대화 시작, 기존 대화 열기, 메시지 전송이다. 이 네 가지가 웹과 데스크톱을 아우르는 13개 계측 지표가 됐고, 각 지표는 사용자 조작으로 시작해 렌더링으로 끝나는 구간으로 정의됐다.
13개 목표 중 12개는 사흘 만에 달성됐다. 수단은 화려하지 않았다. React 초기화 중에도 입력이 되도록 HTML에 정적 입력창을 박아 넣었고, 데스크톱 셸이 재컴파일을 건너뛰도록 V8 코드 캐시를 미리 컴파일해 뒀다. 대화를 옮겨도 입력창은 마운트 상태를 유지했고, 마우스를 올리면 세션을 미리 가져왔으며, 사이드바 리렌더링은 90% 줄였다. Anthropic은 이렇게 아낀 대기 시간을 하루 수만 사용자-시간으로 집계한다.
세어 봐야만 보이는 버그들
그다음에 나온 목록은 성능 개선 백로그라기보다 어떤 대시보드도 보고 있지 않던 것들에 대한 감사에 가깝다. 훅을 전수 조사하자 키를 누를 때마다 입력창을 리렌더링하는 훅이 6,900개 나왔다. :root:has() 선택자 하나가 모든 DOM 변경에 24밀리초를 물리고 있었다. 잊힌 location.reload() 하나는 어떤 로딩 지표에도 잡히지 않은 채 하루 50만 번씩 실행됐다. 똑같은 캐시 스냅샷이 메인 스레드에서 분당 두 번씩 IndexedDB로 복제되고 있었다.
가장 기묘한 것은 완성된 코드 블록에서 1초씩 멈추는 현상이었고, 원인은 엠 대시였다. Latin-1이 아닌 문자가 하나만 있어도 V8은 문자열 전체를 UTF-16으로 붙들고, 그 결과 구문 강조 정규식이 전부 느린 2바이트 경로로 떨어진다. 블록을 1바이트 문자열로 먼저 복사하는 코드 20줄로 문제는 사라졌다.
레이아웃 이동이 이 점을 가장 분명하게 보여준다. 사이드바가 한 번 튈 때 누적 레이아웃 이동 점수는 약 0.008로, 페이지를 양호로 판정하는 0.1 기준을 한참 밑돌았다. 표준 지표로는 아무 문제가 없었다는 뜻이다. 대신 Layout Instability API의 원시 데이터를 읽고 화면 영역별로 이동을 분류하자, 웹 로딩의 31%에서 페이지가 이미 쓸 수 있게 된 뒤에 무언가가 움직이고 있었다.
더 어려운 수치는 롤백 0건이다
2주간 머지 3,000건은 처리량에 관한 주장이다. 첫 페인트와 입력창처럼 노출도가 높은 핫 패스에서 장애도 롤백도 없었다는 것은 프로세스에 관한 주장이고, 베낄 만한 쪽은 이쪽이다.
장치 하나하나는 평범했다. 모든 풀 리퀘스트에 자동 리뷰와 최소 한 명의 사람 승인을 걸었고, 최적화가 보호할 대상의 단위 테스트를 먼저 작성했다. 사용자 눈에 보이는 변경은 수명이 짧은 플래그 뒤에 두고 직원, 사용자 1%, 전체 순으로 단계적으로 풀었다. 평범하지 않았던 것은 규모다. 플래그를 200개 가까이 열어 그중 절반 이상을 2주 안에 회수했고, 전체 풀 리퀘스트의 약 3분의 1은 수정이 아니라 새 텔레메트리나 가드레일을 담고 있었다. 계측은 후속 티켓이 아니라 변경의 일부로 취급됐다.
이것이 중요한 이유
측정은 그동안 0단계였다. 지표를 내보내고 데이터가 쌓이기를 기다린 뒤에야 문제를 이해하기 시작했다. 주어진 수치라면 무엇이든 최적화하는 에이전트 앞에서 측정은 등반의 1단계가 된다. 그리고 희소해지는 자원은 애초에 무엇에 수치를 붙일지 정하는 판단으로 옮겨간다. 83만 줄 규모의 Rust 재작성이나 에이전트에게 코드를 맡기면서도 배포 권한은 사람이 쥔 Perplexity처럼, 에이전트 비중이 큰 다른 엔지니어링 사례에서도 같은 역전이 보인다.
Anthropic은 이를 과장하지 않으려 조심한다. 자체 정리 글은 이 루프가 생산적이었지만 자율적이지는 않았다고 적는다. 목표와 트레이드오프, 승인은 사람 몫으로 남았고, 모델이 기본값보다 범위를 덜 보수적으로 잡도록 계속 밀어붙이는 일이 상시 과제였다. 이를 템플릿으로 읽는 팀에게 불편한 함의는 병목이 리뷰 역량과 무엇을 측정할지 고르는 안목으로 옮겨간다는 점이다. 둘 다 에이전트를 늘린다고 늘어나지 않는다.
FAQ — 자주 묻는 질문
이번 스프린트는 어떤 모델이 수행했나
Anthropic은 베타 상태의 Claude Tag를 썼고, 그 위에서 Opus 5.5와 대체로 비슷한 수준이라고 설명한 내부 연구용 모델을 돌렸다고 밝혔다. 작업은 전용 도구가 아니라 공유 Slack 채널 한 곳에서 조율됐다.
변경 사항은 사람이 검토했나
그렇다. 모든 풀 리퀘스트가 자동 리뷰를 거쳤고 최소 한 명의 사람 승인이 필요했다. 사용자 눈에 보이는 변경은 기능 플래그 뒤에서 직원, 사용자 1%, 전체 순으로 점진 배포됐다.
내부 모델이 없는 팀도 이 방식을 따라 할 수 있나
메커니즘은 모델을 가리지 않는다. 결정론적 지표가 지연 시간과 상관관계를 갖는다는 것을 증명한 뒤 CI에서 그 값을 조여 나가면 된다. 따라 할 수 없는 쪽은 처리량이다. 2주에 머지 3,000건은 대부분의 팀이라면 먼저 구축해야 할 리뷰 역량과 계측을 전제로 한다.






