PR 병목 해소하기: Matt Pocock, AIHero

Matt Pocock이 자동 검사, 자동 리뷰, 사람의 리뷰를 조합해 AI가 만드는 PR의 품질과 검토 속도를 높이는 방법을 설명한다. 구현과 리뷰의 역할을 분리하고, 변경의 가역성과 영향 범위에 맞춰 검토하며, 회고로 작업 환경을 개선하는 과정을 다룬다.

PR 병목 해소하기: Matt Pocock, AIHero

에이전트가 작업을 시작하는 소프트웨어 팩토리

Matt Pocock은 검토받지 못한 PR이 쌓이는 문제는 AI 이전에도 대부분의 조직이 겪었으며, AI 때문에 그 부담이 훨씬 커졌다고 설명한다. AI의 핵심 약속은 적은 자원으로 더 많은 일을 하는 것이다. 에이전트가 사람의 작업 능력을 확장하면서 코드와 PR의 생산량도 함께 늘어난다.

그가 말하는 소프트웨어 팩토리에서는 사람이 모든 작업을 시작하지 않는다. 일부 작업의 시작을 에이전트와 자동화에 넘긴다. 원문에서 Jeff라고 부르는 분류기가 들어온 내용을 수정 작업이나 문제 재현으로 전환할 수도 있고, 담당자에게 곧바로 알릴 수도 있다. PlanetScale에서 데이터베이스의 느린 쿼리 보고서를 받아 팩토리의 다른 작업을 시작하는 방식도 가능하다. 이런 경우에는 사람이 아니라 결정론적으로 동작하는 코드가 작업을 촉발한다. 자동으로 시작되는 작업이 많아지면 팩토리에서 코드를 처리하는 속도도 빨라지지만, 처리 속도를 높이는 것만으로는 충분하지 않다.

원문 영상 · 0:01

품질을 높이는 세 단계의 제동 장치

계속 코드를 생산하기만 하면 사람이 열어보거나 검토하기조차 어려운 저품질 PR이 쌓일 수 있다. Pocock은 이를 막는 장치가 코드의 품질을 높여야 한다고 말한다. 코드베이스는 에이전트가 작업하는 환경이므로, 나쁜 코드가 쌓이면 그 환경을 참고하는 에이전트가 다시 나쁜 코드를 만들기 쉽다. 이런 악순환을 막는 제동 장치가 오히려 전체 작업 속도를 높인다는 것이 발표의 관점이다.

첫 단계는 자동 검사다. 린트, 테스트, 타입 검사, 코드 품질 지표처럼 매번 같은 방식으로 실행되는 결정론적 검사가 여기에 속한다. 그 위에는 에이전트가 수행하는 자동 리뷰가 있다. 자동 리뷰는 테스트가 놓친 문제를 찾거나 코드베이스의 구조를 살펴본다. 마지막 단계에서는 사람이 PR을 읽고 검토한다.

세 단계를 함께 운영하는 목적은 사람이 검토하는 시간을 줄이는 것이다. 생산 속도가 높아질수록 PR 수가 늘어나므로 앞의 두 단계가 더 많은 품질 문제를 처리해야 한다. 사람이 받는 결과물의 품질이 높아지면 개입해야 할 부분도 줄어든다.

원문 영상 · 2:21

코드가 자동 검사를 통과해도 놓칠 수 있는 문제

Pocock은 자동 검사가 저렴하다는 점을 강조한다. 자동 리뷰처럼 모델 토큰을 소비하거나 사람의 시간을 쓰는 대신 주로 CPU 연산을 사용하므로, 코드가 바뀔 때마다 테스트를 실행할 수 있다. 물론 테스트가 에이전트의 버그를 발견하면 그 버그를 수정하는 데 토큰이 필요하다. 그는 그런 토큰 지출은 가치가 있다고 본다. 따라서 저장소에 여러 검사를 겹쳐 적용할 수 있으며, 많은 팀이 검사를 충분히 활용하지 않거나 검사 방법을 충분히 다양하게 생각하지 못한다고 평가한다.

