본문으로 건너뛰기
█ █  ▄▀█  ▀█  ▀█  ▀█  █
█▀█  █▀█  █▄  █▄  █▄  █
⚡ no css · no framework · no problem ⚡

검증할 수 없는 코드량은 생산성이 아니라 재고다

· AI 시대에 개발의 병목은 코드 작성에서 검증으로 이동했다

🇺🇸 English


TL;DR "바이브코딩 이후 PR은 300줄 이하에서 500줄, 1천 줄, 때로는 1만 줄까지 커졌습니다. AI 리뷰와 하네스는 검사량을 늘렸지만 사람이 이해하고 독립적으로 검증할 수 있는 변경량까지 늘려주지는 않았습니다. 생성된 코드가 아니라 검증되고 소유 가능한 변경량을 생산성으로 봐야 한다고 생각합니다."

AI를 통해 제품 개발 속도가 빨라졌습니다. 그만큼 기술 부채도 많아졌고요.

올해 초부터 대부분의 코딩을 바이브코딩으로 진행하고 있습니다. 요구사항과 의도를 적어주면 에이전트가 구현과 테스트를 진행하고 다른 에이전트가 리뷰합니다. 예전보다 기능이 나가는 속도는 체감할 만큼 빨라졌습니다.

문제는 코드를 만드는 속도만 빨라진 게 아니었다는 점입니다.

병목의 이동

제가 직접 개발할 때는 1 commit ≈ 1 PR에 가깝게 작업했습니다. 기능을 작게 나누고 PR을 자주 올렸고 가능하면 changed lines가 300줄을 넘지 않게 했습니다.

300줄 이하의 변경은 리뷰하는 사람이 한 번에 변경의 의도와 흐름을 따라갈 수 있다고 생각했습니다. 그렇다고 300줄이 넘어가면 무조건 나쁘다는 뜻도 아니고 299줄이면 안전하다는 뜻은 아닙니다. 그냥 제가 이해할 수 있는 범위 안에 변경을 두기 위한 기준이었습니다.

팀을 옮기고 바이브코딩을 주로 하게 되면서 이 크기가 500줄, 1천 줄을 넘기기 시작했습니다. 어느 순간에는 1만 줄이 넘는 diff도 생겼습니다. 초반에는 대강이라도 읽으면서 리뷰해보려고 했는데 봐야 하는 줄 수가 늘수록 인지 부하도 같이 늘었습니다. 그러다 보니 나중에는 안 보고 CI만 통과하면 넘기게 되더라고요.

에이전트가 코드를 생성하는 처리량은 커졌는데 제가 읽고 이해하는 처리량은 그대로였습니다. 병목이 코드 작성에서 검증으로 옮겨간 셈입니다.

그런데 제가 검토할 수 있는 양보다 더 많이 만들어진 코드는 부채라기보다 아직 처리하지 못한 재고에 가까웠습니다. 이걸 그대로 생산성이라고 불러도 되나 싶습니다.

생성됨과 완료됨

한참 지나 코드 파일을 열어 본 적이 있습니다. 테스트와 린트, 에이전트 규칙을 묶어둔 하네스가 있었는데도 땜빵식 수정이 계속 붙어 있었고 한 컴포넌트가 받는 props는 20개를 넘었습니다. 그래도 배포 후 기능은 잘 동작했고 하네스도 문제없이 통과했습니다.

하지만 실제 제품에서는 happy path에서만 동작하고 다른 경로에서는 됐다 안 됐다 하는 문제가 있었습니다. 제품을 쓰다가 "여기에 이 화면이 뜨는 게 맞아요?"라고 물었는데 "아니요, 제 의도랑 달라요"라는 답을 받은 적도 있습니다. 기존 코드를 바꾸며 생긴 문제를 내부에서는 모르고 있다가 CS로 처음 알게 된 일도 있었습니다.

