AI는 내가 책임감 있게 검토할 수 있는 속도보다 더 빠르게 코드를 작성할 수 있다
요약
Claude Code와 같은 AI 코딩 에이전트의 빠른 코드 생성 속도가 인간의 검토 역량을 초과하며 발생하는 '검토 부채' 문제를 다룹니다. AI가 생성한 코드를 완전히 이해하지 못한 채 승인할 경우, 미래에 유지보수가 불가능한 기술적 부채로 남을 수 있음을 경고합니다.
핵심 포인트
- AI의 코드 생성 속도가 인간의 멘탈 모델 구축 속도보다 빠름
- 생성 비용은 낮아졌으나 코드 검토 및 이해를 위한 비용은 증가함
- 이해 없이 승인된 코드는 미래의 '검토 부채'가 됨
- 결제, 권한 등 중요한 결정은 AI의 속도에 의존하지 말고 신중해야 함
나는 Zenovay를 구축하는 동안 거의 매일 Claude Code를 사용합니다.
Claude Code는 내가 커피를 다 마시기도 전에 기능을 스캐폴딩(scaffold)하고, 여러 파일에 걸쳐 버그를 추적하며, 테스트를 작성하고, 오래된 모듈을 리팩터링(refactor)하며, 익숙하지 않은 코드베이스의 부분을 설명해 줄 수 있습니다.
이것은 순수한 레버리지(leverage)처럼 들립니다.
하지만 이것은 내가 예상하지 못한 문제를 만들어냈습니다:
AI는 내가 그것에 대한 신뢰할 수 있는 멘탈 모델(mental model)을 구축할 수 있는 속도보다 훨씬 더 빠르게 코드를 생성할 수 있습니다.
병목 현상은 더 이상 코드를 작성하는 것이 아닙니다.
그것은 인간의 주의력(attention)입니다.
거대한 diff는 여전히 진전처럼 느껴진다
에이전트(agent)가 작업을 수행하는 것을 지켜보는 것에는 어떤 만족감이 있습니다.
파일이 변경됩니다. 테스트가 나타납니다. 타입 에러(Type error)가 사라집니다. 터미널이 계속 움직입니다.
20분 후, 700줄의 diff가 생기고 모든 것이 초록색(pass)으로 변합니다.
생산적인 세션처럼 느껴집니다.
그러다 diff를 열어보면, AI가 내린 모든 결정을 확신을 가지고 설명할 수 없다는 사실을 깨닫게 됩니다.
왜 이 추상화(abstraction)가 추가되었는가?
이 재시도(retry) 로직이 중복 이벤트를 생성하는가?
권한 확인(permission check)이 API 경계에서 일어나는가, 아니면 인터페이스(interface)에서만 일어나는가?
웹훅(webhook)이 두 번 도착하면 어떻게 되는가?
코드가 세 프롬프트(prompt) 전에 내가 설명했던 개인정보 보호 규칙을 유지했는가?
위험한 출력물은 명백하게 실패하는 코드인 경우가 드뭅니다.
그것은 컴파일(compile)되고, 해피 패스(happy-path) 테스트를 통과하며, 조용히 잘못된 가정을 구현하는 코드입니다.
생성 비용은 저렴해졌지만, 검토 비용은 그렇지 않다.
코딩 에이전트가 등장하기 전에는, 기능을 작성하는 데 필요한 노력이 자연스럽게 그 규모를 제한했습니다.
타이핑을 하는 동안 생각할 시간이 있었습니다. 인터페이스를 반복해서 사용해야 했기 때문에 어색한 인터페이스를 알아차릴 수 있었습니다. 10분 전에 직접 작성했기 때문에 해당 브랜치(branch)가 왜 존재하는지 기억할 수 있었습니다.
AI는 그러한 마찰(friction)의 상당 부분을 제거합니다.
그것은 유용하지만, 그 마찰은 또한 숨겨진 작업(hidden work)을 수행하고 있었습니다.
그 마찰은 시스템에 들어오는 새로운 코드의 양을 늦추었습니다.
이제 1인 개발자도 팀 단위의 속도(velocity)에 근접하게 변경 사항을 생성할 수 있습니다. 하지만 검토 역량(review capacity)은 여전히 한 사람입니다.
이것은 일종의 검토 부채(review debt)를 만들어냅니다.
내가 완전히 이해하지 못한 채 승인된 모든 코드 라인은 미래의 작은 의무가 됩니다. 어쩌면 해롭지 않을 수도 있습니다. 하지만 6개월 뒤에는 왜 그렇게 작동하는지 아무도 기억하지 못해서, 아무도 건드리고 싶어 하지 않는 함수가 될 수도 있습니다.
코드는 빠르게 생성되었습니다.
이해는 미뤄졌습니다.
어떤 결정들은 느리게 유지되어야 합니다
분석(analytics) 제품을 구축할 때, 작은 기술적 결정들은 실제적인 결과를 초래할 수 있습니다.
기여도(attribution) 측정의 실수는 고객에게 잘못된 획득 채널(acquisition channel)을 보여줄 수 있습니다.
세션 리플레이(session replay)의 실수는 마스킹(masking) 처리되었어야 할 무언가를 캡처할 수 있습니다.
결제 로직(billing logic)의 실수는 실제 돈에 영향을 줄 수 있습니다.
권한 부여(authorization)의 실수는 한 고객의 데이터를 다른 고객에게 노출할 수 있습니다.
저는 여전히 이 모든 영역 주변에서 AI를 사용하지만, AI가 중요한 경계(boundaries)를 조용히 결정하도록 내버려 두지는 않습니다.
이제 저는 몇 가지 사항을 다르게 취급합니다:
데이터 및 개인정보 보호 경계
에이전트(agent)는 규칙을 구현하는 데 도움을 줄 수 있습니다.
하지만 규칙 그 자체는 저로부터 나와야 합니다.
저는 무엇이 시스템에 들어오는지, 어디에서 변환되는지, 얼마나 오래 머무는지, 그리고 무엇을 절대 저장해서는 안 되는지를 정확히 알고 싶습니다.
권한 부여 및 결제
그럴싸해 보이는 권한 확인(permission check)만으로는 충분하지 않습니다.
인증(auth), 구독(subscriptions), 송장(invoices), 환불(refunds), 그리고 웹훅(webhooks)의 경우, 저는 변경된 함수만 보는 대신 전체 경로(full path)를 검토합니다.
데이터베이스 마이그레이션 (Database migrations)
AI는 올바르게 보이는 마이그레이션(migration)을 생성하는 데 매우 능숙합니다.
하지만 이미 운영 환경(production)에 존재하는 기이한 데이터, 여전히 지원 중단된 필드(deprecated field)를 보내고 있는 오래된 클라이언트, 또는 새벽 2시에 당신이 수행해야 할 롤백(rollback)에 대해서는 인지도가 낮습니다.
제품 가설 (Product assumptions)
에이전트는 불분명한 요구사항을 작동하는 코드로 기꺼이 바꿔 놓을 것입니다.
그렇다고 해서 그 요구사항이 올바른 것은 아닙니다.
모델이 누락된 제품 결정을 채워 넣을 때, 종종 가장 관습적인(conventional) 답을 선택합니다. 관습적인 것이 항상 당신의 제품에 필요한 것은 아닙니다.
나의 워크플로우가 바뀌었습니다
예전에는 구현을 위해 프롬프트(prompt)를 입력하고 그 결과를 검토했습니다.
이제 저는 사고(thinking)와 작성(writing)을 분리합니다.
먼저, 제안된 접근 방식(approach), 영향을 받는 파일들, 가정(assumptions), 실패 사례(failure cases), 그리고 여전히 모호한 작업 부분들을 요청합니다.
그다음에야 비로소 모델이 코드를 수정하도록 허용합니다.
또한, 생성된 코드 전체를 오후 내내 스크롤하며 검토하지 않아도 될 만큼 각 변경 사항을 충분히 작게 유지하려고 노력합니다.
중요한 경로(critical paths)에 대해서는, 에이전트에게 자신의 솔루션을 스스로 공격하도록 요청합니다:
- 이 부분이 조용히 실패(fail silently)할 수 있는 지점은 어디인가?
- 어떤 입력값이 현재의 가정을 깨뜨리는가?
- 재시도(retries) 중에 어떤 일이 발생하는가?
- 두 개의 요청이 동시에 도착하면 어떻게 되는가?
- 누락된 권한 확인(authorization check)은 무엇인가?
- 어떤 데이터가 실수로 저장될 수 있는가?
이 방식은 유용한 문제들을 잡아내지만, 책임이 모델로 전가되는 것은 아닙니다.
테스트도 마찬가지입니다.
테스트 스위트(test suite)는 우리가 생각했던 케이스들이 예상대로 작동한다는 것을 증명할 뿐입니다. 아무도 고려하지 않은 케이스에 대해서는 아무것도 말해주지 않습니다.
마지막에 저는 스스로에게 한 가지 간단한 질문을 던집니다:
AI를 언급하지 않고도 이 변경 사항을 다른 개발자에게 설명할 수 있는가?
만약 대답이 '아니오'라면, 저는 그것을 머지(merge)할 준비가 되지 않은 것입니다.
AI는 엔지니어링적 판단(engineering judgment)의 필요성을 제거하지 못했다
코딩 에이전트(coding agents)는 아마도 제 워크플로에서 생산성을 가장 크게 향상시킨 요소일 것입니다.
저는 이전으로 돌아가지 않을 것입니다.
하지만 저는 더 이상 변경된 파일의 수나 작업이 얼마나 빨리 초록색 체크 표시(green checkmark)에 도달했는가로 좋은 AI 세션을 측정하지 않습니다.
유용한 지표는 검증된 진전(verified progress)이 코드베이스에 얼마나 들어왔는가입니다.
그것은 대개 생성된 디프(diff)보다 덜 인상적입니다.
하지만 훨씬 더 가치 있습니다.
AI는 코드를 작성하는 데 도움을 줄 수 있습니다.
테스트를 제안하고, 리스크를 지적하며, 구현 방식에 이의를 제기할 수도 있습니다.
하지만 그 코드가 프로덕션(production)에 도달하는 순간, 그 이면에 담긴 약속을 유지하는 것은 모델이 아닙니다.
바로 저입니다.
여러분은 자신의 워크플로에서 이를 어떻게 다루고 계신가요?
AI가 생성한 코드의 모든 줄을 검토하시나요, 아니면 의도적으로 더 신뢰하는 영역이 있나요?
공개 사항: 저는 Zenovay를 구축하는 동안 AI를 집중적으로 사용했으며, 이 포스트의 구조를 잡고 편집하는 데 AI를 활용했습니다. 의견, 예시 및 최종 결정은 저의 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기