하지만 CI가 초록색이라는 사실만으로 코드가 머지할 준비를 마쳤다고 볼 수는 없다. 자동 검사가 실제 문제를 놓치고도 안전하다는 인상을 줄 수 있기 때문이다. 자동 리뷰와 사람의 리뷰는 자동 검사가 놓친 문제를 찾아내는 추가 장치다.

첫 사례는 구현을 그대로 다시 확인하는 동어반복 테스트다. Pocock은 자신이 사용한 에이전트, 특히 원문에서 ‘Opus 5’라고 부르는 모델이 이런 테스트를 자주 작성했다고 말한다. X 게시물의 글자 수 제한을 280으로 정의해 놓고, 테스트에서 다시 그 제한 상수가 280인지 확인하는 식이다. 이는 실제 기능을 검증하기보다 구현 내용을 반복한다. 상수의 값이나 이름을 바꾸기만 해도 테스트를 함께 고쳐야 하므로 내부 구조에 지나치게 민감하다.

fixing-pr-bottleneck-matt-pocock-05-51
X 게시물의 280자 제한을 구현 그대로 다시 확인하는 동어반복 테스트 (5:51)

두 번째 사례는 화면의 요소 순서를 소스 파일의 문자열 순서로 검사하는 테스트다. 피치 상세 페이지에서 동영상 섹션이 콘텐츠 계획 뒤에 나타나는지 확인하려고, 실제 화면을 렌더링하지 않고 모듈 파일을 읽는다. 파일 안에서 콘텐츠 계획과 동영상에 해당하는 문자열을 찾아, 동영상 문자열의 위치가 더 뒤인지 비교한다. 이 방식은 사용자에게 보이는 화면 순서 대신 소스의 배치를 검증한다. 화면 동작을 유지하면서 소스만 재구성해도 실패하므로 코드 구조에 너무 강하게 결합되어 있다.

fixing-pr-bottleneck-matt-pocock-06-41
화면 렌더링 없이 소스 파일에서 콘텐츠 계획과 동영상 문자열의 위치를 비교하는 테스트 (6:41)

원문 영상 · 4:12

실패를 가리는 모킹과 깊은 모듈

자동 검사가 놓치는 또 다른 유형은 특정 오류 상황에서 아예 실패할 수 없는 테스트다. use audio boost 함수는 내부에서 DOM의 AudioContext API를 사용한다. 이 API에는 복잡한 오류 조건이 있으며, API가 특수한 상황에서 실패할 수 있다. 그런데 테스트가 실제 API를 가짜 메서드로 대체하면 그 오류 조건을 재현할 수 없다. 테스트는 통과하지만 운영 환경에서 예상하지 못한 오류를 만나게 된다.

fixing-pr-bottleneck-matt-pocock-07-28
AudioContext API를 가짜 메서드로 대체해 실제 오류 조건을 가리는 테스트 (7:28)

Pocock은 에이전트가 일부러 나쁜 테스트를 만드는 것은 아니라고 설명한다. 주어진 지시를 선의로 수행하더라도 실제 코드를 실행하는 대신 구현 구조에 묶인 검사를 작성할 수 있다. 따라서 자동 검사를 형식적으로 통과하기 어렵게 만들어 검사의 품질과 전체 품질 기준을 높여야 한다.

그가 제시하는 첫 방법은 코드베이스 설계다. John Ousterhout의 《A Philosophy of Software Design》에서 설명하는 깊은 모듈은 단순한 인터페이스 뒤에 복잡한 동작을 감춘다. 발표에서 제시한 모듈 A는 작은 인터페이스 아래에 큰 구현을 둔다. 반대로 모듈 B는 인터페이스가 크고 호출할 함수도 많지만 각각의 함수가 하는 일은 작다.