기능이 잘 동작해도 제품이 의도대로 동작한다고 볼 수는 없었습니다. 하네스를 통과했더라도 실제 사용 경로에서 어떻게 동작하는지까지 알 수는 없었습니다. 나중에 고칠 수 있을 만큼 제가 이 코드를 이해하고 있는지도 어느샌가 잘 모르겠더라고요.

타입 체크, 린트, 테스트와 AI 리뷰는 코드 안에서 찾을 수 있는 문제를 걸러줍니다. 실제 제품의 다른 경로와 데이터까지 확인해야 제가 의도한 동작인지 알 수 있습니다. 문제가 생겼을 때 왜 이렇게 만들었는지 설명하고 되돌릴 수 있어야 이후에도 고칠 수 있습니다.

그전에는 테스트를 포함한 verify CI를 통과했고 배포까지 됐으니 필요한 검증도 다 끝났다고 은연중에 생각했던 것 같습니다.

AI가 AI를 리뷰하는 일

요즘에는 AI가 작성한 코드를 AI가 리뷰합니다. 이게 아무 의미도 없다고 생각하지는 않습니다. 놓친 null 처리나 테스트, 놓치고 수정하지 못한 소비처를 찾아낼 때가 있고 사람이 전부 읽기 전에 의심할 지점을 좁혀주는 데도 쓸 수 있습니다.

다만 리뷰 결과만 보고 있으면 AI가 어떤 컨텍스트를 실제로 알고 판단한 건지 아니면 그럴싸하게 아는 척한 건지 구분하기 어렵습니다. 작성 에이전트와 리뷰 에이전트가 같은 diff와 같은 저장소를 읽었다면 검토 횟수는 늘어도 증거의 종류는 그대로일 수 있습니다.

GeekNews에 소개된 인간 중심에서 에이전틱 코드 리뷰로 - 더 빠른 결정이 더 나은 리뷰를 뜻하지는 않는다는 207개 오픈소스 프로젝트의 리뷰 완료 PR 102만 건을 분석했습니다. AI 에이전트가 참여한 일부 흐름에서는 리뷰 결정 시간이 줄었지만 속도와 품질 모두에서 사람만 참여한 리뷰보다 일관되게 나은 방식은 없었습니다. 관찰 연구이고 품질도 실제 장애가 아닌 대리 지표로 측정했기 때문에 AI 리뷰가 나쁘다는 결론은 아닙니다. 적어도 리뷰가 빨라졌다는 사실만으로 코드 품질까지 좋아졌다고 말할 수는 없었습니다.

AI-to-AI Code Reviews of GitHub Pull Requests는 AI가 작성한 PR 중 248,641개가 하나 이상의 AI 리뷰를 받은 현상을 확인했습니다. 논문에서 닫힌 흐름이라고 부른 건 AI가 작성과 리뷰 양쪽에 참여했다는 뜻이지 사람의 리뷰가 전혀 없었다는 뜻은 아닙니다. 식별된 AI 작성 PR의 8.8%였습니다. 절대 건수로는 이미 상당했지만 이 연구는 리뷰의 정확성이나 최종 코드 품질을 평가하지 않았습니다. 많이 쓰였다고 해서 리뷰가 유효하다고 볼 수는 없었습니다.

AI 리뷰는 코드 안에서 결함을 찾는 도구로서 유용합니다. 실제 제품과 데이터에서 의도대로 동작하는지까지 자동으로 확인해주지는 않습니다. 하네스도 이미 알고 있는 실패를 막는 데는 강하지만 아직 모르는 경로나 잘못 정의한 문제까지 알아서 찾아주지는 않았습니다.

맥락과 소유

맹구run 개발기에서는 앱을 처음부터 끝까지 만들면서 코드를 한 줄도 보지 않았다고 썼습니다. 당시에는 167개의 작은 커밋이 쌓였고 prd.json을 55번 수정했습니다.

