AI가 작성한 코드를 어디까지 믿을 수 있을까?
전 직장에서 약 8,000줄이 변경되는 PR을 본 적이 있다. AI가 작성한 코드였고, AI끼리의 리뷰를 거친 뒤 사람의 리뷰 없이 병합됐다.
당시 나는 에이전트에게 작업을 나눠서 진행하고, PR도 500줄 정도의 단위로 쪼개도록 요청하고 있었다. 사람이 코드를 이해하고 검토하려면 변경 범위가 작아야 한다고 생각했기 때문이다. 그런 상황에서 동료가 훨씬 큰 변경을 한 번에 병합하는 모습을 보고 꽤 놀랐다.
그 변경은 이후 개발 환경의 테스트에서 성능 문제가 발견되어 다시 수정됐다. 다만 나는 운영 환경에서도 잘 동작했는지까지는 확인하지 못했다. 그래서 이 경험만으로 그 작업 방식 전체가 잘못됐다고 평가할 수는 없다. 그래도 의문은 남았다.
AI가 코드를 작성하고 리뷰까지 하는 상황에서도 PR을 작게 나누는 것이 중요할까? 사람의 리뷰 없이 병합해도 된다고 판단하려면 무엇이 준비되어 있어야 할까?
그러던 중 Meta의 React 팀에서 React Compiler 개발에 참여했고, 이후 Cursor에서 에이전트 창의 성능 개선을 맡았던 Lauren Tan과 Matt Pocock의 대담을 보게 됐다. Lauren은 한 달 동안 약 2,500개의 PR을 프로덕션에 반영했다고 설명했다. 한 달을 30일로 잡으면 하루 평균 약 83개다.
물론 이 숫자만으로 PR마다 얼마나 많은 코드가 변경됐는지는 알 수 없다. 그녀도 2,500개의 PR이 새로운 기능 2,500개를 의미하는 것은 아니며, 코드 정리와 유지보수 작업도 많이 포함돼 있다고 설명한다.
그래서 PR의 크기에 대한 답을 숫자에서 찾기보다, 그녀가 어떻게 에이전트에게 병합까지 맡길 수 있게 됐는지를 살펴보기로 했다.
사람이 계속 중간에 있어야 한다면
Lauren도 처음부터 에이전트를 온전히 신뢰했던 것은 아니었다.
초기에는 하나의 에이전트를 세세하게 관리하는 데 많은 시간을 썼다고 한다. Cursor의 에이전트 창 성능을 개선할 때도 직접 플레임 그래프와 힙 스냅샷을 살펴보고, 알아낸 내용을 에이전트에게 전달했다.
AI가 코드를 작성하더라도 결과를 관찰하고 설명하는 일은 계속 사람이 하고 있었던 것이다. 그녀는 이때 자신이 에이전트와 Chrome DevTools 사이에서 중계 역할을 하고 있었다고 이야기한다.
나도 비슷한 경험이 있다. AI가 구현했다고 말해도 그대로 믿기는 어려워서 테스트를 실행하거나 직접 동작을 확인했다. 브라우저를 활용한 검증을 맡기기도 하고, 마지막에 반드시 검증하라는 프롬프트를 남기기도 했지만, 결국 다시 수동으로 확인하는 경우가 있었다.
이 방식에서는 구현 속도가 빨라져도 내가 확인할 수 있는 속도는 그대로다. 에이전트를 더 많이 사용하면 오히려 확인해야 할 결과만 늘어날 수도 있다.
사람이 계속 붙어 있지 않아도 작업이 진행되려면 에이전트가 필요한 정보를 찾고, 자신의 작업 결과를 확인하고, 실패한 지점을 수정할 수 있어야 한다. 대담에서 강조하는 검증은 이 과정을 연결하는 역할을 한다.
검증은 테스트 통과보다 넓다
Lauren이 설명하는 검증에는 앱을 직접 실행하고, 일반 사용자처럼 상호작용하며, 디버깅 자료와 트레이스, 스냅샷을 수집하는 일까지 포함된다.
에이전트가 자기 작업의 결과를 실제로 관찰할 수 있어야 한다는 것이다.
생각해보니 나도 일부 작업에서는 이런 방식을 사용했다. 쿼리를 개선하거나 레거시 코드를 수정할 때, 에이전트에게 직접 DB에 연결하고 실행 계획을 살펴보도록 요청한 적이 있다. 더미 데이터를 넣어서 실제 응답과 성능이 개선되는지도 확인하게 했다. 결과는 Markdown이나 HTML로 정리해서 보고하도록 했다.
당시에는 필요한 내용을 프롬프트에 하나씩 적었다. 이번 대담을 보면서 그 작업을 반복 가능한 검증 과정으로 정리할 수 있겠다는 생각이 들었다.
기준을 주고, 구현 결과가 그 기준을 만족하는지 확인하고, 만족하지 못하면 수정한 뒤 다시 확인한다. 루프라는 표현을 쓰지만 흐름 자체는 낯설지 않다.
구현 결과를 실제로 관찰하고, 기준을 충족하는지 비교하는 과정이 필요하다.
다만 흐름이 단순하다고 준비도 간단한 것은 아닐 것이다. 무엇을 성공으로 볼지, 어떤 조건으로 실행할지, 어떤 결과를 비교할지가 명확해야 한다. 테스트가 통과했다는 사실과 요구사항이 충족됐다는 사실도 항상 같지는 않다.
예를 들어 쿼리가 실행된다고 성능 개선이 확인된 것은 아니다. 적은 데이터에서는 빨라도 데이터가 쌓이면 느려질 수 있고, 응답 시간은 줄었지만 결과가 달라졌을 수도 있다.
결국 에이전트에게 검증하라고 말하는 것만큼, 무엇을 근거로 검증할지 정하는 일이 중요하다고 느꼈다.
반복해서 시키는 일은 도구로 만들 수 있다
Lauren은 검증 과정에서도 반복 작업을 발견했다고 한다.
에이전트들이 필요한 스크립트와 도구를 매번 새로 만들었고, 만드는 방식도 달랐다. 이전 에이전트가 만든 도구가 잘 동작했더라도 다음 에이전트가 다시 만들고 테스트하는 일이 발생했다.
그래서 절차를 고정할 수 있는 부분을 CLI로 옮겼다고 설명한다. 반복적인 실행은 도구가 맡고, 상황을 이해하거나 대안을 선택하는 부분은 에이전트에게 남기는 방식이다.
이 내용을 읽으며 기존의 재사용성에 관한 이야기와 크게 다르지 않다고 생각했다. 같은 작업을 계속 새로 만들지 않고, 잘 동작하는 것을 공통으로 사용하는 것이다.
다만 에이전트와 작업하면서 재사용할 대상이 더 넓어진 것 같다. 코드뿐 아니라 내가 반복해서 설명하는 작업 순서, 검증 방법, 판단 기준도 정리할 수 있다. 그중 일부는 스킬이 되고, 일부는 스크립트나 CLI 같은 실행 도구가 될 수 있다.
앞으로는 CLI나 MCP 같은 인터페이스를 활용하는 것과 함께, 내가 계속 반복해서 시키는 일이 무엇인지 돌아보는 능력도 중요할 것 같다.
나도 쿼리 개선을 맡길 때 매번 비슷한 검증 요청을 작성했다. 이런 내용을 작업 흐름과 실행 도구로 정리한다면, 다음 작업에서는 필요한 맥락과 달라진 조건에 더 집중할 수 있을 것이다.
코드 구조는 에이전트에게도 중요하다
대담에서 특히 인상 깊었던 부분은 코드베이스의 구조에 관한 이야기였다.
Lauren은 초기 Grok Bot에 각각 1만 줄 이상인 거대한 파일이 여럿 있었다고 설명한다. 이후 기능별 디렉터리를 두고, 기능을 추가하는 관례와 엄격한 린트 규칙을 마련했다. 에이전트가 기능을 추가할 때 따라갈 경로를 명확하게 만든 것이다.
문서에 규칙을 많이 적는 것과, 환경이 잘못된 선택을 어렵게 만드는 것은 다르다. 코드 구조와 자동 검사가 규칙을 뒷받침하면 에이전트가 모든 지침을 기억하는 데만 의존하지 않아도 된다.
문서로 방향을 전달하고, 코드 구조와 자동 검사로 잘못된 선택을 줄일 수 있다.
사실 최근에는 AI가 코드를 쉽게 구현하는 모습을 보면서 SOLID나 재사용성 같은 개념을 얼마나 중요하게 봐야 할지 고민한 적이 있다. 사람이 코드를 이해하고 유지보수하기 위해 고민했던 것들인데, AI가 구현과 수정의 많은 부분을 대신한다면 중요성이 달라지는 것 아닐까?
이 대담에서는 오히려 그런 지식이 에이전트가 작업하는 환경을 만드는 데 활용되고 있었다.
그렇다고 모든 곳에 추상화를 추가하거나 특정 원칙을 기계적으로 적용해야 한다는 뜻은 아닐 것이다. 중요한 것은 기능을 넣을 위치, 허용된 방식, 확인해야 할 절차를 명확하게 만드는 일에 가까워 보였다.
이런 환경에서는 사람과 에이전트 모두 헤매는 일이 줄어든다. 결국 사람과 에이전트가 함께 일하는 코드베이스라면, 구조를 이해하기 쉽고 변경을 확인하기 쉬워야 한다는 요구도 여전히 남아 있는 것 같다.
많이 실행하기 전에 문제를 함께 바라보기
대담은 코드 밖의 맥락도 다룬다.
버그 제보나 요구사항은 Slack, 이슈 관리 도구, 여러 메시지에 흩어져 있다. 에이전트가 코드만 읽는다고 이런 정보를 모두 아는 것은 아니다. 사람이 계속 수집해서 전달해야 한다면 그 과정도 병목이 된다.
Lauren은 외부 정보를 가져오는 과정과 코드를 구현하고 검증하는 과정을 연결한다고 설명한다. 여기서도 제보를 받자마자 무조건 구현하는 방식으로 끝나지는 않는다. 실제 버그인지 재현하고, 관련된 문제들을 살펴보고, 작업을 나눈다.
특히 코드의 잘못된 패턴을 발견했을 때 즉시 수정하게 하지 않고, 먼저 문서에 기록하도록 한다는 점이 흥미로웠다.
여러 기록을 함께 보면 개별 문제라고 생각했던 것들이 같은 원인에서 나왔다는 것을 발견할 수 있다. 작은 수정 여러 개가 필요한지, 공통 추상화를 바꿔야 하는지, 규칙을 추가해야 하는지 판단하는 것이다.
이것 역시 기존 소프트웨어 엔지니어링과 연결된다고 느꼈다. 구현을 빠르게 할 수 있다고 해서 눈앞의 증상마다 바로 수정하는 것이 항상 좋은 해결은 아니다. 문제를 관찰하고, 공통 원인을 찾고, 적절한 단위로 해결하는 과정은 여전히 필요하다.
병합까지 맡긴다는 것은 어디까지 맡긴다는 뜻일까?
Lauren은 일부 작업에서 에이전트에게 병합까지 맡기고, 다음 날 커밋 이력을 살펴본다고 설명한다.
그 전에 검증 에이전트들이 앱을 실행하고 문제를 찾고, 수정하고, 다시 확인하는 과정이 있다. 준비된 환경과 검증 루프를 바탕으로 병합을 허용하는 것이다. 토큰을 많이 사용하고, 그 단계까지 도달하는 데 상당한 시간과 노력이 필요하다는 점도 함께 말한다.
그래서 이 이야기를 사람의 리뷰가 필요 없다는 의미로 받아들이기는 어렵다고 생각했다. 개별 변경을 모두 사전에 읽는 방식에서, 결과와 반복되는 패턴을 관찰하고 환경을 개선하는 방식으로 일부 이동한 것으로 보인다.
나는 특히 핵심 도메인 로직이나 되돌리기 어려운 변경에는 사람의 리뷰가 필요하다고 생각한다. 화면에서 관찰하기 쉬운 동작과 데이터 정합성처럼 겉으로 드러나기 어려운 문제는 검증 방법도 다를 것이다.
대담에서도 비슷한 질문이 나온다. 쉽게 되돌릴 수 있는 변경과 데이터 손실처럼 되돌리기 어려운 변경을 같은 방식으로 다뤄도 되는지, 의료나 금융 분야에서는 어떻게 해야 하는지 묻는다.
Lauren도 모든 경우에 대한 답을 갖고 있지는 않다고 말한다. 이 부분은 나 역시 더 고민해봐야 할 지점이다.
처음에 떠올렸던 PR 크기 문제도 이 대담만으로 답을 내릴 수는 없다. PR 2,500개라는 숫자에는 각 변경의 크기가 담겨 있지 않다. 큰 변경을 자동 병합할 수 있는 조건이 있었다고 해서, 내 작업에서도 PR을 크게 만들어도 된다는 결론이 나오지는 않는다.
지금은 사람이 이해하고 검토할 수 있도록 작업을 나누면서, 자동 검증으로 맡길 수 있는 범위를 조금씩 확인하는 방식이 나에게 맞을 것 같다.
내 도구는 내 경험에서 만들어야 한다
Lauren은 셰프가 직장을 옮겨도 자기 칼을 가지고 가는 것처럼, 누구나 자신의 도구와 스킬을 가져야 한다고 이야기한다.
공개된 스킬을 가져다 쓸 수는 있지만, 자신의 업무에서 반복되는 문제와 개입 지점을 살펴보고 조정해야 한다는 것이다. 그 재료로 이전 대화 기록을 추천한다. 무엇을 반복해서 설명했고, 어디에서 에이전트를 수정했으며, 어떤 맥락이 계속 필요했는지를 살펴보는 방식이다.
내가 반복해서 개입한 지점이 다음 작업에서 사용할 도구의 재료가 된다.
앞서 반복해서 시키는 일을 도구로 만들면 좋겠다고 생각했는데, 대담 후반에서도 같은 방향의 이야기가 나와 반가웠다.
공통 스킬만으로 모든 업무가 해결되는 것은 아닐 것이다. 내 업무에서 무엇이 중요한지, 어떤 결과를 확인해야 하는지 판단하는 데에는 결국 내가 가진 도메인 지식과 경험이 필요하다.
이번 대담을 보며, AI가 구현을 많이 맡는 시대에도 기존 소프트웨어 엔지니어링의 고민이 계속 중요하겠다는 생각이 들었다. 재사용성, 코드 구조, 문제 관찰, 검증, 맥락 공유는 에이전트와 작업할 때도 필요한 것들이었다.
앞으로는 에이전트가 코드를 얼마나 빨리 작성하는지만 볼 것이 아니라, 내가 어떤 근거로 결과를 신뢰하는지도 함께 살펴보려 한다. 우선 내가 반복해서 작성했던 검증 요청부터 돌아보고, 다시 사용할 수 있는 작업 흐름으로 정리해보고 싶다.
참고 자료
이 글은 대담에서 소개된 작업 방식과 개인적인 경험을 연결해 정리했다. 대담의 성과 수치는 발언자의 설명을 기준으로 하며, 그 방식이 모든 개발 환경에 동일하게 적용된다는 의미는 아니다.