깊은 모듈은 내부 구현을 더 많이 감추므로 테스트가 내부 구조에 종속될 가능성을 줄인다. 에이전트가 내부의 세부 구현을 직접 검사하기보다, 작은 공개 인터페이스를 통해 동작을 검증하도록 유도하는 것이 사람의 역할이다. Pocock은 이런 인터페이스에서 테스트할 때 더 좋은 테스트를 얻을 수 있다고 본다.

원문 영상 · 7:11

모듈을 개선하는 공통 언어와 구현 에이전트의 부담

Pocock이 소개하는 코드베이스 설계 스킬은 상태가 좋지 않은 바이브 코딩 코드베이스에서도 모듈을 깊게 만들 기회를 찾는다. 스킬은 개선 후보들을 HTML 문서로 보여주고, 각 후보의 변경 전후를 비교한다. 중복을 줄이고 깊고 테스트하기 쉬운 모듈을 만드는 제안을 확인한 뒤 구현할 수 있다.

fixing-pr-bottleneck-matt-pocock-09-53
코드베이스 설계 스킬이 만든 HTML 문서: 모듈 개선 후보와 변경 전후 (9:53)

그는 코드 구조를 설명하는 접근법이 여러 가지인데 그 접근법들을 모두 DDD 같은 이름으로 부르기도 하므로, 팀에서 일관되게 쓸 언어가 필요하다고 말한다. 자신의 스킬은 locality, leverage, seam 같은 용어를 정의한다. Locality는 관련 코드가 얼마나 함께 배치되어 있는지, 작은 변경이 다른 부분에 얼마나 영향을 미치는지와 관련된다. Leverage는 깊은 모듈이 제공하는 가치다. 호출하는 쪽이 단순한 함수 하나를 사용하면서 많은 기능을 얻는다. 그는 이런 특성이 코드베이스뿐 아니라 그 안에서 일하는 에이전트에도 도움이 된다고 본다. Seam이라는 용어도 소개하지만 이 발표에서는 별도의 정의를 설명하지 않는다.

그렇다면 에이전트가 깊은 모듈을 만들고 좋은 테스트를 작성하며, 동어반복 테스트와 구조에 민감한 테스트를 피하도록 어떻게 보장할 수 있을까. Pocock의 첫 조언은 구현 에이전트의 지침에 코딩 표준까지 넣지 말라는 것이다.

구현 에이전트는 하나의 컨텍스트 창 안에서 변경할 코드를 탐색하고, 파일을 수정하고, 자동 검사를 실행해 문제를 디버깅해야 한다. 이 작업만으로도 이미 많은 역할을 맡는다. 여기에 코딩 표준을 모두 지키라는 요구까지 더하면 성능이 나빠진다는 것이 그의 경험이다. 그는 구현 작업을 이미 과부하 상태인 단계로 보고, 표준을 적용할 책임을 다른 단계에 배치한다.

원문 영상 · 9:34

독립된 검토 에이전트가 표준을 적용하고 수정하기

Pocock의 코드 리뷰 스킬은 diff를 받고, 저장소 안에서 팀이 작성하고 조정할 수 있는 코딩 표준 파일을 읽은 뒤 변경 내용이 그 표준을 따르는지 확인한다. 이 리뷰는 별도 서브에이전트에서 실행되므로 독립된 컨텍스트 창과 작업 예산을 갖는다.

리뷰 에이전트도 변경의 넓은 맥락을 이해하기 위해 코드를 탐색해야 한다. 다만 diff 덕분에 검토할 위치를 이미 알고 있으며, 구현이나 디버깅을 처음부터 맡을 필요는 없다. Pocock은 구현 단계와 달리 리뷰 단계에는 역할을 추가할 여유가 있으므로, 코딩 표준의 적용을 이 단계에 집중하면 더 잘 적용할 수 있다고 설명한다.

