1. 핵심 요약
Netflix AI 플랫폼 팀의 스태프 엔지니어 Rajat Shah가 "성능 엔지니어링에 AI 에이전트를 투입해 처리량을 늘린" 실전 플레이북을 공유하는 발표다. 핵심 주장은 다음과 같다.
- 코딩 에이전트가 코드 생성 속도를 10배 끌어올리면서, 정작 그 코드의 실행 효율(컴퓨트 비용)은 따라가지 못하는 간극이 벌어지고 있다. 에이전트는 프레임워크·내부 코드베이스의 특수한 관례를 모르기 때문에 비효율적인 패턴을 그대로 양산한다.
- 프로파일링 데이터(콜스택, self/inclusive CPU)는 언어·런타임과 무관하게 구조가 거의 동일하기 때문에, LLM 에이전트가 이를 읽고 병목을 찾는 작업에 적합하다는 것이 이 실험의 핵심 가설이었다.
- 실제로 Netflix는 프로파일링 데이터를 LLM에 먹여서 O(n²) 같은 안티패턴을 자동으로 찾아내고, Git 저장소를 체크아웃해 정확한 수정 코드리뷰까지 5분 이내에 만들어내는 데 성공했다.
- 더 나아가, 한 서비스에서 발견한 안티패턴(예: 핫패스에서 매 반복마다 생성되는 카운터 객체)을 크로스 레포 검색으로 확장해 7개 서비스에서 동일 패턴을 찾아내 0.5~4.6% CPU 절감 기회를 발견했다.
- 이 경험을 "패턴/안티패턴 카탈로그"라는 마크다운 기반 Git 저장소로 구조화해, 무상태(stateless) LLM 에이전트와 결합함으로써 조직 전체가 공유하는 장기 기억(fleet-wide memory)을 만들 것을 제안한다.
- 노이즈를 줄이기 위한 3단계 검증 파이프라인(단위/통합 테스트 → 카나리 배포 비교 → 사람 승인)을 제시하며, "프로파일러는 추정치를, 카나리는 실측 근거를 준다(Profiler gives the estimate, canary gives ground truth)"는 멘탈모델을 강조한다.
- 마지막으로 이 워크플로를 사후대응(reactive) → 코드리뷰 단계 개입(shift-left) → 코드 작성 단계 개입(proactive)의 3단계로, 그리고 자동화 수준을 Level 1(수동 LLM 호출) → Level 2(고정 워크플로 오케스트레이션, 이 발표가 다룬 수준) → Level 3(에이전트가 스스로 계획·추론하는 완전 자율, 샌드박싱/보안 투자가 선행되어야 함)로 단계적으로 발전시킬 것을 권한다.
2. 상세 내용
2.1 문제: 왜 성능 엔지니어링은 스케일하지 않는가
- "와이드 코딩(wide coding)" 시대: 코딩 에이전트가 발전하면서 더 많은 엔지니어가 더 빠르게 코드를 만들어낸다. 하지만 에이전트는 "코드를 빠르게 출시하는 것"에 튜닝돼 있지 늘 "가장 빠르게 실행되는 코드"를 쓰지는 않는다. 그 결과 컴퓨트 비용이 코드 생산 속도와 비슷한 속도로 증가한다.
- 근본 원인: 에이전트는 특정 플랫폼·프레임워크·내부 코드베이스 관례를 모른다. 그래서 이미 봤던 다른 코드베이스의 패턴을 그대로 가져오거나, 팀이 예상하지 못한 새로운(하지만 비효율적인) 패턴을 발명해서 쓴다.
- 기존 "인간 성능 엔지니어"의 워크플로: (1) 프로덕션 인스턴스에서 프로파일링 트리거 → (2) 원시 데이터(콜스택의 JSON 구조) 다운로드 → (3) 시각화 도구로 열어서 CPU 소모 지점을 눈으로 찾는 "보물찾기" → (4) 병목이 될 만한 코드 경로/패키지를 코드베이스에서 검색 → (5) 운 좋게 근본 원인을 찾으면 코드리뷰 작성·머지. 이 과정을 배우는 데만 러닝커브가 있고, 병목을 식별하는 데만 수십 분이 걸린다. 그래서 실제로는 새벽 2시에 CPU 문제로 장애가 터졌을 때만 이 작업을 한다 — 즉 거의 하지 않는다.
2.2 핵심 질문과 두 가지 가설
질문: "LLM이 이 프로파일링 데이터를 읽을 수 있을까? 인간 엔지니어가 20분 걸려 하던 핫패스 식별을 LLM 에이전트가 더 빠르게 할 수 있을까?"
이 실험을 뒷받침한 두 가지 전제:
- 프로파일러는 언어에 상관없이 같은 언어로 말한다. Java, Python, Go 등 어떤 언어로 작성됐든, 프로파일러는 단일 인스턴스에서 실행되며 콜스택, self CPU, inclusive CPU를 고빈도로 샘플링한다. 즉 프로파일링 데이터의 출력 구조는 런타임과 무관하게 매우 유사하고 잘 정형화돼 있어 LLM 에이전트가 다루기 좋다.
- 코딩 에이전트는 공개 코드로부터 흔한 패턴을 이미 학습했다. O(n²) 반복문, 루프 불변식(매번 계산할 필요 없는 값을 반복문 밖으로 빼지 않는 경우), 반복적인 객체 할당, 배칭으로 최적화 가능한 컨텐션 등은 이미 좋은 품질의 코드로 학습된 에이전트라면 패턴 인식으로 쉽게 잡아낼 수 있다.
2.3 실험과 첫 성공 사례
- 프로파일링 출력에서 같은 콜 경로가 반복되는 것(예:
immutable map copy가tensor merge메서드 내부에서 반복 사용됨)을 에이전트가 보고, 이것이 선형이 아니라 이차(quadratic) 알고리즘이라는 것을 코드베이스를 직접 보지 않고 콜스택만으로 식별했다 — 발표자가 "첫 번째 아하 모먼트"로 꼽은 지점. - 패턴을 식별한 뒤 실제 수정까지 가는 4단계:
- 해당 메서드가 정의된 코드 레포를 코드 서치로 찾기
- 현재 프로덕션에서 실행 중인 정확한 커밋을 추출 (어떤 빌드가 배포됐는지는 통상 쉽게 알 수 있음)
- 그 커밋 시점의 Git 저장소를 체크아웃해 해당 코드 경로를 정확히 찾고 내부 라이브러리 세부사항은 건너뜀
- 해당 메서드의 전체 콜 경로를 추적
- 이 4단계를, 스킬/프롬프트 형태의 충분한 지침만 주면 대규모 코드베이스에서도 5분 이내에 코드리뷰 제출까지 완료할 수 있었다. CPU와 레이턴시 절감 실측치도 산출했다(구체적 수치는 발표 슬라이드에서 시각적으로 제시, 트랜스크립트상 정확한 수치는 없음).
2.4 스케일업: 하나의 패턴에서 여러 서비스로
- 첫 사례는 단일 서비스의 단일 나쁜 구현을 고친 것이었다면, 두 번째 사례는 한 걸음 더 나갔다. Spectator 메트릭용 카운터 객체가 핫패스의 매 반복마다 새로 생성되는 안티패턴을 하나의 서비스에서 발견한 뒤, 에이전트가 크로스 레포 코드 서치로 같은 패턴이 재사용되는 곳을 능동적으로 찾아냈다.
- 결과: 동일한 안티패턴이 7개의 서로 다른 서비스에서 발견됐고, 전부 고치면 CPU 사이클 기준 0.5%~4.6% 절감이 가능한 것으로 나타났다.
2.5 개발 라이프사이클에 통합하기 — 장기 기억(카탈로그) 구축
- LLM은 컴팩트한 메모리는 있지만, 인간 성능 엔지니어가 디버깅하면서 쌓은 도메인 지식 같은 것은 갖고 있지 않다. 따라서 재사용 가능한 장기 기억을 도입해야 한다.
- 해법: 패턴/안티패턴을 담은 카탈로그. 상태를 가진(stateful) 카탈로그 + 무상태(stateless) LLM 에이전트를 합치면 플릿 전체(fleet-wide)가 공유하는 메모리가 완성된다.
- 이 카탈로그는 특정 팀·프로덕트에 종속되지 않고 중앙화되고 계속 자라나는 형태여야 한다. 예: O(n²) 패턴은 언어에 상관없이 일반화 가능하므로, 카탈로그도 언어·프레임워크를 넘나드는 청사진(blueprint)이 될 수 있다.
- 구현은 화려한 벡터 검색이나 벡터 DB가 아니라, 중앙화된 Git 저장소의 마크다운 파일로 시작하면 충분하다. 한 서비스가 프로파일링으로 패턴을 찾으면, 나중에 다른 서비스를 프로파일링하는 에이전트가 그 카탈로그를 참조해 같은 조사를 처음부터 반복하지 않아도 된다.
- 처음부터 완벽할 필요는 없다. 빈 카탈로그로 시작해도 되고, 참고할 만한 공개 소스도 많다: C++ 최적화에 대한 Jeff Dean의 블로그 포스트, PyTorch의
torchfix레포(커널·모델 그래프 최적화 안티패턴 카탈로그), 그리고 조직 자체의 성능 플레이북. - 카탈로그 엔트리 구성 요소: 향후 LLM이 카탈로그를 쉽게 조회할 수 있게 하는 심볼 목록, 어떤 서비스에서 확인됐는지, 신뢰도(confidence) 수준(여러 서비스에서 확인될수록 신뢰도가 올라가고, 신뢰도가 높을수록 에이전트가 더 확신을 갖고 사람에게 코드리뷰를 보낼 수 있음). 좌측엔 안티패턴, 우측엔 좋은 패턴을 함께 기록.
2.6 노이즈 관리: 사람에게 가기 전 3단계 검증
에이전트가 충분한 검증 없이 마구잡이로 코드리뷰를 보내면 신뢰를 잃는다. 그래서 사람의 주의를 요청하기 전 다음 단계를 거쳐야 한다.
- 단위/통합 테스트(기능적 정확성 검증): 최적화 코드 변경이 비즈니스 로직을 깨뜨리지 않는지 에이전트가 먼저 확인. 테스트 커버리지가 좋을수록 제안하는 변경이 옳다는 확신이 커진다.
- 카나리 배포: 기존 코드를 도는 머신과 신규(최적화) 코드를 도는 머신 두 대에 동일한 트래픽을 약 10분간 흘려보내 CPU 사용량 등을 비교. 관측 리포트에는 CPU 절감량, 레이턴시 절감량, 에러율 증가 여부가 포함되며, 에러율이 늘면 비즈니스 로직이 잘못됐다는 적신호로 판단해 진행을 멈춘다. (이 관측/카나리/검증 로직 자체는 AI 문제가 아니라 표준 인프라 문제라고 강조.)
- 엔지니어의 최종 승인: 프로덕션에서 정상 동작 중인 코드를 최적화 목적으로 수정하는 것은 리스크가 크므로(비즈니스 컨텍스트 부족, 테스트 커버리지 불충분 가능성), 마지막 가드레일로 사람의 승인이 반드시 필요하다고 강조 — 발표자는 이를 "의도적으로" 자동 프로덕션 반영을 하지 않는 이유로 명시.
멘탈모델: "프로파일러는 추정치를 주고, 카나리는 실측 근거를 준다. 최종 결정은 엔지니어가 한다."
2.7 사후대응에서 사전예방으로 — Shift-Left
지금까지 다룬 것은 "이미 프로덕션에 배포된 코드를 사후에 고치는" 리액티브 경로다. 이는 원래 위험한 작업(운영 중인 코드를 건드림)이므로, 이 경험을 초기 카탈로그를 만드는 용도로 쓰고 점점 더 왼쪽(사전예방)으로 이동해야 한다.
- 코드리뷰 단계 개입: 사람 또는 코딩 에이전트가 새 코드를 작성하면, 리뷰어 에이전트가 카탈로그를 조회해 "이 패턴은 카탈로그와 과거 프로파일링 데이터에 비춰볼 때 안티패턴으로 보인다"는 인라인 코멘트를 제공.
- 코드 작성 단계 개입 (가장 강력): 코드리뷰까지 기다릴 필요 없이, 코딩 에이전트가 새 토큰을 생성하기 전에 카탈로그를 참조해 처음부터 최적화된 코드를 쓰도록 한다. 다만 이는 코드 생성 속도를 늦추고 토큰 소비를 늘릴 수 있으므로, 카탈로그를 계층적으로 잘 색인화해 필요한 패턴만 빠르게 찾을 수 있게 구조화하는 것이 중요하다.
- 더 일찍 잡을수록 리뷰·프로덕션 반영의 불필요한 오버헤드를 건너뛸 수 있다.
주의할 점: AI 에이전트를 소프트웨어 개발 라이프사이클의 모든 단계에 상상하는 것은 쉽지만, 그것이 발표의 의도는 아니다. 테스트 커버리지·비즈니스 로직 인코딩·카나리 자동화 같은 기초 인프라가 견고해야 하고, 이 부분에는 AI가 필요 없다 — AI 에이전트는 그저 카나리를 어떻게 트리거하고 리포트를 어디서 받아 판단할지만 알면 된다. 패턴 카탈로그도 사람과 에이전트 모두가 읽고 쓸 수 있도록 의도적으로 Git 저장소(마크다운) 형태로 설계됐다.
2.8 자동화 수준(레벨)과 결론
- Level 1 (현재 규범): 수 시간을 들여 수동으로 문제를 찾음. LLM 없음.
- Level 2 (이 발표가 주로 다룬 수준, "오케스트레이션"): 프로파일러 트리거 → 데이터 다운로드 → LLM 분석 → 카나리 실행 → 수정안 제안까지 이어지는 고정되고 사전 정의된 워크플로에 LLM을 도구/통합 지점으로 붙인 것. 에이전트가 스스로 추론·계획하지는 않지만, 이 상태로도 매주 스케줄 실행을 걸어 지속적으로 새로운 문제를 찾아낼 수 있다.
- Level 3 (완전 자율): 워크플로가 고정돼 있지 않고 에이전트가 스스로 계획·추론·행동함. 다만 이 단계로 가려면 프롬프트 인젝션 등 보안 공격에 대한 평가/샌드박싱 투자를 훨씬 크게 해야 하며, 현재 일반적인 에이전트 인프라가 이를 항상 해결하지는 못한다.
권고: Level 1에서 시작해 Level 2로 옮겨가면 최대 이득을 얻을 수 있고, 필요하면 그다음 단계로 나아가라.
3. 인용/사례
- "The problem is arising from the fact is that you are authoring code now at a 10x faster speed... the compute cost also is increasing at a similar pace because it doesn't always write the fastest code." — 와이드 코딩 시대의 핵심 문제 제기.
- "Your agent doesn't know specific details about your platforms and your frameworks and your internal code base patterns." — 코딩 에이전트가 비효율 코드를 양산하는 근본 원인.
- O(n²) 사례:
immutable map copy가tensor merge메서드 내부에서 반복 호출되는 콜스택 패턴을 코드베이스를 보지 않고 프로파일링 데이터만으로 식별 → CPU 시간의 8.8%를 소모하고 있었음. 4단계(코드서치 → 커밋 특정 → 체크아웃 → 콜패스 추적)를 거쳐 5분 이내 코드리뷰까지 완성. - Spectator 카운터 객체 사례: 핫패스 반복마다 카운터 객체가 새로 생성되는 안티패턴을 크로스 레포 검색으로 확장해 7개 서비스에서 동일 패턴 발견, 수정 시 CPU 0.5~4.6% 절감 가능.
- "Profiler gives the estimate, canary gives ground truth. An engineer makes the eventual decision." — 검증 파이프라인의 멘탈모델.
- 카탈로그 참고 공개 소스: Jeff Dean의 C++ 최적화 블로그 포스트, PyTorch
torchfix레포. - 발표자 개인 사이트에 상세 블로그 포스트 예고: shaharrajat.com (발표 중 언급, 정확한 스펠링은 트랜스크립트 음성 인식 한계로 다를 수 있음).
4. 시사점
- 프로파일링 데이터는 LLM에게 "코드베이스보다 먼저" 줄 수 있는 고효율 입력이다. 콜스택 구조가 언어에 무관하게 표준화돼 있다는 점을 활용하면, 코드 전체를 이해시키지 않고도 병목 후보를 빠르게 좁힐 수 있다 — 데이터 엔지니어링/백엔드 조직이라면 자사 프로파일러 출력 포맷을 LLM 친화적으로 구조화하는 것부터 검토할 만하다. </br>
- "카탈로그 = 마크다운 Git 저장소"라는 선택은 의도적으로 단순하다. 벡터DB나 임베딩 검색 없이도, 사람과 에이전트가 함께 읽고 쓸 수 있는 텍스트 저장소만으로 조직 전체의 장기 기억을 만들 수 있다는 점은 다른 도메인(예: 온보딩 지식, 인시던트 포스트모템)에도 적용 가능한 패턴이다.
- AI 도입의 순서가 명확하다: 사후대응 → 코드리뷰 개입 → 코드 작성 개입. 리스크가 낮은 지점(이미 실패한 코드를 사후에 고침)에서 시작해 카탈로그를 채우고, 신뢰도가 쌓인 뒤에야 더 이른 단계(코드 작성 시점)로 개입 범위를 넓히는 전략은 프로덕션에 영향을 주는 다른 AI 자동화 과제에도 일반화할 수 있는 리스크 관리 원칙이다.
- 자동화(에이전시) 수준과 조직의 투자 수준을 분리해서 생각해야 한다. Level 2(고정 워크플로 + LLM 도구 호출)만으로도 상당한 가치를 얻을 수 있으며, Level 3(완전 자율 에이전트)로 가는 것은 보안·샌드박싱 투자가 선행되지 않으면 오히려 리스크가 더 크다는 경고는, "에이전트를 더 자율적으로 만드는 것"이 항상 다음 목표가 되어서는 안 된다는 점을 시사한다.
- 사람의 최종 승인을 "의도적으로" 남겨둔 설계 철학은 주목할 만하다. 이는 기술적 한계 때문이 아니라, 프로덕션에서 정상 작동 중인 코드를 건드리는 리스크의 비대칭성(잘 되면 소소한 절감, 잘못되면 장애) 때문이라는 점을 명시적으로 밝힌다. 성능 최적화뿐 아니라 다른 자동화된 코드 수정 파이프라인 설계 시에도 참고할 만한 원칙이다.