그 글을 성공담이라고 생각하지는 않습니다. 그때 얻은 레슨은 다른 세션에서도 작업이 이어지게 prd.json을 잘 작성하고 중간에 컨텍스트를 잃어도 괜찮은 상태를 만들어두자는 것이었습니다. AI와 일하는 방법을 처음 배운 개발기에 가까웠습니다.

모델이 더 좋아지고 한 번에 다룰 수 있는 컨텍스트도 커진 지금, 당시 방식이 여전히 같은 정도로 유효하다고 보지는 않습니다. 모델이 더 많은 맥락을 다루는 것과 제가 제품의 의도를 이해하는 것은 별개의 문제라는 것도 알게 됐습니다. prd.json은 세션 사이의 맥락을 이어줄 수 있었지만 코드 생성량이 사람의 검증량을 넘는 문제까지 해결하지는 못합니다.

결국 당시 맹구run에서 풀었던 건 세션 간 연결 문제였고 지금 겪는 건 생성량과 검증량의 차이였습니다.

300줄은 답이 아니다

그러면 다시 모든 PR을 300줄 아래로 쪼개면 되나 싶었습니다. 그것도 잘 모르겠습니다.

이미 나가야 할 작업이 있는데 diff가 크다는 이유로 멈추는 게 맞을까요. 그렇다고 에이전트에게 300줄 이하의 stacked PR로 작업하라고 하면 의미 있는 범위로 나눌지 아니면 300줄을 맞추기 위해 코드를 어거지로 쪼갤지도 확신이 없습니다. GitHub도 1,721줄짜리 AI 생성 PR을 작은 stacked PR로 나누는 방법을 소개했지만 작은 PR이라는 형식만으로 변경의 의미가 작아지는 것은 아닙니다.

사람이 설명할 수 없는 코드를 버리는 것도 현실적이지 않습니다. 버린 뒤에는 결국 누군가 다시 작성해야 하는데, 제가 손으로 작성해서 에이전트의 생성량을 따라가기도 어렵습니다. 이미 AI로 개발하는 방식에 들어온 이상 예전으로 그대로 돌아가기도 어렵습니다.

돌아보면 제가 지키려 했던 300줄은 정답이 아니라 변경을 놓치지 않으려고 정해둔 대략적인 선이었습니다. 한 번의 변경에서 의도와 영향부터 확인 방법까지 따라가기 위한 숫자였습니다. 이제는 줄 수보다 한 번의 변경을 처음부터 끝까지 따라가며 내 의도와 맞는지 확인해야 할 것 같습니다. 방법은 잘 모르겠지만요.

AI 생성 PR 33,707개의 리뷰 부담을 분석한 연구에서는 패치 크기, 수정한 파일 수, 설정 파일 변경 같은 정적 신호가 PR 설명보다 리뷰 부담이 큰 PR을 더 잘 가려냈습니다. 이 결과는 작업을 어떻게 나눠야 하는지가 아니라 검토 비용이 커질 변경을 일찍 알아볼 수 있다는 이야기였습니다. 변경을 어느 단위로 나눌지는 아직 답을 못 찾았습니다.

검증되지 않은 재고

아직 운영 방법에 대한 답은 없습니다. 생성을 멈추거나 이미 만든 코드를 전부 다시 쓰기는 어렵습니다. 줄 수만 제한하는 것으로도 충분하지 않습니다.

테스트와 CI 통과는 자동 검사가 끝났다는 뜻입니다. 제가 그 변경을 이해했고 실제 제품의 다른 경로까지 확인했다는 뜻은 아닙니다.

다음 1만 줄짜리 diff에도 자동 검사의 초록색 체크가 붙을 겁니다. 이제는 그 체크를 완료의 표시로 바로 읽지 않는 데서 시작해보려고 합니다.


댓글 0개

아직 댓글이 없어요.

GitHub에서 댓글 남기기 · GitHub 계정으로 로그인 후 이슈에 코멘트를 남기면 여기에 표시돼요.