그는 좋은 코드를 한 번에 얻으려는 기대 대신 코드를 완성하는 과정을 두 단계로 나누어 생각한다. 구현 단계에서 코드를 동작하게 만든 뒤, 리뷰 단계에서 코딩 표준을 적용해 품질을 개선한다. 이는 red-green-refactor와도 연결된다. 하나의 컨텍스트 창에서 red-green을 수행하고, 다른 컨텍스트 창에서 리팩터링한다. 이런 분리는 자신의 작업에서 성공적이었다고 말한다.

코딩 표준을 전역 지침이나 agents.md에 모두 넣으면 구현 에이전트에 과도한 부담을 줄 수 있고, 에이전트가 표준을 읽거나 적용할지도 확실하지 않다. 그는 coding standards.md 같은 별도 파일에 표준을 두어 코드 리뷰 에이전트만 읽게 한다.

자동 리뷰를 Cursor Bugbot이나 CodeRabbit 같은 외부 서비스에 맡기는 사람들도 있다. Pocock은 자신도 버그와 보안 문제를 포괄적으로 찾는 범용 리뷰 스킬을 만들려 했지만 어려웠다고 회고한다. 너무 일반적인 지침은 해당 팀에 맞지 않는 오탐을 만든다. 반대로 TypeScript 문제만 구체적으로 찾도록 만들면 Rust 사용자에게는 쓸모가 없다. 그래서 그는 팀의 자동 리뷰를 직접 만들고, 코딩 표준을 점진적으로 축적해 팀 전체에 공유하라고 권한다. 아무도 읽지 않는 기존 표준 문서가 있다면 그 내용을 리뷰 에이전트가 활용할 문서에 포함할 수 있다.

리뷰 에이전트가 PR에 긴 댓글만 남기는 방식도 사람의 작업을 늘린다. 사람은 각 제안의 의미를 읽고 어떤 수정을 적용할지 다시 판단해야 한다. Pocock은 리뷰 에이전트가 발견한 문제를 직접 수정하고 커밋하는 것을 기본값으로 삼아야 한다고 주장한다. 판단에 의문이 남는 부분은 댓글로 물을 수 있지만, 명확한 수정은 완료한 뒤 사람에게 더 좋은 결과물을 넘긴다. 구현 에이전트 하나를 완벽하게 만드는 데 모든 역할을 몰아주지 말라는 권고다.

원문 영상 · 12:34

되돌릴 수 있는 변경과 머지 위험도

자동 검사와 자동 리뷰를 거친 PR을 사람이 가장 효율적으로 읽으려면 PR 자체도 사람이 이해하기 쉬워야 한다. Pocock은 당시 만들고 있던 PR 스킬에서 여러 사람이 제안한 좋은 아이디어를 모으고 있다고 설명한다. 그 스킬의 첫 원칙은 모든 리뷰가 똑같이 중요하거나 필수인 것은 아니라는 점이다. 중요한 리뷰에 사람의 에너지를 집중해야 한다.

그는 AWS의 용어를 빌려 변경을 one-way door와 two-way door로 구분한다. 대부분의 PR은 머지한 뒤 쉽게 되돌릴 수 있는 two-way door에 해당한다. 이처럼 변경을 쉽게 되돌릴 수 있다는 점은 문제가 생기면 다리가 무너지는 토목 공사 같은 one-way door와 구별되는 소프트웨어의 장점이다.

그러나 변경이 작다고 해서 항상 되돌릴 수 있는 것은 아니다. 단순한 수정으로도 6만 명에게 이메일이 발송될 수 있다. 이미 발송된 이메일을 회수할 수 없으므로 이런 변경은 one-way door이며 주의 깊게 검토해야 한다. 비용이 큰 마이그레이션이나 데이터 손실을 수반하는 변경도 마찬가지다.

되돌릴 수 있는지뿐 아니라 영향 범위도 알아야 한다. 무엇이 잘못될 수 있고, 문제가 생기면 얼마나 심각한지 평가한다. Pocock은 PR 아래쪽에 merge danger라는 짧은 요약을 둔다. 쉽게 되돌릴 수 있고 영향도 국소적인 변경이라면 검토에 많은 시간을 쓰지 않아도 된다는 판단을 빠르게 할 수 있다.

