나의 코딩 에이전트가 건드리지도 않은 세 개의 페이지에 버그를 배포했다
요약
AI 코딩 에이전트를 활용해 개발할 때 발생할 수 있는 사이드 이펙트와 그 위험성을 경고합니다. 공유 컴포넌트 수정 시 영향 범위를 명확히 정의하고 검증하는 프로세스의 중요성을 강조합니다.
핵심 포인트
- 에이전트의 변경 사항이 의도치 않은 공유 컴포넌트에 영향을 줄 수 있음
- 변경 전 '유지되어야 할 사항'을 명시적으로 지시하여 영향 범위 제한
- 공유 요소 수정 전 코드베이스 전체를 검색(Grep)하여 사용 사례 확인 필수
- 작은 변경이라도 프로덕션 배포 전에는 엄격한 리뷰 프로세스 적용
요구사항은 간단했습니다. 제품 상세 페이지의 구매 버튼 스타일을 변경하는 것이었습니다. 그 외에는 아무것도 없었죠. 에이전트(Agent)가 이를 구현했고, 저는 diff(변경 사항)를 대충 훑어보았습니다. 버튼 변경처럼 보였기에 그대로 배포(ship)했습니다. 하루도 채 지나지 않아 결제(checkout), 장바구니(cart), 그리고 구독 페이지 하나가 모두 조용히 형태가 망가졌다는 보고를 받았습니다. 버튼은 공유 컴포넌트(shared component)에 포함되어 있었고, 한 페이지를 위해 스타일을 변경한 것이 해당 컴포넌트가 사용된 모든 곳의 스타일을 변경해 버린 것이었습니다. 저는 이와 정확히 똑같은 실수를 몇 달 간격으로 두 번의 서로 다른 리디자인(redesign) 과정에서 저질렀습니다. 첫 번째 실수 때 프로세스(process) 대신 증상(symptom)만을 수정했기 때문입니다.
저는 다른 엔지니어 없이 혼자 스토어를 운영합니다. 프로덕션(production)에 배포되는 모든 것은 커밋(commit) 권한을 가진 계약직이자 끝이 없는 수습 기간을 거치는 에이전트(agent)를 통해 진행됩니다. 제 업무는 기능을 직접 작성하는 것이 아니었습니다. 제 업무는 "이 변경 사항은 주장하는 범위 내로 국한되어 있다"라고 자신 있게 말할 수 있는 능력을 갖추는 것입니다. 하지만 오랫동안 저는 실제로 그렇게 하지 못했습니다. 그저 diff(변경 사항)를 대충 훑어보며 파일 목록이 합리적으로 보이는지만 바랐을 뿐입니다.
순진한 실수, 그리고 왜 스토어 운영자에게 특히 비용이 많이 드는가
혼자서 배포할 때 유혹적인 지름길은 작아 보이는 모든 것에 대해 에이전트(agent)가 프로덕션(production)에 바로 푸시(push)하도록 허용하는 것입니다. "그냥 문구 변경이야", "그냥 버튼 하나야"라고 생각하면서 말이죠. 프로덕션 환경의 이커머스(e-commerce) 사이트는 내부 도구(internal tool)와 달리 그런 지름길을 용납하지 않습니다. 결제(checkout) 버그는 누군가 이를 발견할 때까지의 시간이 아니라, 버그가 라이브(live) 상태로 유지되는 매 분마다 비용을 발생시킵니다. 따라서 "리뷰를 건너뛸 만큼 충분히 작은 것"에 대한 기준은 "diff(변경 사항) 요약에서 작아 보이는 것"이 아니라 거의 제로(zero)에 가까워야 합니다.
실제로 유효한 프로세스(process)는 5단계로 구성되며, 저는 단순한 오타 수정(typo fix)을 제외하고는 어떤 경우에도 이 단계들을 건너뛰지 않습니다.
1. 변경되어서는 안 되는 사항을 명시하기
에이전트가 무엇인가를 건드리기 전에, 저는 변경 사항을 평이한 언어로 작성하며 — 이 부분은 제가 예전에 건너뛰곤 했던 부분입니다 — 무엇이 동일하게 유지되어야 하는지를 명시적으로 적습니다. "PDP(상품 상세 페이지)의 구매 버튼 스타일을 재조정하세요. 결제(checkout), 장바구니(cart), 구독(subscription) 페이지는 픽셀 단위로 동일하게 유지되어야 합니다." 이 두 번째 문장이 제가 겪었던 원래의 사고를 발생하기 전에 잡아냈을 것입니다. 왜냐하면 이 문장은 에이전트(그리고 저)가 버그 리포트가 올라온 후가 아니라, 코드 한 줄을 쓰기 전에 영향 범위(blast radius)에 대해 생각하도록 강제하기 때문입니다.
2. 공유 요소를 재조정하기 전에 Grep 하세요
이것은 두 번의 사고로부터 직접 도출된 단 하나의 규칙이며, 이제는 타협할 수 없는 원칙입니다. 어떤 공유 컴포넌트(shared component)를 수정하기 전에, 에이전트는 코드베이스 전체에서 해당 컴포넌트의 모든 사용 사례를 Grep(검색)하고, 각 사용 사례에 대해 한 줄의 영향 노트를 포함하여 변경 요약(change summary)에 목록을 작성합니다. 제 운영 환경(production) 사고의 대부분은 정확히 이 패턴으로 거슬러 올라갑니다. 즉, 누군가가 염두에 둔 특정 페이지를 위해 컴포넌트 스타일을 재조정했는데, 그것을 재사용하는 다른 모든 페이지가 조용히 변형되어 버리는 것입니다. 이 일로 두 번 데이고 나면, "작은 변경 사항이다"라는 범주를 더 이상 신뢰하지 않게 되며, 매번 "이 파일을 사용하는 다른 것이 무엇인가"를 반사적으로 묻기 시작합니다.
내가 빠졌던 함정: 공유 컴포넌트 유출(shared-component leak)은 완전히 다른 두 번의 리디자인 과정에서 저에게 발생했습니다. 하나는 결제 테마 변경이었고, 몇 달 후에는 상품 페이지 리디자인이었습니다. 두 번째 일이 발생했을 때 저는 이것이 운이 나빴던 것이 아니라, 제 체크리스트에 한 줄이 빠져 있었다는 것을 깨달았습니다. 관련 없는 프로젝트에서 동일한 유형의 버그가 반복된다면, 그것은 운이 나쁜 한 주가 아니라 프로세스의 공백입니다.
3. 구축한 세션이 아닌, 새로운 에이전트 세션으로 리뷰하세요
3. 구축한 세션이 아닌, 새로운 에이전트 세션으로 리뷰하세요
제 초기 검토 프로세스를 한동안 무력화했던 실수는 공유 컴포넌트 문제보다 더 미묘했습니다. 바로 변경 사항을 구현하는 데 사용했던 것과 동일한 에이전트 세션에게 그 내용을 다시 검토하게 했다는 점입니다. 매번의 검토는 형식적인 절차에 불과했습니다. 왜냐하면 에이전트는 자신이 '무엇을 의미했는지' 알고 있었기 때문입니다. 즉, 실제 diff가 아니라 자신의 의도를 검토했을 뿐입니다. 5분 전 선의로 내린 결정에 대해 회의적일 수 없었던 것입니다.
해결책은 구현 과정의 추론(reasoning)에 대한 기억이 전혀 없는 완전히 새로운 세션을 가동하고, 오직 명세서(spec)와 diff만 전달하며, 이를 의심하는 검토자(skeptical reviewer)로 명시적으로 설정하는 것입니다. 이 프레이밍(framing)은 들리는 것보다 더 중요합니다. '문제점을 찾는 시니어 엔지니어로 이것을 검토해 주세요'라는 지시는 '이 diff가 명세서와 일치하는지 확인하세요'라는 지시와는 완전히 다른 품질의 결과물을 만들어냅니다. 실제로 자신이 작성하지 않은 diff를 검토하는 것이 애초에 작성하는 것과 어떻게 다른지 여기에서 살펴보겠습니다:
| 구현자(Implementer)의 관점 | 신규 검토자(Fresh reviewer)의 관점 | |
|---|---|---|
| 컨텍스트 | 변경이 무엇을 의미했는지 알고 있음 | 명시된 명세서만 알고 있음 |
| ... | ||
| 검토자의 역할은 일반적인 것이 아니라 구체적입니다. 의도치 않은 파일 변경, 공유 컴포넌트의 영향 범위(blast radius), 설정값이어야 할 하드코딩 값, 그리고 비즈니스 불변성(business invariants) 위반—할인 스케줄, 가격 책정 로직 등 선호 사항이 아닌 규칙에 해당하는 모든 것—을 찾아내는 것입니다. '저에게는 괜찮아 보여요'라는 말은 판결이 아닙니다. '승인' 또는 '이유와 함께 변경 요청'만이 판결입니다. |
4. 미리보기(Preview) → 스모크 테스트(Smoke test) → 프로덕션(Production)
어떤 것도 검토를 거쳤다고 해서 바로 라이브가 되지는 않습니다. 먼저 미리보기 배포(preview deployment)로 이동하며, 돈과 관련된 모든 것—결제(checkout), 장바구니(cart), 구독 흐름(subscription flows)—에 대해서는 프로덕션 환경 근처에 가기 전에 실제 구매 과정 전체를 그 미리보기 URL에서 전 과정을 거쳐 테스트합니다. 이 단계는 코드 리뷰가 진정으로 놓칠 수밖에 없는 종류의 버그, 즉 구문적으로는 완벽하지만 논리적으로는 틀린 것들(예: 네 가지 구독 주기에는 올바르게 계산되지만 다섯 번째 주기에 대해서는 조용히 잘못되는 할인 등급)을 잡아냅니다.
그 과정이 끝난 후에야 비로소 프로덕션 (production) 환경으로 배포됩니다. 그리고 배포가 끝났다고 해서 작업이 완료된 것은 아닙니다. 에이전트는 배포 직후 실제 고객이 경험하는 방식 그대로 라이브 사이트를 다시 검증하며, 전후 스크린샷을 찍습니다. "성공적으로 배포됨 (Deployed successfully)"과 "올바르게 배포됨 (deployed correctly)"은 서로 다른 주장이며, 직접 확인하지 않고 믿을 가치가 있는 것은 오직 후자뿐입니다.
5. 모든 사고는 영구적인 체크리스트 항목이 된다
저의 배포 체크리스트는 9개의 항목으로 구성되어 있습니다. 체크리스트의 모든 항목은 하나의 흉터입니다. 이는 수사적인 표현이 아닙니다. 문자 그대로 저에게 무언가 손실을 입혔던 특정 사고에서 비롯된 것이며, 이 체크리스트가 있기에 저는 그 사고들을 세 번째로 반복하지 않을 수 있었습니다. 프로세스에도 불구하고 무언가 잘못되었을 때는, 몇 주 뒤 기억에 의존해 요약하는 것이 아니라 세부 사항이 생생할 때 즉시 짧은 사후 분석 (postmortem)을 작성하여 체크리스트에 반영합니다.
영향 (Impact): 저와 같은 상점 규모에서 에이전시 수준의 개발을 진행한다면 한 달에 수천 달러의 비용이 들 것입니다. 하지만 제가 사용하는 도구는 그 비용의 아주 일부분만을 차지하며, 리뷰 프로세스 자체는 최소 분기에 한 번은 매출에 영향을 미치는 버그를 프로덕션에 도달하기 전에 잡아냈습니다. 각각의 버그는 그 자체로 한 달 치 도구 비용보다 더 큰 가치가 있으며, 이것이 바로 20분을 아끼기 위해 리뷰 단계를 건너뛰는 대신 리뷰 통과 단계를 유지해야 하는 실제적인 이유입니다.
코드를 직접 작성할 수 없을 때 실제 리뷰는 어떻게 이루어지는가
"내가 작성하지도 않았고, 작성할 수도 없었던 diff(차이점)를 어떻게 리뷰하는가"라는 질문에 대한 솔직한 답변은, 코드의 품질을 리뷰하는 것이 아니라는 점입니다. 당신은 격리 (containment)와 불변량 (invariants)을 리뷰하는 것입니다. 파일 목록이 명시된 범위 (scope)와 일치하는가? 그 범위를 벗어난 무언가가 변경되었는가? 변경 사항이 변경 전에도 유효했고 변경 후에도 유효해야 하는 비즈니스 규칙(pricing, 할인 계산, 고객에게 노출되는 숫자에 영향을 주는 모든 것 등)을 준수하는가? 이것은 어떤 운영자라도 해당 기능을 직접 작성할 수 없더라도 능숙하게 수행할 수 있도록 배울 수 있는 리뷰 방식이며, 1인 창업자(solo-founder)가 제품 출시 (shipping)를 느린 속도의 부채가 아닌 생존 가능한 수준으로 만드는 실제적인 기술입니다.
제가 실제로 실행하는 프롬프트 쌍은 다음과 같습니다. 구현자 (implementer)를 위한 것 하나와 리뷰어 (reviewer)를 위한 것 하나로, 항상 두 개의 별도 세션으로 운영합니다:
변경 사양 (Change spec): [일상 언어로 된 설명]. 변경 금지 사항 (Must-not-change): [목록].
[이름] 브랜치에 구현할 것. 요구 사항:
- 공유 컴포넌트를 건드리기 전에, 모든 사용처를 grep으로 검색하고 목록을 작성할 것
...
정말로 어처구니없는 실수로 인해 겪었던 또 다른 습관이 있습니다. 한때 작업 디렉토리가 세션의 활성 워크스페이스로 사용 중인 상태에서 삭제되는 바람에 진행 중이던 재설계 (redesign) 작업이 통째로 날아간 적이 있습니다. 커밋 (commit)은 일찍 하고, 푸시 (push)는 자주 하십시오. 그리고 "이 디렉토리를 삭제하라"는 명령을 프로덕션 배포 (production deploy)만큼이나 의심스러운 작업으로 취급하십시오. 데이터 손실 관점에서 보면 그것은 기본적으로 배포와 다를 바 없기 때문입니다.
이 모든 것이 혼자서 제품을 출시하는 것을 팀과 함께하는 것만큼 안전하게 만들어 주지는 않습니다. 다만 실패 모드 (failure modes)를 비싸고 모호한 것이 아니라, 저렴하고 구체적인 것으로 만들어 줄 뿐입니다. 그리고 1인 운영자에게는 바로 이것이 넘어야 할 실제 기준입니다.
원문 게시 위치: https://methezone.github.io/solo-operator-playbook/agent-deploys-review-pass.html
30개의 모든 워크플로우는 프롬프트 및 실패 사례와 함께 작성되어 있습니다. 그중 5개는 전체 내용을 무료로 제공합니다: the sampler.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기