다음으로 필요한 것은 무엇이 왜 바뀌는지 이해하기 쉬운 설명이다. 그는 여러 방식을 시도한 뒤 의사 코드가 도움이 된다고 보았다. 또 Dex Hadley의 HumanLayer 스킬 저장소에 있는 show me 스킬에서 영향을 받았다. 이 스킬은 많은 텍스트 대신 이미지와 다이어그램을 사용해 변경 내용과 이유를 쉽게 파악하게 한다.

원문 영상 · 16:19

PR을 시각화하고 코드를 만드는 과정까지 검토하기

PR에서 변경한 코드의 동작 순서는 Mermaid나 UML로 보여줄 수 있다. 더 단순한 그림도 유용하다. 발표에서는 CLI에 새 명령 하나와 플래그 두 개가 추가된 것을 짧은 그림으로 보여준다. Pocock은 이런 설명이 사람이 무엇이 바뀌었는지 이해하는 데 큰 도움이 되며, 변경 이유를 가능한 한 빨리 이해하게 하는 것이 목표라고 말한다.

fixing-pr-bottleneck-matt-pocock-19-12
Author, lesson-move-planner, sections.title 사이의 PR 변경 흐름 시퀀스 다이어그램 (19:12)

사람이 검토할 세 번째 대상은 코드가 만들어지는 과정이다. 팀은 같은 스킬 파일과 에이전트 지침 파일을 함께 사용하며 에이전트가 일할 환경을 구성한다. Pocock은 이 과정이 코드 자체만큼 중요하다고 본다. 사람이 PR을 검토할 때는 결과 코드와 함께 그 코드를 만든 시스템도 검토해야 한다.

그의 원칙은 같은 리뷰 댓글을 두 번 쓰지 않는 것이다. 서로 다른 PR에서 에이전트가 같은 문제를 반복하도록 두지 않으려면, 이번 검토에서 발견한 사항이 다음 작업의 방식을 바꿔야 한다.

원문 영상 · 19:12

회고로 검사와 지침을 계속 개선하기

retro 스킬은 retrospective, 즉 회고를 수행한다. 하나의 에이전트 세션을 입력으로 받을 수도 있고, PR과 그 세션을 함께 살펴볼 수도 있다. 지난 일주일 동안의 모든 PR과 리뷰를 모아 회고하는 방식도 가능하다. 그 결과로 다음 작업을 개선할 자동 검사와 코딩 표준을 제안한다. Pocock은 이렇게 사람이 수행한 리뷰가 다음 리뷰의 품질을 높이고 미래의 검토 부담을 줄이는 누적 효과를 만든다고 설명한다.

회고는 자동 검사와 coding standards.md의 변경만 제안하지 않는다. 에이전트가 필요한 정보를 쉽게 찾았는지 확인하고, 다음에는 agents.md 안에 탐색 경로를 안내하는 포인터를 둘지 검토한다. 사용한 도구를 더 적은 토큰으로 활용할 방법도 찾는다. 이런 도구 사용의 비효율은 세션 바깥에서 원인을 파악하기 어려운 경우가 많다. 분량이 지나치게 늘어난 지침 파일이나 스킬이 나쁜 결과에 영향을 주었는지도 살펴보고 더 정돈할 방법을 제안한다.

자동 검사와 자동 리뷰를 여러 겹으로 적용하고, 사람이 받는 PR을 이해하기 쉽게 만들면 사람의 검토를 더 빠르고 간단하게 운영할 수 있다는 것이 Pocock의 목표다. 그는 쉽게 되돌릴 수 있는 변경을 모두 사람이 직접 검토할 필요는 없다고 주장한다. 반면 되돌릴 수 없는 변경은 하나도 빠짐없이 검토해야 한다.

원문 영상 · 20:36